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
amountis at leastamount_in. - Its
_nonceand_versionmatch the on-chain commitment. - The wallet can serialize it in the format expected by the SDK or CLI.
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:
scale. A record may contain a larger amount, but the public amount_in itself must satisfy this no-dust requirement.
Review Native token amounts 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:- Determine the concrete token program.
- Call
transfer_public_to_privatefor the signer. - Wait for acceptance.
- Locate the returned record output.
- Decrypt it with the signer’s key when needed.
- Preserve the complete record plaintext for later spending.
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
Selecting among records
The contract consumes one dynamic input record. It does not combine several small records insideswap.
A practical selector should:
- Filter by concrete token program or dynamic record identifier.
- Exclude records already marked spent or pending.
- Exclude records owned by a different signer.
- Choose a record whose amount covers
amount_in. - Prefer the smallest sufficient record when that reduces change-management cost.
- Reserve the record locally before transaction construction.
Change record behavior
The AMM requests an exact private-to-public transfer ofamount_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:
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 selectionreserved: assigned to a transaction that has not reached a terminal statusspent: consumed by an accepted transactionunknown: transaction outcome or record spend status cannot yet be confirmed
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:- Off-chain token metadata
- Concrete token-program record identity
- On-chain decimal registration
- On-chain pool-creation allowlisting
- Pool, token, pair, and global pause state
- Operator compliance policy and asset review
Confidentiality considerations
Token records keep their plaintext confidential from ordinary public observers, but the swap exposesamount_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
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_inis an exact native base-unit integer withinu128._nonceand_versionare 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.