Restore archived contract data using the JavaScript SDK
The manual operation (RestoreFootprintOp) is, for the most part, no longer needed starting in Protocol 23, as archived entries are automatically restored when they appear in a footprint during InvokeHostFunctionOp. RestoreFootprintOp can be used in rare use cases described in this section.
This is a pretty likely occurrence: my piece of persistent data is archived because I haven't interacted with my contract in a while. How do I make it accessible again?
If you find that a piece of persistent data is archived, it can be restored using a Stellar transaction containing a RestoreFootprintOp operation. We'll make two assumptions for the sake of this guide:
- The contract instance itself is still live (i.e., others have been extending its TTL while you've been away).
- You don't know how your archived data is represented on the ledger.
The restoration process we'll use involves three discrete steps:
- Simulate our transaction as we normally would.
- If the simulation indicated it, we perform restoration with a
RestoreFootprintOpoperation using the hints we got from the simulation. - We retry running our initial transaction.
Here's a function called submitOrRestoreAndRetry() that will take care of all those steps for us:
This guide makes use of the (aptly named) submitTx function we created in another guide.
import {
BASE_FEE,
Networks,
Keypair,
TransactionBuilder,
SorobanDataBuilder,
rpc as StellarRpc,
xdr,
} from "@stellar/stellar-sdk"; // add'l imports to submitTx
const { Api, assembleTransaction } = StellarRpc;
// assume that `server` is the Server() instance from the submitTx
async function submitOrRestoreAndRetry(
signer: Keypair,
tx: Transaction,
): Promise<Api.GetTransactionResponse> {
// We can't use `prepareTransaction` here because we want to do
// restoration if necessary, basically assembling the simulation ourselves.
const sim = await server.simulateTransaction(tx);
// Other failures are out of scope of this tutorial.
if (!Api.isSimulationSuccess(sim)) {
throw sim;
}
// If simulation didn't fail, we don't need to restore anything! Just send it.
if (!Api.isSimulationRestore(sim)) {
const prepTx = assembleTransaction(tx, sim);
prepTx.sign(signer);
return submitTx(prepTx);
}
// Build the restoration operation using the RPC server's hints.
const account = await server.getAccount(signer.publicKey());
let fee = parseInt(BASE_FEE);
fee += parseInt(sim.restorePreamble.minResourceFee);
const restoreTx = new TransactionBuilder(account, { fee: fee.toString() })
.setNetworkPassphrase(Networks.TESTNET)
.setSorobanData(sim.restorePreamble.transactionData.build())
.addOperation(Operation.restoreFootprint({}))
.build();
restoreTx.sign(signer);
const resp = await submitTx(restoreTx);
if (resp.status !== Api.GetTransactionStatus.SUCCESS) {
throw resp;
}
// now that we've restored the necessary data, we can retry our tx using
// the initial data from the simulation (which, hopefully, is still
// up-to-date)
const retryTxBuilder = TransactionBuilder.cloneFrom(tx, {
fee: (parseInt(tx.fee) + parseInt(sim.minResourceFee)).toString(),
sorobanData: sim.transactionData.build(),
});
// because we consumed a sequence number when restoring, we need to make sure
// we set the correct value on this copy
retryTxBuilder.source.incrementSequenceNumber();
const retryTx = retryTxBuilder.build();
retryTx.sign(signer);
return submitTx(retryTx);
}
Guides in this category:
📄️ Create a restoration footprint manually to restore archived data using the JavaScript SDK
Manually set up a restoration footprint with JavaScript SDK
📄️ Extend a persistent entry and contract using the JavaScript SDK
How to extend a persistent entry and contract using the JavaScript SDK
📄️ Restore a contract using the JavaScript SDK
Restore archived contract instance or contract code using the JavaScript SDK
📄️ Restore archived contract data using the JavaScript SDK
Restore archived persistent contract data using the JavaScript SDK
📄️ Test TTL extension logic in smart contracts
Test contracts that extend contract data time to live (TTL)