Compare the paths
Start with the REST API quickstart for data. Use the TypeScript SDK when your application submits transactions. Direct program calls are for clients that need control below the SDK surface.
REST API
The API is the shortest path to indexed market state. It is appropriate for backends, bots, dashboards, explorers, and applications that do not submit Shield transactions. Start with:- List pools.
- Create an API token for routes and authenticated data.
- Handle pagination and retries.
- Use the generated API reference for exact parameters and responses.
TypeScript SDK
@provablehq/shield-swap-sdk adds Shield Swap actions to a Veil client. It handles token and pool discovery, import resolution, local record selection, confidential addresses, swap planning, claims, and the position lifecycle.
The SDK supports local keys and connected wallets. A local process must keep its confidential-address store and monitor transaction finality. A wallet integration delegates keys, records, and proofs to the wallet.
Continue with TypeScript SDK setup, swaps, and liquidity.
Transaction schemas
UseGET /schema/trading and GET /schema/trading/{id} when your wallet or application wants current input definitions for the configured deployment.
The schema does not perform the transaction. Your client still must:
- discover and reserve unspent token records
- preserve change and replacement records
- construct exact values and program identifiers
- sign and prove the transaction
- submit once and track accepted, rejected, or unknown state
- claim pending swap output
- reconcile public mappings with wallet-held records
Direct program calls
Use the direct path when the application must operate independently of the API or mirror contract behavior exactly.1
Bind the integration to one deployment
Record the network, program ID, edition, checksum, dependency revisions, and storage schema. Do not treat two deployments with the same source name as interchangeable.The current Q128.128 fee-growth layout is incompatible with scalar fee-growth deployments and requires a fresh deployment.
2
Generate complete types and parsers
Mirror nested Leo records and structs, including
u256::U256, MerkleProof, the immutable PositionNFT.withdrawal, and MintComplianceRecord where investigator records are handled.Parse nested structs structurally. Do not split Leo values on commas inside braces. Represent u128 and i128 with arbitrary-precision integers.3
Read the required mappings
Load pool identity, slot state, initialized ticks, positions, pending swap outputs, token settings, and control state required by the task.Version parsers by deployment checksum or release, not by a repository branch name.
4
Mirror amount and swap math exactly
Use native token base units in contract math. Apply display decimals only at the interface boundary. Match fixed-point operations, rounding direction, tick limits, price-limit rules, and iteration caps.Single-hop execution uses five swap iterations. Multi-hop execution uses three iterations per hop. Reaching an initialized tick exactly at the price limit completes the crossing.
5
Own record state
Discover records for the signer, verify token and amount, prevent double selection, preserve change, and mark a record spent only after acceptance is known.Every position change consumes a
PositionNFT. Store the replacement returned by increase, decrease, or collect.6
Create and retain the confidential address factor
Derive the public confidential address from the exact program address, domain constant, signer, and factor. Persist the factor until claim succeeds and never reuse the resulting address.A deterministic factor derived by a test client is a client convention, not a contract rule.
7
Treat swap and claim as one user workflow
After swap acceptance, read
swap_outputs[swap_id] and use its exact stored fields to construct the claim. Persist pending claims across restarts and network failures.8
Verify controls and final state
Read global, token, pair, pool, and position controls before construction. Refresh them before retrying because state can change before finalization.A visible success requires both the expected public mapping change and possession of the expected output records. Test routed calls where
caller != signer.