forked from MystenLabs/sui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[JSON-RPC] Generate openrpc.json spec and rpc.discover endpoint (Myst…
…enLabs#1588) * add open rpc rpc.discover support * * generated open rpc spec in sui/open_rpc/spec * more refactoring * updated doc * update doc * update rpc spec * rename package * remove unused deps * more docs added JsonSchema for MoveStructLayout * Update json-rpc.md Start edits and add TODOs to RPC server doc * address comments in doc Co-authored-by: Clay-Mysten <[email protected]>
- Loading branch information
1 parent
3b6cd6b
commit a626f6e
Showing
27 changed files
with
3,426 additions
and
112 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,302 @@ | ||
--- | ||
title: Local RPC Server & JSON-RPC API Quick Start | ||
--- | ||
|
||
Welcome to the Sui RPC server quick start. | ||
|
||
This document walks you through setting up your own local Sui RPC Server and using the Sui JSON-RPC API to interact with a local Sui network. This guide is useful for developers interested in Sui network interactions via API. For a similar guide on Sui network interactions via CLI, refer to the [wallet](wallet.md) documentation. | ||
|
||
|
||
## Local RPC server setup | ||
Follow the instructions to [install Sui binaries](install.md). | ||
|
||
### Start local Sui network | ||
Follow the instructions to [create](wallet.md#genesis) and [start](wallet.md#starting-the-network) the Sui network. | ||
The genesis process will create a `gateway.conf` configuration file that will be used by the RPC server. | ||
|
||
### Start local RPC server | ||
|
||
Use the following command to start a local server: | ||
```shell | ||
$ rpc-server | ||
``` | ||
You will see output resembling: | ||
``` | ||
2022-04-25T11:06:40.147259Z INFO rpc_server: Gateway config file path: ".sui/sui_config/gateway.conf" | ||
2022-04-25T11:06:40.147277Z INFO rpc_server: AccessControl { allowed_hosts: Any, allowed_origins: None, allowed_headers: Any, continue_on_invalid_cors: false } | ||
2022-04-25T11:06:40.163568Z INFO rpc_server: Available JSON-RPC methods : ["sui_moveCall", "sui_getTransaction", "sui_getObjectTypedInfo", "sui_getTotalTransactionNumber", "sui_getOwnedObjects", "sui_getObjectInfoRaw", "sui_transferCoin", "sui_executeTransaction", "sui_mergeCoins", "sui_getRecentTransactions", "sui_getTransactionsInRange", "rpc.discover", "sui_splitCoin", "sui_publish", "sui_syncAccountState"] | ||
2022-04-25T11:06:40.163590Z INFO rpc_server: Sui RPC Gateway listening on local_addr:127.0.0.1:5001 | ||
``` | ||
|
||
> **Note:** For additional logs, set `RUST_LOG=debug` before invoking `rpc-server`. | ||
Export a local user variable to store the hardcoded hostname + port that the local RPC server starts with to be used when issuing the `curl` commands that follow. | ||
```shell | ||
export SUI_RPC_HOST=http://127.0.0.1:5001 | ||
``` | ||
|
||
## Sui JSON-RPC API | ||
|
||
In the following sections we will show how to use Sui's JSON-RPC API with | ||
the `curl` command. | ||
|
||
## Sui JSON-RPC methods | ||
|
||
### rpc.discover | ||
|
||
Sui RPC server supports OpenRPC’s [service discovery method](https://spec.open-rpc.org/#service-discovery-method). | ||
A `rpc.discover` method is added to provide documentation describing our JSON-RPC APIs service. | ||
|
||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", "method":"rpc.discover","id":1}' | ||
``` | ||
|
||
You can see an example of the discovery service in the [OpenRPC Playground](https://playground.open-rpc.org/?schemaUrl=https://raw.githubusercontent.com/MystenLabs/sui/189d61df846f7c3676c1215cc41fb970ee9e22b5/sui/open_rpc/spec/openrpc.json). | ||
|
||
### sui_syncAccountState | ||
|
||
Synchronize client state with validators with the following command, | ||
replacing `{{address}}` with an actual address value, for example one obtained from `wallet.conf`: | ||
|
||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", "method":"sui_syncAccountState", "params":["{{address}}"], "id":1}' | ||
``` | ||
|
||
This will fetch the latest information on all objects owned by each | ||
address that is managed by this server. This command has no output. | ||
|
||
### sui_getOwnedObjects | ||
|
||
Return the list of objects owned by an address: | ||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", "method":"sui_getOwnedObjects", "params":["{{address}}"], "id":1}' | json_pp | ||
``` | ||
|
||
You should replace `{{address}}` in the command above with an actual | ||
address value, you can retrieve the list of the addresses created during | ||
genesis from `wallet.conf`. Ensure you have run [`sui_syncAccountState`](#sui_syncaccountstate) | ||
|
||
The output you see should resemble the following (abbreviated to show only two objects): | ||
|
||
```shell | ||
{ | ||
"id" : 1, | ||
"jsonrpc" : "2.0", | ||
"result" : { | ||
"objects" : [ | ||
{ | ||
"digest" : "zpa45U9ANfA9A6iS01NvAoVH0RbYB6a5rjhgh2Hb/GE=", | ||
"objectId" : "17b348903b0cfb75fc9ab5426bb69d83d1e756a5", | ||
"version" : 1 | ||
}, | ||
{ | ||
"digest" : "8SPi0h6xVMVNBvGzzF4RfuOoaXISdtiB5aT7+BYDbxg=", | ||
"objectId" : "7599d8ea1de4c9616d077f16ca0eb38cdecacc07", | ||
"version" : 1 | ||
}, | ||
... | ||
] | ||
} | ||
} | ||
|
||
``` | ||
|
||
### GET sui_getObjectInfoRaw | ||
|
||
Return the object information for a specified object, for example: | ||
|
||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", "method":"sui_getObjectInfoRaw", "params":["{{object_id}}"], "id":1}' | json_pp | ||
``` | ||
|
||
Replace `{{object_id}}` in the command above with an | ||
actual object ID, for example one obtained from [`sui_getOwnedObjects`](#sui_getownedobjects) (without quotes). | ||
|
||
### sui_transferCoin | ||
#### 1, Create a transaction to transfer a Sui coin from one address to another: | ||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", | ||
"method":"sui_transferCoin", | ||
"params":["{{owner_address}}", | ||
"{{coin_object_id}}", | ||
"{{gas_object_id}}", | ||
{{gas_budget}}, | ||
"{{to_address}}"], | ||
"id":1}' | json_pp | ||
``` | ||
A transaction data response will be returned from the gateway server. | ||
```json | ||
{ | ||
"id" : 1, | ||
"jsonrpc" : "2.0", | ||
"result" : { | ||
"tx_bytes" : "VHJhbnNhY3Rpb25EYXRhOjoAAFHe8jecgzoGWyGlZ1sJ2KBFN8aZF7NIkDsM+3X8mrVCa7adg9HnVqUBAAAAAAAAACDOlrjlT0A18D0DqJLTU28ChUfRFtgHprmuOGCHYdv8YVHe8jecgzoGWyGlZ1sJ2KBFN8aZdZnY6h3kyWFtB38Wyg6zjN7KzAcBAAAAAAAAACDxI+LSHrFUxU0G8bPMXhF+46hpchJ22IHlpPv4FgNvGOgDAAAAAAAA" | ||
} | ||
} | ||
|
||
``` | ||
#### 2, Sign the transaction using the Sui signtool | ||
```shell | ||
sui signtool --address <owner_address> --data <tx_bytes> | ||
``` | ||
The signing tool will create and print out the signature and public key information. | ||
You will see output resembling: | ||
```shell | ||
2022-04-25T18:50:06.031722Z INFO sui::sui_commands: Data to sign : VHJhbnNhY3Rpb25EYXRhOjoAAFHe8jecgzoGWyGlZ1sJ2KBFN8aZF7NIkDsM+3X8mrVCa7adg9HnVqUBAAAAAAAAACDOlrjlT0A18D0DqJLTU28ChUfRFtgHprmuOGCHYdv8YVHe8jecgzoGWyGlZ1sJ2KBFN8aZdZnY6h3kyWFtB38Wyg6zjN7KzAcBAAAAAAAAACDxI+LSHrFUxU0G8bPMXhF+46hpchJ22IHlpPv4FgNvGOgDAAAAAAAA | ||
2022-04-25T18:50:06.031765Z INFO sui::sui_commands: Address : 51DEF2379C833A065B21A5675B09D8A04537C699 | ||
2022-04-25T18:50:06.031911Z INFO sui::sui_commands: Public Key Base64: H82FDLUZN1u0+6UdZilxu9HDT5rPd3khKo2UJoCPJFo= | ||
2022-04-25T18:50:06.031925Z INFO sui::sui_commands: Signature : 6vc+ku0RsMKdky8DRfoy/hw6eCQ3YsadH6rZ9WUCwGTAumuWER3TOJRw7u7F4QaHkqUsIPfJN9GRraSX+N8ADQ== | ||
``` | ||
|
||
#### 3, Execute the transaction using the transaction data, signature and public key. | ||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", | ||
"method":"sui_executeTransaction", | ||
"params":[{ | ||
"tx_bytes" : "{{tx_bytes}}", | ||
"signature" : "{{signature}}", | ||
"pub_key" : "{{pub_key}}"}], | ||
"id":1}' | json_pp | ||
``` | ||
|
||
Native transfer by `sui_transferCoin` is supported for coin | ||
objects only (including gas objects). Refer to | ||
[transactions](transactions.md#native-transaction) documentation for | ||
more information about a native transfer. Non-coin objects cannot be | ||
transferred natively and require a [Move call](#sui_movecall). | ||
|
||
You should replace `{{owner_address}}` and `{{to_address}}` in the | ||
command above with an actual address values, for example one obtained | ||
from `wallet.conf`. You should also replace | ||
`{{coin_object_id}}` and `{{gas_object_id}}` in the command above with | ||
an actual object ID, for example one obtained from `objectId` in the output | ||
of [`sui_getOwnedObjects`](#sui_getownedobjects). You can see that all gas objects generated | ||
during genesis are of `Coin/SUI` type). For this call to work, objects | ||
represented by both `{{coin_object_id}}` and `{{gas_object_id}}` must | ||
be owned by the address represented by `{{owner_address}}`. | ||
|
||
|
||
### sui_moveCall | ||
|
||
#### 1, Execute a Move call transaction by calling the specified function in | ||
the module of a given package (smart contracts in Sui are written in | ||
the [Move](move.md#move) language): | ||
|
||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", | ||
"method":"sui_moveCall", | ||
"params":["{{owner_address}}", | ||
"0x2", | ||
"GAS", | ||
"transfer", | ||
[], | ||
["Pure": "{{coin_object_id_base64}}", "Pure": "{{to_address_base64}}"}], | ||
"{{gas_object_id}}", | ||
2000], | ||
"id":1}' | json_pp | ||
``` | ||
|
||
#### 2, Sign the transaction | ||
Follow the instructions to [sign the transaction](rest-api.md#2-sign-the-transaction-using-the-sui-signtool). | ||
|
||
#### 3, Execute the transaction | ||
Follow the instructions to [execute the transaction](rest-api.md#3-execute-the-transaction-using-the-transaction-data-signature-and-public-key). | ||
|
||
Arguments are passed in, and type will be inferred from function | ||
signature. Gas usage is capped by the gas_budget. The `transfer` | ||
function is described in more detail in | ||
the [Sui Wallet](wallet.md#calling-move-code) documentation. | ||
|
||
Calling the `transfer` function in the `GAS` module serves the same | ||
purpose as the native coin transfer ([`sui_transferCoin`](#sui_transfercoin)), and is mostly used for illustration | ||
purposes as native transfer is more efficient when it's applicable | ||
(i.e., we are transferring coins rather than non-coin | ||
objects). Consequently, you should fill out argument placeholders | ||
(`{{owner_address}}`, `{{coin_object_id}`, etc.) the same way you | ||
would for [`sui_transferCoin`](#sui_transfercoin) - please not additional | ||
`0x` prepended to function arguments. | ||
|
||
To learn more about what `args` are accepted in a Move call, refer to the [SuiJSON](sui-json.md) documentation. | ||
|
||
### sui_publish | ||
|
||
Publish Move module. | ||
|
||
```shell | ||
curl --location --request POST $SUI_RPC_HOST \ | ||
--header 'Content-Type: application/json' \ | ||
--data-raw '{ "jsonrpc":"2.0", | ||
"method":"sui_publish", | ||
"params":[ "{{owner_address}}", | ||
{{vector_of_compiled_modules}}, | ||
"{{gas_object_id}}", | ||
10000], | ||
"id":1}' | json_pp | ||
``` | ||
|
||
This endpoint will perform proper verification and linking to make | ||
sure the package is valid. If some modules have [initializers](move.md#module-initializers), these initializers | ||
will also be executed in Move (which means new Move objects can be created in | ||
the process of publishing a Move package). Gas budget is required because of the | ||
need to execute module initializers. | ||
|
||
You should replace `{{owner_address}}` in the | ||
command above with an actual address values, for example one obtained | ||
from `wallet.conf`. You should also replace `{{gas_object_id}}` in the command above with | ||
an actual object ID, for example one obtained from `objectId` in the output | ||
of [`sui_getownedobjects`](#sui_getownedobjects). You can see that all gas objects generated | ||
during genesis are of `Coin/SUI` type). For this call to work, the object | ||
represented by `{{gas_object_id}}` must be owned by the address represented by | ||
`{{owner_address}}`. | ||
|
||
To publish a Move module, you also need `{{vector_of_compiled_modules}}`. To generate the value of this field, use the `sui-move` command. The `sui-move` command supports printing the bytecodes as base64 with the following option | ||
|
||
``` | ||
sui-move --path <move-module-path> build --dump-bytecode-as-base64 | ||
``` | ||
|
||
Assuming that the location of the package's sources is in the `PATH_TO_PACKAGE` environment variable an example command would resemble the following | ||
|
||
``` | ||
sui-move --path $PATH_TO_PACKAGE/my_move_package build --dump-bytecode-as-base64 | ||
["oRzrCwUAAAAJAQAIAggUAxw3BFMKBV1yB88BdAjDAigK6wIFDPACQgAAAQEBAgEDAAACAAEEDAEAAQEBDAEAAQMDAgAABQABAAAGAgEAAAcDBAAACAUBAAEFBwEBAAEKCQoBAgMLCwwAAgwNAQEIAQcODwEAAQgQAQEABAYFBgcICAYJBgMHCwEBCAALAgEIAAcIAwABBwgDAwcLAQEIAAMHCAMBCwIBCAADCwEBCAAFBwgDAQgAAgsCAQkABwsBAQkAAQsBAQgAAgkABwgDAQsBAQkAAQYIAwEFAgkABQMDBwsBAQkABwgDAQsCAQkAAgsBAQkABQdNQU5BR0VEBENvaW4IVHJhbnNmZXIJVHhDb250ZXh0C1RyZWFzdXJ5Q2FwBGJ1cm4EaW5pdARtaW50DHRyYW5zZmVyX2NhcAtkdW1teV9maWVsZA9jcmVhdGVfY3VycmVuY3kGc2VuZGVyCHRyYW5zZmVyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgACAQkBAAEAAAEECwELADgAAgEAAAAICwkSAAoAOAEMAQsBCwAuEQY4AgICAQAAAQULAQsACwI4AwIDAQAAAQQLAAsBOAQCAA==", "oRzrCwUAAAALAQAOAg4kAzJZBIsBHAWnAasBB9IC6QEIuwQoBuMECgrtBB0MigWzAQ29BgYAAAABAQIBAwEEAQUBBgAAAgAABwgAAgIMAQABBAQCAAEBAgAGBgIAAxAEAAISDAEAAQAIAAEAAAkCAwAACgQFAAALBgcAAAwEBQAADQQFAAIVCgUBAAIICwMBAAIWDQ4BAAIXERIBAgYYAhMAAhkCDgEABRoVAwEIAhsWAwEAAgsXDgEAAg0YBQEABgkHCQgMCA8JCQsMCw8MFAYPBgwNDA0PDgkPCQMHCAELAgEIAAcIBQILAgEIAwsCAQgEAQcIBQABBggBAQMEBwgBCwIBCAMLAgEIBAcIBQELAgEIAAMLAgEIBAMLAgEIAwEIAAEGCwIBCQACCwIBCQAHCwcBCQABCAMDBwsCAQkAAwcIBQELAgEJAAEIBAELBwEIAAIJAAcIBQELBwEJAAEIBgEIAQEJAAIHCwIBCQALAgEJAAMDBwsHAQkABwgFAQYLBwEJAAZCQVNLRVQHTUFOQUdFRARDb2luAklEA1NVSQhUcmFuc2ZlcglUeENvbnRleHQHUmVzZXJ2ZQRidXJuBGluaXQObWFuYWdlZF9zdXBwbHkEbWludApzdWlfc3VwcGx5DHRvdGFsX3N1cHBseQtkdW1teV9maWVsZAJpZAtWZXJzaW9uZWRJRAx0cmVhc3VyeV9jYXALVHJlYXN1cnlDYXADc3VpB21hbmFnZWQFdmFsdWUId2l0aGRyYXcPY3JlYXRlX2N1cnJlbmN5Bm5ld19pZAR6ZXJvDHNoYXJlX29iamVjdARqb2luAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgMIAAAAAAAAAAAAAgEOAQECBA8IBhELBwEIABMLAgEIAxQLAgEIBAABAAAIFg4BOAAMBAsBCgAPADgBCgAPAQoECgI4AgwFCwAPAgsECwI4AwwDCwULAwIBAAAAEA8JEgAKADgEDAEKABEKCwEKADgFCwA4BhIBOAcCAgEAAAMECwAQAjgIAgMBAAAFHA4BOAkMBAoEDgI4CCEDDgsAAQsDAQcAJwoADwELATgKCgAPAgsCOAsLBAsADwALAzgMAgQBAAADBAsAEAE4CQIFAQAAAwQLABAAOA0CAQEBAgEDAA=="] | ||
Build Successful | ||
``` | ||
|
||
Copy the outputting base64 representation of the compiled Move module into the | ||
REST publish endpoint. | ||
|
||
#### 2, Sign the transaction | ||
Follow the instructions to [sign the transaction](json-rpc.md#2-sign-the-transaction-using-the-sui-signtool). | ||
|
||
#### 3, Execute the transaction | ||
Follow the instructions to [execute the transaction](rest-api.md#3-execute-the-transaction-using-the-transaction-data-signature-and-public-key). | ||
|
||
Below you can see a truncated sample output of [sui_publish](#sui_publish). One of the results of executing this command is generation of a package object representing the published Move code. An ID of the package object can be used as an argument for subsequent Move calls to functions defined in this package. | ||
|
||
``` | ||
{ | ||
"package": [ | ||
"13e3ec7279060663e1bbc45aaf5859113fc164d2", | ||
... | ||
} | ||
``` | ||
|
||
## Connect to remote JSON-RPC server | ||
|
||
Coming soon - alternative ways of working with Sui's JSON-RPC API. Connect to Sui devnet, testnet, or mainnet! |
Oops, something went wrong.