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

# Preparing token records

> How wallets select, preserve, and spend token records for confidential swaps.

Shield Swap does not debit a public wallet balance at the start of a user swap. The `swap` and `swap_multi_hop` functions consume an input token record and ask that token program to transfer the requested amount into the AMM's public custody.

Order construction must include record selection, spent-state checks, and change-record tracking.

## Outcome

You are ready to build a swap when:

* one record from the exact input token program is reserved for the attempt
* the record is owned by the signer, unspent, and large enough for `amount_in`
* the public amount satisfies the pool's scale requirement
* the client can serialize the complete record without dropping private fields
* the client is prepared to discover and store any change record returned by the input transfer

## Before you start

Confirm the concrete input record program, AMM token program, signer, target base-unit amount, asset kind, and current record commitments. A symbol or display name is not sufficient proof that a record belongs to the required program.

## Record requirements

The selected record must satisfy all of the following:

* It was created by the concrete input token program used by the pool.
* It is owned by the account signing the swap.
* It has not already been spent.
* Its private `amount` is at least `amount_in`.
* Its `_nonce` and `_version` match the on-chain commitment.
* The wallet can serialize it in the format expected by the SDK or CLI.

The selected record must originate from the exact input token program. Wrapper records with matching symbols or decimals remain distinct assets.

## Amounts are raw token units

`amount_in` uses the AMM token program's native base units. The core contract performs no decimal normalization.

For tokens with at most nine decimals, the scale is `1`. For a token with more than nine decimals:

```text theme={"languages":{"custom":["/languages/leo.tmLanguage.json"]}}
scale = 10^(decimals - 9)
internal_amount = raw_amount / scale
```

The raw input must be an exact multiple of `scale`. A record may contain a larger amount, but the public `amount_in` itself must satisfy this no-dust requirement.

Review [Native token amounts](../concepts/token-amount-normalization) before building amount controls for mixed-decimal markets.

## Acquiring a record

A wallet can use a record already in its local record store or call the input token program's public-to-private transfer path to create one:

1. Determine the concrete token program.
2. Call `transfer_public_to_private` for the signer.
3. Wait for acceptance.
4. Locate the returned record output.
5. Decrypt it with the signer's key when needed.
6. Preserve the complete record plaintext for later spending.

The token program performs this conversion. It neither deposits funds into the AMM nor establishes a pool position.

Production wallets should prefer an existing spendable record when possible. Repeated public-to-private conversion adds latency, fees, and a public funding event before the swap.

## Preserve record version and nonce

A token record includes private owner and amount fields plus public commitment metadata. The current helper preserves `_version` when it is present and defaults to version `1` only when parsing an older form.

Dropping `_version` can make the wallet derive a different commitment and cause a `Commitment does not exist` failure. Do not rebuild a record from owner and amount alone.

The record `_nonce` is unrelated to:

* The public swap nonce used in `swap_id`
* The counter used to derive a blinding factor
* The private blinding factor itself

Keep these values in separate typed fields in wallet storage.

## Selecting among records

The contract consumes one dynamic input record. It does not combine several small records inside `swap`.

A practical selector should:

1. Filter by concrete token program or dynamic record identifier.
2. Exclude records already marked spent or pending.
3. Exclude records owned by a different signer.
4. Choose a record whose amount covers `amount_in`.
5. Prefer the smallest sufficient record when that reduces change-management cost.
6. Reserve the record locally before transaction construction.

If no one record is large enough, acquire or construct a larger record through the token program before submitting the swap. Do not pass multiple records or assume the AMM will consolidate them.

## Change record behavior

The AMM requests an exact private-to-public transfer of `amount_in`. If the input record contains more, the token program returns a change record as a transition output.

The change record is not the same as an unfilled swap refund:

| Value        | Created when                                              | Source                                    |
| ------------ | --------------------------------------------------------- | ----------------------------------------- |
| Input change | The consumed record exceeds `amount_in`                   | Token transfer during the swap transition |
| Swap refund  | The AMM does not consume all native base-unit `amount_in` | `swap_outputs`, claimed later             |

A user can receive both. The wallet must discover and store the input change immediately, then claim the AMM refund after finalize.

## Record state machine

Use at least four local states:

* `available`: confirmed unspent and eligible for selection
* `reserved`: assigned to a transaction that has not reached a terminal status
* `spent`: consumed by an accepted transaction
* `unknown`: transaction outcome or record spend status cannot yet be confirmed

Do not return an `unknown` record to the available pool. Query transaction status and record commitment state first.

When a swap is accepted, atomically update the local store with the consumed record, any change record, the `swap_id`, and the pending claim. Local crashes between those writes are a common cause of apparently missing funds.

## Token metadata and record authority

The off-chain API supplies display metadata such as symbol, decimals, and wrapper program. Record spent state comes from chain data, token eligibility from contract mappings, and market approval from operator policy.

Keep these layers separate:

1. Off-chain token metadata
2. Concrete token-program record identity
3. On-chain decimal registration
4. On-chain pool-creation allowlisting
5. Pool, token, pair, and global pause state
6. Operator compliance policy and asset review

The seed script is operator tooling. It defaults to a production API endpoint and writes unless dry-run mode is selected. Wallet record handling and compliance controls are separate.

## Confidentiality considerations

Token records keep their plaintext confidential from ordinary public observers, but the swap exposes `amount_in`, pool, direction, price limit, minimum output, token identifiers, and timing as public data.

Wallets should still protect:

* Decrypted record plaintext
* Private keys and view keys
* Blinding factors and derivation counters
* Local links between records, swap identifiers, and user profiles
* Compliance record exports received through an authorized disclosure process

Avoid logging full record plaintext. Error messages should identify a local record by a non-sensitive internal handle or commitment, not by owner and amount.

## Pre-submit checklist

* The concrete record token matches the pool input side.
* The signer owns the record.
* The record is confirmed unspent.
* The record amount covers `amount_in`.
* `amount_in` is an exact native base-unit integer within `u128`.
* `_nonce` and `_version` are preserved.
* The record is locally reserved.
* Change-record discovery is enabled.
* Blinding recovery material is persisted.
* The quote and deadline were generated from recent state.

Continue with [Single-hop swaps](./single-hop-swaps) or [Multi-hop swaps](./multi-hop-swaps).
