> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Restore archived contract data

> Restore archived persistent contract data using the Stellar SDKs

> [!NOTE]
>
> The manual operation (`RestoreFootprintOp`) is, for the most part, no longer needed starting in Protocol 23, as archived entries are automatically restored during `InvokeHostFunctionOp` when simulation includes them in the transaction's [restore list](https://developers.stellar.org/docs/learn/fundamentals/contract-development/storage/state-archival.md#contract-data-automatic-restoration). `RestoreFootprintOp` can be used in rare use cases [described in this section](https://developers.stellar.org/docs/learn/fundamentals/contract-development/storage/state-archival.md#restorefootprintop).

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:

1. Simulate our transaction as we normally would.
2. If the simulation indicated it, we perform restoration with a `RestoreFootprintOp` operation using the hints we got from the simulation.
3. We retry running our initial transaction.

Here's a function called `submitOrRestoreAndRetry()` that will take care of all those steps for us:

> [!NOTE]
>
> This guide makes use of the (aptly named) `submitTx` function we created in [another guide](https://developers.stellar.org/docs/build/guides/transactions/submit-transaction-wait.md).

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import {
  Networks,
  Keypair,
  Operation,
  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;
  }

  // No restorePreamble (the usual case since Protocol 23): just send it.
  // The invocation restores any archived entries in its restore list.
  if (!Api.isSimulationRestore(sim)) {
    const prepTx = assembleTransaction(tx, sim).build();
    prepTx.sign(signer);
    return submitTx(prepTx);
  }

  // Build the restoration operation using the RPC server's hints.
  const account = await server.getAccount(signer.publicKey());

  // Bid what recent transactions paid, capped at what you're willing to spend,
  // then add the resource fee from the restore preamble.
  const { sorobanInclusionFee } = await server.getFeeStats();
  const MAX_FEE = 100_000; // stroops per operation (0.01 XLM): pick your own cap
  let fee = Math.min(Number(sorobanInclusionFee.p90), MAX_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({}))
    .setTimeout(30)
    .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);
}
```
