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

# Swap history and recovery

> Check an existing swap and finish an interrupted claim in the Shield Swap app or with the SDKs or CLI.

<div className="shield-trade-switch not-prose" role="group" aria-label="Trading guide audience">
  <button type="button" id="trade-developers-option" data-trade-select="developers" aria-pressed="true" aria-controls="developers">Developers</button>
  <button type="button" id="trade-web-app-option" data-trade-select="web-app" aria-pressed="false" aria-controls="web-app">Web App</button>
</div>

If your swap went through but the output has not arrived, the output is waiting for its claim and you can collect it. A timeout, a closed window, or a restart does not undo the trade. This page helps you check what happened to a swap and finish it, in the Shield Swap app or with the SDKs or CLI.

## How recovery works

Every swap finishes in two steps, a swap and then a claim. [Swap](./swap#how-a-swap-settles) explains why. Recovery starts with the original trade: you check its history and status before deciding whether a claim is still needed.

In the app, Shield Wallet keeps the data that connects a swap to your wallet, so your history and any unfinished claims appear whenever that wallet is connected. With the SDKs or CLI, your trading tools retain that data. Reopening it allows you to find unfinished trades after a restart. A transaction ID helps you check what happened, but it does not replace the secret data needed to claim.

<div id="web-app" data-trade-view="web-app" role="region" aria-labelledby="trade-web-app-option" hidden>
  ## In the app

  **Before you start**

  You'll need: Shield Wallet connected to Shield Swap, using the same account that made the trade.

  ### Check a swap

  1. Open **Portfolio**.
  2. Select **History**.

  Each row shows the direction, the amount in, the amount out, the price, the **Status**, the **Route**, and when the trade happened. A trade that finished shows **Claimed**. \[VERIFY: the other values Status can show, such as a swap whose claim has not finished or a swap that failed]

  Use **All**, **Direct**, or **Multi-hop** to filter by route, and **Export CSV** to download the table. On the **Trade** page, **Your Trades** under the chart shows the same trades for the current market, with a **Remaining** column for any input the trade did not spend. On the **Swap** page, **Swap history** shows your most recent swaps, and **View All** opens **Portfolio**.

  ### Finish a pending claim

  1. Open **Portfolio**.
  2. Select **Pending Claims**.

  When nothing is waiting, the tab reads **No funds to recover**. The **Position funds** tile shows funds available from liquidity positions; it does not include pending swap outputs.

  3. Select **Claim** in the row for the swap.
  4. In **Review collection**, check the transaction details, then select **Confirm**.
  5. Approve the request in Shield Wallet.

  The received asset appears in your Shield Wallet balance, and the row leaves **Pending Claims**.

  <Warning>
    **Do not submit the swap again.** A second swap opens a new trade instead of finishing the first one. The output of the first swap is still waiting in **Pending Claims**.
  </Warning>

  Position funds also arrive here. If you decrease, close, or rebalance a liquidity position and its funds do not reach your wallet, they wait in the same tab. See [Manage positions](../liquidity/manage-positions).

  ### Troubleshooting

  | What you see | Why it happens | What to do |
  | - | - | - |
  | **History** is empty, but you made trades | Shield Swap shows the history for the connected account only. | Check which account is selected in Shield Wallet. Switch to the account that made the trade and connect again. |
  | A trade shows in **History**, but the received asset is not in Shield Wallet | The claim has not finished, or Shield Wallet has not refreshed its balance yet. | Open **Pending Claims**. If nothing is waiting, select the refresh control in Shield Wallet and check again. \[VERIFY: how long a balance can take to update after a claim] |
  | **Pending Claims** reads **No funds to recover**, but a swap seems stuck | The swap may still be pending, its claim may have finished, or the history check may be incomplete. | Check the original transaction in Shield Wallet and its explorer link. If its status is pending or unavailable, wait and check again. Do not submit another swap because the trade is missing from **History**. |
</div>

<div id="developers" data-trade-view="developers" role="region" aria-labelledby="trade-developers-option">
  ## Read account history

  **Prerequisites:** Use the same account and network that submitted the swap. These examples use the mainnet clients from [Setup](./configure), with the [original recovery store or journal](./configure#3-configure-optional-storage) reopened. For a testnet trade with saved recovery data, reopen its testnet store and set `--network testnet` in CLI commands.

  The Quickstart SDK snippets keep recovery data in memory. If that session is still open, continue with its original `client` or `shield_swap_client` and `handle` in [the claim step](./quickstart#4-wait-for-the-output-and-claim). Creating a new file store does not copy that session's recovery data.

  An empty SDK store does not restore saved claim data. The TypeScript examples use `client` and its `identities` store; Python uses `dex` with its original journal attached. Run CLI commands from the account directory used for the trade.

  <Tabs>
    <Tab title="TypeScript">
      Reconciliation matches your saved recovery data against transaction history. It can fill in missing swap IDs and claim results so you can distinguish completed trades from outputs still waiting to be claimed.

      ```typescript theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      const result = await client.reconcileSwapHistory({ maxPages: 40, pageSize: 50 })
      const records = await identities.load()
      const pending = await client.getUnclaimedSwaps()
      ```

      `records` contains your stored history, including `swapId`, `status`, and any saved `handle` or `claim`. `pending.swaps` lists outputs still present on chain; each has a `swapId` and a `claimable` flag indicating whether the store contains a usable handle.

      Both pagination options are optional integers. `maxPages` limits this search to 40 pages; omitting it allows the full history walk. `pageSize` sets calls per page, from 1 to 50, and defaults to 50.

      If `result.complete` is `false`, raise or omit `maxPages` to search farther back. `pending.unresolvable` lists stored identities whose swap IDs remain unknown. Even a complete history search cannot establish the outcome of a transaction still awaiting confirmation.
    </Tab>

    <Tab title="Python">
      Your journal records local swap submissions and confirmed claims. A submission can appear before its swap ID is known, then appear again after confirmation. Keeping the latest event for each transaction gives you one entry per submission:

      ```python theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      swaps = {}
      claims = {}
      for event in dex.journal.events():
          if event["type"] == "swap":
              swaps[event["transaction_id"]] = event
          elif event["type"] == "claim":
              claims[event["swap_id"]] = event
      ```

      `swaps` maps transaction IDs to their latest swap events. Each event's `swap_id` lets you find a matching entry in `claims`, which contains the claim's `transaction_id` and `amount_out` in base units.

      A swap with no `swap_id` still needs investigation; it is omitted from `dex.journal.pending_claims()`. A journal entry alone is not an independent chain confirmation, so check transaction status before submitting a claim.

      The journal saves the received amount but does not retain the refund amount. For refund accounting, retain `claim.amount_remaining` when a claim completes.
    </Tab>

    <Tab title="CLI">
      The history command combines saved recovery data with chain state. It can update local history without submitting a claim:

      ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      shield-swap history --network mainnet --json
      ```

      The JSON response includes `history` entries and an `owed` list of unclaimed outputs. Missing identifiers or claim amounts may need a transaction-history search:

      ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      shield-swap history --network mainnet --reconcile --pages 40 --json
      ```

      `--reconcile` forces a search even if local history looks complete. The optional integer `--pages` bounds the search; raise or omit it if the command reports that it stopped early. By default, the search has no page limit.

      The CLI also looks for account identities beyond those already saved. Its optional integer `--window` defaults to 16 counters beyond the last known identity. A bounded search can miss older activity separated by larger gaps.
    </Tab>
  </Tabs>

  Stored claim amounts use base units. Resolve the token's decimals before displaying received output or refunded input. Account history serves a different purpose from the [pool trade feed](../api-reference/pools/list-pool-trades), which reports public market activity rather than your account's recovery state.

  ## Establish the original outcome

  A transaction can succeed even when your application stops waiting for it. Use the original swap and claim transaction IDs with the [transaction lookup](./verify-settlement#check-both-transactions) before submitting anything else.

  | What you find | What to do next |
  | - | - |
  | The swap was accepted and its output is claimable. | Submit one claim for that swap ID, after checking that no claim is already pending. |
  | The claim was accepted, but your balance has not updated. | Wait for record scanning and check the returned records. Do not claim again. |
  | The transaction is pending, or its status cannot be retrieved. | Keep the original IDs and check again. Do not start a replacement trade. |
  | The transaction was rejected. | Inspect the rejection and your original records before preparing another operation. |
  | Your local entry has no swap ID. | Inspect its transaction or proving job and recover the ID before attempting a claim. |

  A missing pending-output entry on chain can mean the swap has not finalized or its output has already been claimed. The accepted transactions and returned records let you distinguish these cases. [Failures and recovery](./failures-and-recovery) covers unresolved transactions and scanner delays.

  ## Claim one pending output

  **Prerequisites:** Your original mainnet account and recovery store from [Read account history](#read-account-history), and an accepted swap whose output remains unclaimed. Replace `SWAP_ID` with that swap's ID from history, including its `field` suffix.

  <Warning>
    **Check that no earlier claim for this swap is still pending.** Run one claim worker for the swap so separate processes do not submit competing claims.
  </Warning>

  <Tabs>
    <Tab title="TypeScript">
      Find the original swap's handle in the store. The check below stops if its output is absent or the data needed to claim is missing:

      ```typescript theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      const swapId = "SWAP_ID"
      const available = await client.getUnclaimedSwaps()
      const swap = available.swaps.find(item => item.swapId === swapId)
      if (!swap?.handle || !swap.claimable) {
        throw new Error("No claimable handle; inspect the original transaction")
      }
      const claim = await client.claimSwapOutput({ handle: swap.handle })
      ```

      `claim.transactionId` identifies the claim transaction. `claim.amountOut` is the received output and `claim.amountRemaining` is refunded input, both as base-unit `bigint` values.
    </Tab>

    <Tab title="Python">
      Your journal supplies the saved handle. The claim call checks for the output on chain before preparing a transaction:

      ```python theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      swap_id = "SWAP_ID"
      handle = next((item for item in dex.journal.pending_claims()
                     if item.swap_id == swap_id), None)
      if handle is None:
          raise ValueError("No matching handle; inspect the original transaction")
      claim = dex.claim_swap_output(handle, timeout=60).delegate(wait=True)
      ```

      The optional numeric `timeout` waits up to 60 seconds for the output; its default of `0` checks once. `.delegate(wait=True)` submits the claim and waits for confirmation. If an error interrupts either stage, check transaction status before another attempt.

      `claim.transaction_id` identifies the claim transaction. `claim.amount_out` is received output and `claim.amount_remaining` is refunded input, both as base-unit integers.
    </Tab>

    <Tab title="CLI">
      Select the original swap explicitly so the command claims only that output:

      ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
      shield-swap history --claim --swap-id SWAP_ID --network mainnet --execute
      ```

      `--claim` requests a claim and `--execute` authorizes submission; both flags are off by default. `--swap-id` accepts the original ID as a string. Omitting it can claim other pending swaps. `--network mainnet` overrides the CLI's testnet default.

      The result includes the claim transaction ID and received amount for the selected swap.
    </Tab>
  </Tabs>

  After the claim is accepted, [check your spendable funds](./fund-and-bridge#check-spendable-funds). Use [Verify swap settlement](./verify-settlement) when you need to match the claim to its exact output record.

  ## Retain recovery data

  Your recovery store contains secret claim data as well as transaction history. Keep a protected backup with your account, and preserve it while investigating an unfinished swap. Resetting identity counters or deleting the journal can remove data needed to recover the trade. Raw handles and journal events do not belong in application logs.

  If the store is damaged or a transaction remains unresolved, keep a protected copy. The public transaction ID, network, SDK version, and stage where the operation stopped can help with investigation without exposing claim secrets.

  ## Next Steps

  ### Verify the completed trade

  [Verify swap settlement](./verify-settlement) shows how to confirm both transactions and match the claim to the funds received.

  ### Continue from packaged examples

  The [TypeScript recovery example](https://github.com/ProvableHQ/veil/tree/main/packages/shield-swap/examples/first-swap#recover-an-interrupted-swap) explains how to reuse its account and saved handles. The [Python recovery example](https://github.com/ProvableHQ/python-sdk/tree/master/shield-swap-sdk/examples/first-swap#recovery) covers its journal and recovery requirements. Follow their recovery instructions for an existing trade; rerunning a first-swap program starts a new one.
</div>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.