Here lies RPC requests made from postman to a Soroban-RPC endpoint
Note: Items listed as a work-in-progress (WIP) reflects, as far as my understanding goes, the current state of the Soroban-RPC methods that are available and working.
Here's what you'll find in this repository:
- A collection of the (current) JSON RPC requests that can be made against a Soroban-RPC endpoint
- Information on how to format the requests to a Soroban-RPC endpoint
- A collection of Postman requests that will get you going toward making those RPC requests
- A place to get started writing scripts and apps in Python and JavaScript (because those are the main languages I know.)
Here is some of the resources I've used in creating this collection.
- Soroban RPC Design Document
- This is the best source I've found so far. It's not intended as a finalized document, but more as a communal brainstorm/roadmap.
- Paul's OpenRPC Spec (out-of-date I believe)
- Smephite's amazing guide to all things types
- JSON-RPC 2.0 Specification
- The jsonrpcclient Python library makes it quite easy to generate and parse requests like these.
- There is also a json-rpc-2.0 npm package, although I'm no good with JavaScript.
You can get to a running (I think) version of the collection right in your browser by clicking the button below.
Alternatively, the Soroban-RPC Requests.postman-collection.json
file has the
same requests in a format you could import directly into your own instance of
Postman.
The basic structure of a JSON-RPC request looks something like this:
{
"jsonrpc": "2.0", // Specifies the JSON-RPC protocol version to use. Must be exactly "2.0"
"id": 8675309, // An identifier for the client. I'm not entirely sure if this is required by Soroban-RPC
"method": "<method-name>", // The name of the method to be invoked
"params": {
// A structured value that holds the parameter(s) being used during the invocation
"<key>": "<value>"
}
}
With that out of the way, here's how we use the (currently) existing methods for Soroban-RPC endpoints.
With the first method, getAccount
request, I will also provide a python and
javascript snippet for making the request to the endpoint. I trust you'll be
able to extrapolate how to request different methods when necessary. (I will
attempt to keep a working, more-complete, and up-to-date rpc_calls.py
file in
this repository, as well.)
When invoking getAccount
, you must supply the account's public key as the
address
parameter.
The response is intended to be a minimal set of account information, and will include the account ID, sequence number, and balances (not yet?).
Request body:
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getAccount",
"params": {
"address": "GBTXODHDMG3CHYLLTNXMUSSI7WXIAHBQTLKNCSGWGCWO3XV3MTJ7PNZA"
}
}
Response body:
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"id": "GBTXODHDMG3CHYLLTNXMUSSI7WXIAHBQTLKNCSGWGCWO3XV3MTJ7PNZA",
"sequence": "3435501390397448"
}
}
When invoking getHealth
, you are checking on the general well-being of the
node. No parameters are required, nor are they accepted.
Based on my (admittedly limited) understanding of the Soroban-RPC codebase, it
appears (at the moment) any getHealth
request will simply return "healthy."
It's unclear what ultimately will be the measure of health, or when it will be
implemented.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getHealth"
}
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"status": "healthy"
}
}
When invoking getLatestLedger
, you will find out the current latest known
ledger of this node. This is a subset of ledger info available through Horizon.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLatestLedger"
}
"work-in-progress"
According to the design-doc, it should return something like this (someday?):
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"id": "<hash>", // hash of the latest ledger
"protocolVersion": "<number>",
"sequence": "<number>"
}
}
Invoking getLedgerEntry
is useful for reading the current value of
CONTRACT_DATA
ledger entries directly through RPC. This allows you to directly
inspect the current state of a contract.
The tricky part for this method is getting a useable value for the
xdr.LedgerKey
parameter. The contract below is a deployed copy of the
increment
example from the Soroban documentation
examples. As such, the LedgerKey
we need to provide is an xdr-encoded
LedgerKeyContractData
object made with the contractId
and the ScVal
representing the key.
This can be achieved using the soroban
branch of the python stellar_sdk
. A
starter script is supplied in sc_val.py
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntry",
"params": {
"key": "pimawTd4so6Re0r2HRYHQJK1oU6Sx+k1HYJRAOQYd+cAAAAFAAAAB0NPVU5URVIA"
}
}
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"xdr": "<xdr-encoded-string>",
"lastModifiedLedger": "1166180",
"latestLedger": "1166323"
}
}
WARNING:
getContractData
WILL SOON BE DEPRECATED IN FAVOR ORgetLedgerEntry
Invoking getContractData
is useful for reading the current value of
CONTRACT_DATA
ledger entries directly through RPC. This allows you to directly
inspect the current state of a contract.
The tricky part for this method is getting a useable value for the key
parameter. The contract below is a deployed copy of the increment
example from the Soroban documentation examples. As such,
the key
we need to provide is an xdr-encoded ScVal
of the symbol COUNTER
.
This can be achieved using the soroban
branch of the python stellar_sdk
. A
starter script is supplied in sc_val.py
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getContractData",
"params": {
"contractId": "a6299ac13778b28e917b4af61d16074092b5a14e92c7e9351d825100e41877e7",
"key": "AAAABQAAAAdDT1VOVEVSAA=="
}
}
This method can also be used to retrieve WASM byte-code that is stored on the
ledger. This requires us to supply a key
of the ContractCode
SCVal ledger
entry. Here's what the request would look like:
"something"
For the first request above (the "COUNTER" data entry). The returned xdr
can
be decoded as in sc_val.py
:
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"xdr": "AAAAAQAAAAQ=",
"lastModifiedLedgerSeq": "1166180",
"latestLedger": "1166323"
}
}
The response with the WASM byte-code looks like this:
"something
The getEvents
method can be used for a client to retrieve a filtered list of
events that are emitted by a specified ledger range.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getEvents",
"params": {
"startLedger": "100",
"endLedger": "1000",
"filters": {
"type": "contract",
"contractIds": [
"a6299ac13778b28e917b4af61d16074092b5a14e92c7e9351d825100e41877e7",
"4018b6f8f2d50449d001920362be249d2bdf768d5a6da6ce73146a994d8747c7"
],
"topics": [
// "AAAABQAAAAh0cmFuc2Zlcg==" === ScSymbol("transfer").toXdr().toString('base64')
// Matches any token transfer events
["AAAABQAAAAh0cmFuc2Zlcg==", "*", "*"],
// Matches any token transfer events to recipient: `GABC...123`
["AAAABQAAAAh0cmFuc2Zlcg==", "*", "GABC...123"],
// Matches only token transfers from `GDEF...456` to `GABC...123`
["AAAABQAAAAh0cmFuc2Zlcg==", "GDEF...456", "GABC...123"],
]
},
"pagination": {
"cursor": "1234-1",
"limit": 100
}
}
}
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"events": {
"ledger": "<string>", // string-ified sequence number of the ledger
"ledgerClosedAt": "<string>", // ISO8601 timestamp of the ledger closing time
"contractId": "<string>", // id of the emitting contract
"id": "<string>", // event's unique id
"pagingToken": "<string>", // same as `id` field, but expected here for paging
"topic": "<xdr.ScVal[]>", // list of topics this event was emitted with
"value": {
"xdr": "<xdr.ScVal>" // the body of the event (base64-encoded string)
}
}
}
}
The getNetwork
method returns general information about the currently
configured network.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getNetwork"
}
"work-in-progress"
You can use getTransactionStatus
to find out if a sent transaction has been
successful, failed, etc. You will also get a results
response with anything
that was returned by the transaction. In the example below, the transaction was
deploying the increment
contract, and the results
contains the bytes of the
contract ID.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getTransactionStatus",
"params": {
"hash": "9975a8f097fe3e6a3c6048a5c91631202b8f4f2b5f6edb2f81655631aeb3ef51"
}
}
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"id": "9975a8f097fe3e6a3c6048a5c91631202b8f4f2b5f6edb2f81655631aeb3ef51",
"status": "success",
"results": [
{
"xdr": "AAAABAAAAAEAAAAEAAAAIKYpmsE3eLKOkXtK9h0WB0CStaFOksfpNR2CUQDkGHfn"
}
]
}
}
The requestAirdrop
is a friendbot interface. A request can be made (outside of
the public network) to give lumens to a particular account.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "requestAirdrop",
"params": {
"account": "GD3LWOYS4I6P2VF43MH2E627O5LMIJWCSGNIP3Y7SNWU52FGJT4ZI7VP"
}
}
"work-in-progress"
The sendTransaction
allows you to submit a real stellar transaction. You don't
get a status in return, you are expected to use getTransactionStatus
to find
out if it was successful or not, and to get any return from the invocation.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "sendTransaction",
"params": {
"transaction": "AAAAAgAAAABndwzjYbYj4WubbspKSP2ugBwwmtTRSNYwrO3eu2TT9wAAAGQAEcpoAAAABgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAACgAAAAVoZWxsbwAAAAAAAAEAAAAHc29yb2JhbgAAAAAAAAAAAbtk0/cAAABA7S8ZDIj5I/NrZKIEtU9DDF/XNiUlKslxuCkQxUnpz++9+yZ2DdbrCI8yO+CP/BP+hKr5gxfBxJQMdDuAW5LHBw=="
}
}
"something"
The simulateTransaction
method is intended to submit a trial invocation of a
smart contract to get back return values, ledger footprint, expected costs, etc.
I don't seem to be able to make this work. That might be because I'm trying to
use a "classic" stellar transaction?
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "simulateTransaction",
"params": {
"transaction": "AAAAAgAAAABndwzjYbYj4WubbspKSP2ugBwwmtTRSNYwrO3eu2TT9wAAAGQAEcpoAAAABgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAACgAAAAVoZWxsbwAAAAAAAAEAAAAHc29yb2JhbgAAAAAAAAAAAbtk0/cAAABA7S8ZDIj5I/NrZKIEtU9DDF/XNiUlKslxuCkQxUnpz++9+yZ2DdbrCI8yO+CP/BP+hKr5gxfBxJQMdDuAW5LHBw=="
}
}
"work-in-progress"