Add validated shared quote orchestration, canonical planners for every guest instruction, and exact RISC Zero serialization. Expose integer-only slippage preparation and lossless JSON/C adapters without runtime deployment identity checks.
8.0 KiB
AMM client JSON wire API
The C ABI accepts one tagged JSON object and returns one envelope:
{"ok":true,"value":{}}
{"ok":false,"error":{"code":"invalid_request","message":"..."}}
All u128 amounts, reserves, supplies, fees, nonces, and balances are unsigned decimal strings.
All u64 windows and deadlines are also decimal strings. Program IDs are arrays of eight u32
words. Account IDs are base58 strings. Account data is an even-length hexadecimal string.
Shared inputs
Plan context:
{
"ammProgramId": [0, 0, 0, 0, 0, 0, 0, 0],
"tokenProgramId": [0, 0, 0, 0, 0, 0, 0, 0],
"twapOracleProgramId": [0, 0, 0, 0, 0, 0, 0, 0],
"authority": "base58-account-id"
}
Decoded pool input used by existing-pool planners:
{
"poolId": "base58-account-id",
"definitionTokenAId": "base58-account-id",
"definitionTokenBId": "base58-account-id",
"vaultAId": "base58-account-id",
"vaultBId": "base58-account-id",
"liquidityPoolId": "base58-account-id",
"liquidityPoolSupply": "2000",
"reserveA": "1000",
"reserveB": "500",
"fees": "30"
}
Fetched account snapshot used by quotes:
{
"id": "base58-account-id",
"programOwner": [0, 0, 0, 0, 0, 0, 0, 0],
"balance": "0",
"nonce": "0",
"data": "00ff"
}
Existing-pool quote operations include these top-level state fields:
{
"ammProgramId": [0, 0, 0, 0, 0, 0, 0, 0],
"config": { "...": "account snapshot" },
"snapshot": {
"pool": { "...": "account snapshot" },
"tokenADefinition": { "...": "account snapshot" },
"tokenBDefinition": { "...": "account snapshot" },
"vaultA": { "...": "account snapshot" },
"vaultB": { "...": "account snapshot" },
"liquidityDefinition": { "...": "account snapshot" }
}
}
Plan operations
Send requests to amm_client_plan or wire::plan_json.
operation |
Additional fields |
|---|---|
initialize |
ammProgramId, tokenProgramId, twapOracleProgramId, authority |
update_config |
context, optional tokenProgramId, optional twapOracleProgramId, optional newAuthority |
create_price_observations |
context, poolId, windowDuration |
create_oracle_price_account |
context, poolId, windowDuration |
create_pool |
context, tokenADefinitionId, tokenBDefinitionId, userHoldingA, userHoldingB, userHoldingLp, tokenAAmount, tokenBAmount, fees, deadline |
add_liquidity |
context, pool, userHoldingA, userHoldingB, userHoldingLp, minAmountLiquidity, maxAmountToAddTokenA, maxAmountToAddTokenB, deadline |
remove_liquidity |
context, pool, userHoldingA, userHoldingB, userHoldingLp, removeLiquidityAmount, minAmountToRemoveTokenA, minAmountToRemoveTokenB, deadline |
swap_exact_input |
context, pool, userInputHolding, userOutputHolding, swapAmountIn, minAmountOut, deadline |
swap_exact_output |
context, pool, userInputHolding, userOutputHolding, exactAmountOut, maxAmountIn, deadline |
sync_reserves |
context, pool |
A successful plan value contains the following fields (instructionWords is abbreviated here):
{
"instruction": "add_liquidity",
"programId": [0, 0, 0, 0, 0, 0, 0, 0],
"accounts": [
{
"id": "base58-account-id",
"role": "config",
"writable": false,
"signer": false,
"init": false
}
],
"instructionWords": [5]
}
The real instructionWords array contains the complete encoding produced directly from the
canonical amm_core::Instruction with RISC Zero Serde. Account rows follow guest/IDL order.
Quote operations
Send requests to amm_client_quote or wire::quote_json. Except protocol_constants,
create_pool, and prepare_create_pool, every operation below also includes the existing-pool
quote state described above.
operation |
Additional fields |
|---|---|
protocol_constants |
none; returns decimal-string minimumLiquidity, feeBpsDenominator, slippageBpsDenominator, and supportedFeeTiers |
pair_order |
firstTokenDefinitionId, secondTokenDefinitionId |
create_pool |
ammProgramId, config, tokenADefinition, tokenBDefinition, tokenAAmount, tokenBAmount, feeBps |
prepare_create_pool |
same fields as create_pool; returns quote plus NewDefinition instruction arguments |
preview_add_liquidity |
maxAmountA, maxAmountB |
prepare_add_liquidity |
maxAmountA, maxAmountB, slippageBps |
add_liquidity |
maxAmountA, maxAmountB, minimumLiquidity |
preview_remove_liquidity |
userLiquidityHolding, removeLiquidityAmount |
prepare_remove_liquidity |
userLiquidityHolding, removeLiquidityAmount, slippageBps |
remove_liquidity |
userLiquidityHolding, removeLiquidityAmount, minimumAmountA, minimumAmountB |
preview_swap_exact_input |
userInputHolding, userOutputHolding, inputTokenDefinitionId, amountIn |
prepare_swap_exact_input |
userInputHolding, userOutputHolding, inputTokenDefinitionId, amountIn, slippageBps |
swap_exact_input |
userInputHolding, userOutputHolding, inputTokenDefinitionId, amountIn, minimumAmountOut |
preview_swap_exact_output |
userInputHolding, userOutputHolding, inputTokenDefinitionId, exactAmountOut |
prepare_swap_exact_output |
userInputHolding, userOutputHolding, inputTokenDefinitionId, exactAmountOut, slippageBps |
swap_exact_output |
userInputHolding, userOutputHolding, inputTokenDefinitionId, exactAmountOut, maximumAmountIn |
sync_reserves |
no additional fields |
create_oracle_price_account |
windowDuration |
Quote values use these result shapes:
- pool creation:
pool,lockedLiquidity,userLiquidity; - add liquidity:
actualAmountA,actualAmountB,liquidityToMint,pool; - remove liquidity:
withdrawAmountA,withdrawAmountB,liquidityToBurn,pool; - swaps:
direction,amountIn,effectiveAmountIn,feeAmount,amountOut,pool; - reserve sync:
donatedAmountA,donatedAmountB,pool; - oracle price:
baseAsset,quoteAsset,initialPriceQ64_64,windowDuration; and - pair order:
order(storedorreversed).
A pool result contains decimal-string liquidityPoolSupply, reserveA, reserveB, and
spotPriceQ64_64 fields.
Prepared instruction arguments
The five prepare_* operations return the economic result under quote and decimal-string chain
arguments under instructionArgs. Those fields map directly to the matching plan operation:
prepare_create_pool:tokenAAmount,tokenBAmount,fees;prepare_add_liquidity:minAmountLiquidity,maxAmountToAddTokenA,maxAmountToAddTokenB;prepare_remove_liquidity:removeLiquidityAmount,minAmountToRemoveTokenA,minAmountToRemoveTokenB;prepare_swap_exact_input:swapAmountIn,minAmountOut; andprepare_swap_exact_output:exactAmountOut,maxAmountIn.
slippageBps accepts 0 through slippageBpsDenominator (10,000) as an unsigned decimal
string. Minimum guards use integer floor rounding and stay at least one raw unit for positive
quotes. Maximum guards use integer ceil rounding. A maximum above u128 returns
slippage_bound_overflow; an out-of-range tolerance returns slippage_tolerance_out_of_range.
This calculation runs only in the Rust client, never in JavaScript or QML.
Prepared add-liquidity maximums are the quote's actualAmountA and actualAmountB, not the original
possibly lopsided caps. The exact quote is rerun with those fields before they are returned. This
keeps the eventual plan from spending above the displayed/current quoted deposits.
Ownership and failures
The client validates account decoding, configured owners, canonical PDAs, pool/vault/token/LP
relationships, swap input/output pairing, and required input balances. Quote arithmetic failures
retain the stable amm_program::quote::QuoteError code.
No request performs network I/O or checks an ImageID, release version, compatibility manifest, or program allowlist. Deployment configuration is expected to select the corresponding AMM build.