From 3122ab3ceddb567b269b82f5eb41b2f94a848039 Mon Sep 17 00:00:00 2001 From: George Kudrayvtsev Date: Fri, 22 Dec 2023 12:26:40 -0800 Subject: [PATCH 1/3] Update tutorial to (a) actually work and (b) use the latest SDK --- api/methods/getLedgerEntries.mdx | 16 ++++----- .../state-archival.mdx | 35 +++++++++++++------ 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/api/methods/getLedgerEntries.mdx b/api/methods/getLedgerEntries.mdx index f64df4de..4e9f9446 100644 --- a/api/methods/getLedgerEntries.mdx +++ b/api/methods/getLedgerEntries.mdx @@ -15,10 +15,10 @@ The example above is querying a deployment of the [`increment` example contract] :::note -If you are using the [Python](https://stellar-sdk.readthedocs.io/en/9.0.0-beta0/) `stellar_sdk` to generate these keys, you will need to install the latest pre-release version of the SDK. This can be done like so: +If you are using the [Python](https://stellar-sdk.readthedocs.io/en/latest/) `stellar_sdk` to generate these keys, you will need to install the latest version of the SDK. This can be done like so: ```bash -pip install --upgrade --pre stellar-sdk +pip install --upgrade stellar-sdk ``` ::: @@ -51,11 +51,11 @@ print( If you are using the [JavaScript](https://stellar.github.io/js-stellar-sdk/) `stellar-sdk` to generate these keys, you will need to install the latest pre-release version of the SDK. This can be done like so: ```bash -yarn add stellar-sdk@beta +yarn add @stellar/stellar-sdk ``` ```js -import { xdr, StrKey } from 'stellar-sdk'; +import { xdr, StrKey } from '@stellar/stellar-sdk'; const getLedgerKeySymbol = (contractId, symbolText) => { const ledgerKey = xdr.LedgerKey.contractData( @@ -79,14 +79,14 @@ console.log( :::note -This functionality is included in the JavaScript [stellar-sdk](https://www.npmjs.com/package/stellar-sdk) package as `SorobanRpc.Server.getAccount(address)`. +This functionality is included in the JavaScript [`stellar-sdk`](https://www.npmjs.com/package/stellar-sdk) package as `SorobanRpc.Server.getAccount(address)`. ::: Accounts are stored as ledger entries, so we can use this method to look up an account along with it's current sequence number. ```js -import { xdr, Keypair, StrKey } from 'stellar-sdk' +import { xdr, Keypair, StrKey } from '@stellar/stellar-sdk' const getLedgerKeyAccount = (address) => { const publicKey = StrKey.decodeEd25519PublicKey(address) @@ -192,10 +192,10 @@ print( ##### JavaScript ```javascript -import { Address, xdr } from 'stellar-sdk'; +import { Address, xdr } from '@stellar/stellar-sdk'; function getLedgerKeyContractCode(contractId) { - const [ _, instance ] = new ContractId(contractId).getFootprint(); + const instance = new ContractId(contractId).getFootprint(); return instance.toXDR('base64'); } diff --git a/docs/fundamentals-and-concepts/state-archival.mdx b/docs/fundamentals-and-concepts/state-archival.mdx index 29692a02..5d7bf9cb 100644 --- a/docs/fundamentals-and-concepts/state-archival.mdx +++ b/docs/fundamentals-and-concepts/state-archival.mdx @@ -225,14 +225,13 @@ In order to help the scaffolding of the code, we'll introduce some reusable comp ```typescript import { - Server, Transaction, FeeBumpTransaction, SorobanRpc, } from "@stellar/stellar-sdk"; const RPC_SERVER = "https://soroban-testnet.stellar.org/"; -const server = new Server(RPC_SERVER); +const server = new SorobanRpc.Server(RPC_SERVER); // Submits a tx and then polls for its status until a timeout is reached. async function yeetTx( @@ -289,7 +288,7 @@ We'll start with the likeliest occurrence: my piece of persistent data is archiv In this example, we will assume two things: the contract itself is still live (i.e. others have been extending its TTL while you've been away) and you don't know how your archived data is represented on the ledger. If you did, you could skip the steps below where we figure that out and just set up the restoration footprint directly. The process involves three discrete steps: 1. Simulate our transaction as we normally would. -2. If the simulation indicated it, we perform restoration via [`Operation.restoreFootprint`](https://stellar.github.io/js-soroban-client/Operation.html#.restoreFootprint) using its hints. +2. If the simulation indicated it, we perform restoration via [`Operation.restoreFootprint`](https://stellar.github.io/js-stellar-sdk/Operation.html#.restoreFootprint) using its hints. 3. We retry running our initial transaction. Let's see that in code: @@ -322,7 +321,7 @@ async function submitOrRestoreAndRetry( } // If simulation didn't fail, we don't need to restore anything! Just send it. - if (!sim.restorePreamble) { + if (!Api.isSimulationRestore(sim)) { const prepTx = assembleTransaction(tx, Networks.TESTNET, sim); prepTx.sign(signer); return yeetTx(prepTx); @@ -383,9 +382,9 @@ flowchart LR We need **both** to be live for our contract calls to work. -Let's work through how these can be recovered. The recovery process is slightly different for a convenient reason: we don't need simulation to figure out the footprints. Instead, we can leverage [`Contract.getFootprint()`](https://stellar.github.io/js-soroban-client/Contract.html#getFootprint), which prepares a footprint with the ledger keys used by a given contract instance (including its backing WASM code). +Let's work through how these can be recovered. The recovery process is slightly different: while we don't need simulation to figure out the footprints, we do need to do an additional fetch to determine where the WASM code lives on the ledger. We can leverage [`Contract.getFootprint()`](https://stellar.github.io/js-stellar-sdk/Contract.html#getFootprint), which will give us the ledger key used by a given contract instance, but not its backing WASM code. For that, we'll recreate [this example](/api/methods/getLedgerEntries#requesting-a-contracts-wasm-code). -Unfortunately, we still need simulation to figure out the _fees_ for our restoration. This, however, can be easily covered by the SDK's [`Server.prepareTransaction`](https://stellar.github.io/js-soroban-client/Server.html#prepareTransaction) helper, which will do simulation and assembly for us: +We also need simulation to figure out the fees for our restoration. This, however, can be easily covered by the SDK's [`Server.prepareTransaction`](https://stellar.github.io/js-stellar-sdk/Server.html#prepareTransaction) helper, which will do simulation and assembly for us: ```typescript import { @@ -403,24 +402,38 @@ async function restoreContract( signer: Keypair, c: Contract, ): Promise { + const instance = c.getFootprint(); + const account = await server.getAccount(signer.publicKey()); + const wasmEntry = await server.getLedgerEntries( + getWasmLedgerKey(instance) + ); + const restoreTx = new TransactionBuilder(account, { fee: BASE_FEE }) .setNetworkPassphrase(Networks.TESTNET) .setSorobanData( // Set the restoration footprint (remember, it should be in the // read-write part!) - new SorobanDataBuilder().setReadWrite(c.getFootprint()).build(), + new SorobanDataBuilder().setReadWrite([ + instance, + wasmEntry + ]).build(), ) .addOperation(Operation.restoreFootprint({})) .build(); - const preppedTx = await server.prepareTransaction( - restoreTx, - Networks.TESTNET, - ); + const preppedTx = await server.prepareTransaction(restoreTx); preppedTx.sign(signer); return yeetTx(preppedTx); } + +function getWasmLedgerKey(entry: xdr.ContractDataEntry): { + return xdr.LedgerKey.contractCode( + new xdr.LedgerKeyContractCode({ + hash: entry.val().instance().wasmHash() + }) + ); +} ``` The nice part about this approach is that it will restore both the instance and the backing WASM code if necessary, skipping either if they're already in the ledger state. From a9300be7786b8baa18e98d4babf3176b7661b2cd Mon Sep 17 00:00:00 2001 From: George Kudrayvtsev Date: Fri, 22 Dec 2023 12:30:13 -0800 Subject: [PATCH 2/3] Minor fixup and rewording --- docs/fundamentals-and-concepts/state-archival.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals-and-concepts/state-archival.mdx b/docs/fundamentals-and-concepts/state-archival.mdx index 5d7bf9cb..edc6e513 100644 --- a/docs/fundamentals-and-concepts/state-archival.mdx +++ b/docs/fundamentals-and-concepts/state-archival.mdx @@ -322,7 +322,7 @@ async function submitOrRestoreAndRetry( // If simulation didn't fail, we don't need to restore anything! Just send it. if (!Api.isSimulationRestore(sim)) { - const prepTx = assembleTransaction(tx, Networks.TESTNET, sim); + const prepTx = assembleTransaction(tx, sim); prepTx.sign(signer); return yeetTx(prepTx); } @@ -382,7 +382,7 @@ flowchart LR We need **both** to be live for our contract calls to work. -Let's work through how these can be recovered. The recovery process is slightly different: while we don't need simulation to figure out the footprints, we do need to do an additional fetch to determine where the WASM code lives on the ledger. We can leverage [`Contract.getFootprint()`](https://stellar.github.io/js-stellar-sdk/Contract.html#getFootprint), which will give us the ledger key used by a given contract instance, but not its backing WASM code. For that, we'll recreate [this example](/api/methods/getLedgerEntries#requesting-a-contracts-wasm-code). +Let's work through how these can be recovered. The recovery process is slightly different: while we don't need simulation to figure out the footprints, we do need to do an additional ledger entry fetch. We can leverage [`Contract.getFootprint()`](https://stellar.github.io/js-stellar-sdk/Contract.html#getFootprint) to get the ledger key used by a given contract instance, but that won't give us its backing WASM code. For that, we'll recreate [this example](/api/methods/getLedgerEntries#requesting-a-contracts-wasm-code) here. We also need simulation to figure out the fees for our restoration. This, however, can be easily covered by the SDK's [`Server.prepareTransaction`](https://stellar.github.io/js-stellar-sdk/Server.html#prepareTransaction) helper, which will do simulation and assembly for us: From 00a54e114285a22e37884771f1b83b06131bb8ab Mon Sep 17 00:00:00 2001 From: George Kudrayvtsev Date: Fri, 22 Dec 2023 12:33:18 -0800 Subject: [PATCH 3/3] Fixup another rename reference --- docs/reference/rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/rpc.mdx b/docs/reference/rpc.mdx index 3f3b3c36..23b7a0ea 100644 --- a/docs/reference/rpc.mdx +++ b/docs/reference/rpc.mdx @@ -7,7 +7,7 @@ The RPC service allows you to communicate directly with Soroban via a [JSON RPC For example, you can build an application and have it [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntries) and [event data](https://soroban.stellar.org/api/methods/getEvents), or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). -Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks), such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance to access the network. +Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks), such as the [stellar-sdk](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance to access the network. ## Run Your Own Instance for Development