Skip to content

Commit

Permalink
feat: add support for Soroban PRC's getTransactions and `getFeeStat…
Browse files Browse the repository at this point in the history
…s` API interfaces.
  • Loading branch information
overcat committed Jul 24, 2024
1 parent 54340e4 commit fed5eca
Show file tree
Hide file tree
Showing 6 changed files with 522 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Release History
==============

### Pending
#### Update
- feat: add support for Soroban PRC's `getTransactions` and `getFeeStats` API interfaces.

### Version 11.0.0

Expand Down
86 changes: 86 additions & 0 deletions stellar_sdk/soroban_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,89 @@ class GetLatestLedgerResponse(BaseModel):
id: str
protocol_version: int = Field(alias="protocolVersion")
sequence: int


# get_fee_stats
class FeeDistribution(BaseModel):
max: int
min: int
mode: int
p10: int
p20: int
p30: int
p40: int
p50: int
p60: int
p70: int
p80: int
p90: int
p95: int
p99: int
transaction_count: int = Field(alias="transactionCount")
ledger_count: int = Field(alias="ledgerCount")


class GetFeeStatsResponse(BaseModel):
"""Response for JSON-RPC method getFeeStats.
See `getFeeStats documentation <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getFeeStats>`__ for
more information."""

soroban_inclusion_fee: FeeDistribution = Field(alias="sorobanInclusionFee")
inclusion_fee: FeeDistribution = Field(alias="inclusionFee")
latest_ledger: int = Field(alias="latestLedger")


# get_transactions
class GetTransactionsRequest(BaseModel):
"""Request for JSON-RPC method getTransactions.
See `getTransactions documentation <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getTransactions>`__ for
more information."""

start_ledger: int = Field(alias="startLedger")
pagination: Optional[PaginationOptions] = None


class Transaction(BaseModel):
status: str
application_order: int = Field(alias="applicationOrder")
fee_bump: bool = Field(alias="feeBump")
envelope_xdr: str = Field(alias="envelopeXdr")
result_xdr: str = Field(alias="resultXdr")
result_meta_xdr: str = Field(alias="resultMetaXdr")
ledger: int
created_at: int = Field(alias="createdAt")
diagnostic_events_xdr: Optional[List[str]] = Field(
alias="diagnosticEventsXdr", default=None
)


class GetTransactionsResponse(BaseModel):
"""Response for JSON-RPC method getTransactions.
See `getTransactions documentation <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getTransactions>`__ for
more information."""

transactions: List[Transaction]
latest_ledger: int = Field(alias="latestLedger")
latest_ledger_close_timestamp: int = Field(alias="latestLedgerCloseTimestamp")
oldest_ledger: int = Field(alias="oldestLedger")
oldest_ledger_close_timestamp: int = Field(alias="oldestLedgerCloseTimestamp")
cursor: str


# get_version_info
# TODO: To avoid breaking change, let's add it later.
# See: https://github.com/stellar/soroban-rpc/pull/164
# class GetVersionInfoResponse(BaseModel):
# """Response for JSON-RPC method getVersionInfo.
#
# See `getVersionInfo documentation <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getVersionInfo>`__ for
# more information."""
#
# version: str
# commit_hash: str = Field(alias="commitHash")
# build_time_stamp: str = Field(alias="buildTimeStamp")
# captive_core_version: str = Field(alias="captiveCoreVersion")
# protocol_version: int = Field(alias="protocolVersion")
58 changes: 52 additions & 6 deletions stellar_sdk/soroban_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(
def get_health(self) -> GetHealthResponse:
"""General node health check.
See `Soroban Documentation - getHealth <https://soroban.stellar.org/api/methods/getHealth>`_
See `Soroban RPC Documentation - getHealth <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getHealth>`_
:return: A :class:`GetHealthResponse <stellar_sdk.soroban_rpc.GetHealthResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
Expand All @@ -74,7 +74,7 @@ def get_events(
) -> GetEventsResponse:
"""Fetch a list of events that occurred in the ledger range.
See `Soroban Documentation - getEvents <https://soroban.stellar.org/api/methods/getEvents>`_
See `Soroban RPC Documentation - getEvents <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getEvents>`_
:param start_ledger: The first ledger to include in the results.
:param filters: A list of filters to apply to the results.
Expand All @@ -97,6 +97,8 @@ def get_events(
def get_network(self) -> GetNetworkResponse:
"""General info about the currently configured network.
See `Soroban RPC Documentation - getNetwork <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getNetwork>`_
:return: A :class:`GetNetworkResponse <stellar_sdk.soroban_rpc.GetNetworkResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
Expand All @@ -110,6 +112,8 @@ def get_network(self) -> GetNetworkResponse:
def get_latest_ledger(self) -> GetLatestLedgerResponse:
"""Fetches the latest ledger meta info from network which Soroban-RPC is connected to.
See `Soroban RPC Documentation - getLatestLedger <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getLatestLedger>`_
:return: A :class:`GetLatestLedgerResponse <stellar_sdk.soroban_rpc.GetLatestLedgerResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
Expand All @@ -129,7 +133,7 @@ def get_ledger_entries(
or any other ledger entry. This is a backup way to access your contract data
which may not be available via events or simulateTransaction.
See `Soroban Documentation - getLedgerEntries <https://soroban.stellar.org/api/methods/getLedgerEntries>`_
See `Soroban RPC Documentation - getLedgerEntries <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getLedgerEntries>`_
:param keys: The ledger keys to fetch.
:return: A :class:`GetLedgerEntriesResponse <stellar_sdk.soroban_rpc.GetLedgerEntryResponse>` object.
Expand All @@ -145,7 +149,7 @@ def get_ledger_entries(
def get_transaction(self, transaction_hash: str) -> GetTransactionResponse:
"""Fetch the specified transaction.
See `Soroban Documentation - getTransaction <https://soroban.stellar.org/api/methods/getTransaction>`_
See `Soroban RPC Documentation - getTransaction <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getTransaction>`_
:param transaction_hash: The hash of the transaction to fetch.
:return: A :class:`GetTransactionResponse <stellar_sdk.soroban_rpc.GetTransactionResponse>` object.
Expand All @@ -165,7 +169,7 @@ def simulate_transaction(
) -> SimulateTransactionResponse:
"""Submit a trial contract invocation to get back return values, expected ledger footprint, and expected costs.
See `Soroban Documentation - simulateTransaction <https://soroban.stellar.org/api/methods/simulateTransaction>`_
See `Soroban RPC Documentation - simulateTransaction <https://developers.stellar.org/docs/data/rpc/api-reference/methods/simulateTransaction>`_
:param transaction_envelope: The transaction to simulate. It should include exactly one operation,
which must be one of :class:`RestoreFootprint <stellar_sdk.operation.RestoreFootprintOperation>`,
Expand Down Expand Up @@ -204,7 +208,7 @@ def send_transaction(
) -> SendTransactionResponse:
"""Submit a real transaction to the Stellar network. This is the only way to make changes "on-chain".
See `Soroban Documentation - sendTransaction <https://soroban.stellar.org/api/methods/sendTransaction>`_
See `Soroban RPC Documentation - sendTransaction <https://developers.stellar.org/docs/data/rpc/api-reference/methods/sendTransaction>`_
:param transaction_envelope: The transaction to send.
:return: A :class:`SendTransactionResponse <stellar_sdk.soroban_rpc.SendTransactionResponse>` object.
Expand All @@ -222,6 +226,48 @@ def send_transaction(
)
return self._post(request, SendTransactionResponse)

def get_fee_stats(self) -> GetFeeStatsResponse:
"""General info about the fee stats.
See `Soroban RPC Documentation - getFeeStats <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getFeeStats>`_
:return: A :class:`GetFeeStatsResponse <stellar_sdk.soroban_rpc.GetFeeStatsResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
request: Request = Request(
id=_generate_unique_request_id(),
method="getFeeStats",
params=None,
)
return self._post(request, GetFeeStatsResponse)

def get_transactions(
self,
start_ledger: int,
cursor: str = None,
limit: int = None,
) -> GetTransactionsResponse:
"""Fetch a detailed list of transactions starting from the user specified starting point that you can paginate
as long as the pages fall within the history retention of their corresponding RPC provider.
See `Soroban RPC Documentation - getTransactions <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getTransactions>`_
:param start_ledger: The first ledger to include in the results.
:param cursor: A cursor value for use in pagination.
:param limit: The maximum number of records to return.
:return: A :class:`GetTransactionsResponse <stellar_sdk.soroban_rpc.GetTransactionsResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
pagination = PaginationOptions(cursor=cursor, limit=limit)
data = GetTransactionsRequest(
startLedger=str(start_ledger),
pagination=pagination,
)
request: Request = Request[GetTransactionsRequest](
id=_generate_unique_request_id(), method="getTransactions", params=data
)
return self._post(request, GetTransactionsResponse)

def load_account(self, account_id: str) -> Account:
"""Load an account from the server, you can use the returned account
object as source account for transactions.
Expand Down
58 changes: 52 additions & 6 deletions stellar_sdk/soroban_server_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(
async def get_health(self) -> GetHealthResponse:
"""General node health check.
See `Soroban Documentation - getHealth <https://soroban.stellar.org/api/methods/getHealth>`_
See `Soroban RPC Documentation - getHealth <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getHealth>`_
:return: A :class:`GetHealthResponse <stellar_sdk.soroban_rpc.GetHealthResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
Expand All @@ -74,7 +74,7 @@ async def get_events(
) -> GetEventsResponse:
"""Fetch a list of events that occurred in the ledger range.
See `Soroban Documentation - getEvents <https://soroban.stellar.org/api/methods/getEvents>`_
See `Soroban RPC Documentation - getEvents <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getEvents>`_
:param start_ledger: The first ledger to include in the results.
:param filters: A list of filters to apply to the results.
Expand All @@ -97,6 +97,8 @@ async def get_events(
async def get_network(self) -> GetNetworkResponse:
"""General info about the currently configured network.
See `Soroban RPC Documentation - getNetwork <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getNetwork>`_
:return: A :class:`GetNetworkResponse <stellar_sdk.soroban_rpc.GetNetworkResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
Expand All @@ -110,6 +112,8 @@ async def get_network(self) -> GetNetworkResponse:
async def get_latest_ledger(self) -> GetLatestLedgerResponse:
"""Fetches the latest ledger meta info from network which Soroban-RPC is connected to.
See `Soroban RPC Documentation - getLatestLedger <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getLatestLedger>`_
:return: A :class:`GetLatestLedgerResponse <stellar_sdk.soroban_rpc.GetLatestLedgerResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
Expand All @@ -129,7 +133,7 @@ async def get_ledger_entries(
or any other ledger entry. This is a backup way to access your contract data
which may not be available via events or simulateTransaction.
See `Soroban Documentation - getLedgerEntries <https://soroban.stellar.org/api/methods/getLedgerEntries>`_
See `Soroban RPC Documentation - getLedgerEntries <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getLedgerEntries>`_
:param keys: The ledger keys to fetch.
:return: A :class:`GetLedgerEntriesResponse <stellar_sdk.soroban_rpc.GetLedgerEntryResponse>` object.
Expand All @@ -145,7 +149,7 @@ async def get_ledger_entries(
async def get_transaction(self, transaction_hash: str) -> GetTransactionResponse:
"""Fetch the specified transaction.
See `Soroban Documentation - getTransaction <https://soroban.stellar.org/api/methods/getTransaction>`_
See `Soroban RPC Documentation - getTransaction <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getTransaction>`_
:param transaction_hash: The hash of the transaction to fetch.
:return: A :class:`GetTransactionResponse <stellar_sdk.soroban_rpc.GetTransactionResponse>` object.
Expand All @@ -165,7 +169,7 @@ async def simulate_transaction(
) -> SimulateTransactionResponse:
"""Submit a trial contract invocation to get back return values, expected ledger footprint, and expected costs.
See `Soroban Documentation - simulateTransaction <https://soroban.stellar.org/api/methods/simulateTransaction>`_
See `Soroban RPC Documentation - simulateTransaction <https://developers.stellar.org/docs/data/rpc/api-reference/methods/simulateTransaction>`_
:param transaction_envelope: The transaction to simulate. It should include exactly one operation,
which must be one of :class:`RestoreFootprint <stellar_sdk.operation.RestoreFootprintOperation>`,
Expand Down Expand Up @@ -203,7 +207,7 @@ async def send_transaction(
) -> SendTransactionResponse:
"""Submit a real transaction to the Stellar network. This is the only way to make changes "on-chain".
See `Soroban Documentation - sendTransaction <https://soroban.stellar.org/api/methods/sendTransaction>`_
See `Soroban RPC Documentation - sendTransaction <https://developers.stellar.org/docs/data/rpc/api-reference/methods/sendTransaction>`_
:param transaction_envelope: The transaction to send.
:return: A :class:`SendTransactionResponse <stellar_sdk.soroban_rpc.SendTransactionResponse>` object.
Expand All @@ -221,6 +225,48 @@ async def send_transaction(
)
return await self._post(request, SendTransactionResponse)

async def get_fee_stats(self) -> GetFeeStatsResponse:
"""General info about the fee stats.
See `Soroban RPC Documentation - getFeeStats <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getFeeStats>`_
:return: A :class:`GetFeeStatsResponse <stellar_sdk.soroban_rpc.GetFeeStatsResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
request: Request = Request(
id=_generate_unique_request_id(),
method="getFeeStats",
params=None,
)
return await self._post(request, GetFeeStatsResponse)

async def get_transactions(
self,
start_ledger: int,
cursor: str = None,
limit: int = None,
) -> GetTransactionsResponse:
"""Fetch a detailed list of transactions starting from the user specified starting point that you can paginate
as long as the pages fall within the history retention of their corresponding RPC provider.
See `Soroban RPC Documentation - getTransactions <https://developers.stellar.org/docs/data/rpc/api-reference/methods/getTransactions>`_
:param start_ledger: The first ledger to include in the results.
:param cursor: A cursor value for use in pagination.
:param limit: The maximum number of records to return.
:return: A :class:`GetTransactionsResponse <stellar_sdk.soroban_rpc.GetTransactionsResponse>` object.
:raises: :exc:`SorobanRpcErrorResponse <stellar_sdk.exceptions.SorobanRpcErrorResponse>` - If the Soroban-RPC instance returns an error response.
"""
pagination = PaginationOptions(cursor=cursor, limit=limit)
data = GetTransactionsRequest(
startLedger=str(start_ledger),
pagination=pagination,
)
request: Request = Request[GetTransactionsRequest](
id=_generate_unique_request_id(), method="getTransactions", params=data
)
return await self._post(request, GetTransactionsResponse)

async def load_account(self, account_id: str) -> Account:
"""Load an account from the server, you can use the returned account
object as source account for transactions.
Expand Down
Loading

0 comments on commit fed5eca

Please sign in to comment.