> ## 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.

# Quickstart

> Complete a testnet swap with the TypeScript SDK, Python SDK, or CLI.

Swap **1.5 USDCx for ETH on testnet** with an SDK or the CLI. A swap takes two transactions: the request and the claim.

The SDK steps follow the [Veil](https://github.com/ProvableHQ/veil/tree/main/packages/shield-swap/examples/first-swap) and [Python](https://github.com/ProvableHQ/python-sdk/tree/master/shield-swap-sdk/examples/first-swap) examples. Run them in order in one session; they use an existing testnet key and keep recovery data in memory. The [complete programs](#run-packaged-examples) also cover account creation and storage.

For a first trade from a terminal, we recommend the CLI.

## 1. Install and configure an account

For the SDKs, supply your existing testnet private key through `SHIELD_SWAP_PRIVATE_KEY` in the process environment. The CLI can create and save an account for you.

<Tabs>
  <Tab title="TypeScript">
    Use Node.js 22 or later in an ES module project:

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    npm install @provablehq/shield-swap-sdk@0.12.1 @provablehq/veil-aleo-sdk@0.12.1
    ```

    ```typescript theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    import { loadNetwork } from '@provablehq/veil-aleo-sdk'
    import { parseUnits, shieldSwapActions } from '@provablehq/shield-swap-sdk'

    const privateKey = process.env.SHIELD_SWAP_PRIVATE_KEY
    if (!privateKey) throw new Error('Supply a testnet private key')

    const aleo = await loadNetwork('testnet')
    const { walletClient, publicClient, account } = aleo.createAleoClient({ privateKey })
    const client = walletClient.extend(shieldSwapActions({ api: {} }))
    ```

    The client includes a record scanner to find spendable funds, plus delegated proving and fee payment.
  </Tab>

  <Tab title="Python">
    Use Python 3.11 or later:

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    python -m pip install "shield-swap-sdk==0.6.1"
    ```

    ```python theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    import os
    from aleo import Aleo, HTTPProvider, testnet
    from aleo_shield_swap import ShieldSwap

    aleo = Aleo(HTTPProvider("https://edge.provable.com/api", network="testnet"))
    private_key = testnet.PrivateKey.from_string(os.environ["SHIELD_SWAP_PRIVATE_KEY"])
    account = aleo.account.from_private_key(private_key)
    address = str(account.address)

    registration = aleo.records.register(account)
    if not registration["ok"]:
        raise RuntimeError(f"Record scanner registration failed: {registration['error']}")

    shield_swap_client = ShieldSwap(aleo)
    ```

    Registration lets the scanner find your account's records. The SDK decrypts the returned records locally.
  </Tab>

  <Tab title="CLI">
    Use Node.js 22 or later. Run these commands from the directory you will keep for the account:

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    npm install -g @provablehq/shield-swap-cli@0.12.1
    shield-swap setup --new --network testnet
    ```

    Setup saves the account, authenticates, and requests test tokens when needed. Keep `.shield-swap/testnet/` between sessions and out of source control.
  </Tab>
</Tabs>

## 2. Get test tokens

Your account needs spendable USDCx before you can trade. These examples authenticate and request test tokens if your existing balance is insufficient.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    await client.authenticateShieldSwap()
    const amountIn = '1.5'
    const from = await client.tokenData('USDCx')
    const balances = await client.getBalances({ tokens: [from.id] })
    if ((balances[from.id]?.private ?? 0n) < parseUnits(amountIn, from.decimals)) {
      await client.api.confirmAirdrop(account.address)
    }
    ```

    `confirmAirdrop` waits for the faucet transfer and its token records.
  </Tab>

  <Tab title="Python">
    ```python theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    shield_swap_client.api.authenticate(address, lambda message: str(private_key.sign(message.encode())))
    source = shield_swap_client.api.get_token("USDCx")
    amount_in = "1.5"
    if not shield_swap_client.has_swap_balance(source.address, amount_in):
        funding = shield_swap_client.confirm_airdrop()
        if not funding.success:
            raise RuntimeError(funding.error)
    ```

    `has_swap_balance` checks for one spendable record covering 1.5 USDCx.
  </Tab>

  <Tab title="CLI">
    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    shield-swap balances --network testnet
    ```

    Check for at least 1.5 USDCx in the `private` balance. If setup reports `AIRDROP_PENDING`, resume it with `shield-swap setup --network testnet`.
  </Tab>
</Tabs>

A swap spends one token record. If your balance is split across smaller records, [prepare a covering record](./preparing-token-records).

## 3. Quote and submit the swap

Quote **1.5 USDCx for ETH** with 50 basis points (0.5%) slippage. The SDKs choose the route and preserve the quote's minimum output when submitting. Each run submits a new swap.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    const quote = await client.quote({ from: 'USDCx', to: 'ETH', amountIn, slippageBps: 50 })
    const handle = await client.swap({ quote })
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    quote = shield_swap_client.quote(
        token_in="USDCx", token_out="ETH", amount_in=amount_in, slippage_bps=50,
    )
    handle = shield_swap_client.swap(quote).delegate(wait=True)
    ```
  </Tab>

  <Tab title="CLI">
    Preview the quote, then submit with `--no-claim` to collect the output in step 4:

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    shield-swap swap --from USDCx --to ETH --amount 1.5 --slippage 50 --network testnet
    shield-swap swap --from USDCx --to ETH --amount 1.5 --slippage 50 --network testnet --no-claim --execute
    ```

    `--execute` obtains a fresh quote and submits without another prompt. Keep the returned swap ID.
  </Tab>
</Tabs>

Keep `handle` available until you claim the output.

## 4. Wait for the output and claim

The claim delivers the output and any unused input to your account. Continue with the handle or swap ID from step 3.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    await client.waitForSwapOutput({ handle })
    const claim = await client.claimSwapOutput({ handle })
    if (claim.amountOut <= 0n) throw new Error('The claim returned no ETH')
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    claim = shield_swap_client.claim_swap_output(
        handle, timeout=5,
    ).delegate(wait=True)
    if claim.amount_out <= 0:
        raise RuntimeError("The claim returned no ETH")
    ```

    `.delegate(wait=True)` waits for claim confirmation.
  </Tab>

  <Tab title="CLI">
    Replace `SWAP_ID` with the ID from step 3, including its `field` suffix:

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

You're done when the claim confirms with a positive ETH amount. If a call times out, keep the session open and [recover the existing trade](./history-and-recovery) before retrying.

## Run packaged examples

The complete programs create or reuse a testnet account and perform the same **1.5 USDCx swap**. Each run starts a new trade.

<Tabs>
  <Tab title="TypeScript">
    With Node.js 22 or later and pnpm 10, run from a [Veil checkout](https://github.com/ProvableHQ/veil/tree/main/packages/shield-swap/examples/first-swap):

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    pnpm setup:first-swap
    cd packages/shield-swap/examples/first-swap
    npm start
    ```

    Keep the saved private key and recovery JSON file. The example's README explains how to reuse them.
  </Tab>

  <Tab title="Python">
    Run the [installed Python example](https://github.com/ProvableHQ/python-sdk/tree/master/shield-swap-sdk/examples/first-swap):

    ```bash theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
    python -m aleo_shield_swap.examples.first_swap.swap
    ```

    The example saves a generated account in a profile. Enable its optional journal before trading if you need swap recovery after a restart.
  </Tab>
</Tabs>

## Next Steps

[Setup](./configure) covers mainnet configuration. [Swap History & Recovery](./history-and-recovery) shows how to finish an existing trade, and [Verify swap settlement](./verify-settlement) checks its transactions and output records.


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