Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Update the state archival JavaScript tutorial #698

Merged
merged 3 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions api/methods/getLedgerEntries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

:::
Expand Down Expand Up @@ -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(
Expand All @@ -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)
Expand Down Expand Up @@ -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');
}

Expand Down
37 changes: 25 additions & 12 deletions docs/fundamentals-and-concepts/state-archival.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -322,8 +321,8 @@ async function submitOrRestoreAndRetry(
}

// If simulation didn't fail, we don't need to restore anything! Just send it.
if (!sim.restorePreamble) {
const prepTx = assembleTransaction(tx, Networks.TESTNET, sim);
if (!Api.isSimulationRestore(sim)) {
const prepTx = assembleTransaction(tx, sim);
prepTx.sign(signer);
return yeetTx(prepTx);
}
Expand Down Expand Up @@ -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 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.

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 {
Expand All @@ -403,24 +402,38 @@ async function restoreContract(
signer: Keypair,
c: Contract,
): Promise<SorobanRpc.Api.GetTransactionResponse> {
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.
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/rpc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down