Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"programs/token/methods",
"programs/amm/core",
"programs/amm",
"programs/amm/client",
"programs/amm/methods",
"programs/ata/core",
"programs/ata",
Expand Down Expand Up @@ -38,6 +39,7 @@ token_core = { path = "programs/token/core" }
token_program = { path = "programs/token" }
amm_core = { path = "programs/amm/core" }
amm_program = { path = "programs/amm" }
amm_client = { path = "programs/amm/client" }
ata_core = { path = "programs/ata/core" }
ata_program = { path = "programs/ata" }
twap_oracle_core = { path = "programs/twap_oracle/core" }
Expand Down
22 changes: 22 additions & 0 deletions programs/amm/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "amm_client"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[lints]
workspace = true

[dependencies]
alloy-primitives = { version = "1", default-features = false }
amm_core = { path = "../core" }
amm_program = { path = ".." }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0" }
nssa_core = { workspace = true }
risc0-zkvm = { version = "=3.0.5", default-features = false }
serde = { workspace = true }
serde_json = { workspace = true }
token_core = { workspace = true }
twap_oracle_core = { path = "../../twap_oracle/core" }
83 changes: 83 additions & 0 deletions programs/amm/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# AMM client

`amm_client` is the stateless host boundary for the AMM program. It reuses
`amm_program::quote` for economic calculations, builds the actual
`amm_core::Instruction` variants, derives protocol accounts through core PDA helpers, and encodes
instructions with the RISC Zero Serde codec consumed by the guest.

The crate does not fetch accounts, manage keys, sign, or submit transactions. Those remain host
adapter responsibilities.

## Rust API

- `quote` validates fetched config, pool, vault, token-definition, LP-definition, and user-holding
snapshots before delegating calculations to `amm_program::quote`.
- `discovery` derives config and complete pair read manifests, then classifies raw pair snapshots
as missing or active without performing network I/O.
- `intent` prepares canonical opening amounts and caller/stored order mappings with integer-only
protocol math. It also converts exact human price ratios and token decimals into stored-order
Q64.64 prices without floating point.
- `slippage` converts validated quotes into integer-only instruction guards. Minimum guards round
down, maximum guards round up, and checked overflow returns a typed error.
- `plan` covers all ten guest instructions and returns the canonical instruction plus ordered
account roles and writable, signer, and init flags.
- `transaction` binds complete snapshots, canonical quotes, exact plans, caller amounts, wallet
prerequisites, and a refreshable quote commitment for create/add/remove/swap tasks.
- `TransactionPlan::instruction_data` serializes its `amm_core::Instruction` with
`risc0_zkvm::serde::to_vec`.
- `wire` exposes lossless JSON adapters for non-Rust hosts.

Planner coverage:

| Guest instruction | Planner |
|---|---|
| `Initialize` | `plan_initialize` |
| `UpdateConfig` | `plan_update_config` |
| `CreatePriceObservations` | `plan_create_price_observations` |
| `CreateOraclePriceAccount` | `plan_create_oracle_price_account` |
| `NewDefinition` | `plan_create_pool` |
| `AddLiquidity` | `plan_add_liquidity` |
| `RemoveLiquidity` | `plan_remove_liquidity` |
| `SwapExactInput` | `plan_swap_exact_input` |
| `SwapExactOutput` | `plan_swap_exact_output` |
| `SyncReserves` | `plan_sync_reserves` |

Quote coverage includes protocol constants, pair ordering, pool creation, preview and exact
add/remove liquidity, preview and exact-input/output swaps, reserve synchronization, and
oracle-price initialization. `prepare_create_pool`, `prepare_add_liquidity`,
`prepare_remove_liquidity`, `prepare_swap_exact_input`, and `prepare_swap_exact_output` return a
quote plus the exact amount fields to pass to the corresponding planner. Consumers choose a
slippage tolerance in basis points but do not calculate chain guards. Prepared add-liquidity maxima
preserve caller caps because substituting rounded actual deposits can change execution's
proportional integer quote. The task-level transaction API validates funding against those caps.

## Compatibility assumption

The client and deployed AMM are expected to be built from the corresponding source version. The
client performs no runtime ImageID, release-version, or program allowlist check. The supplied AMM
program ID is used for transaction targeting and canonical PDA derivation. Snapshot owner, account
relationship, and PDA checks remain normal protocol validation.

## C and JSON boundary

The built library exports:

```c
char *amm_client_plan(const char *request_json);
char *amm_client_quote(const char *request_json);
void amm_client_free(char *value);
```

Every call returns an owned JSON envelope. Release it exactly once with `amm_client_free`; passing
`NULL` to the free function is allowed. See [`include/amm_client.h`](include/amm_client.h) and
[`docs/wire-api.md`](docs/wire-api.md) for the complete transport contract.

Raw `u128` and `u64` values cross JSON as decimal strings. Account IDs use canonical base58.
Program IDs use exactly eight JSON `u32` words; hexadecimal and byte layouts are host-adapter-only.
Account data uses hexadecimal, and encoded instruction words remain JSON `u32` numbers. No
JavaScript `Number` conversion is required for chain amounts or deadlines. Plan JSON also includes
typed `instructionArgs`, derived directly from the same
`amm_core::Instruction` encoded in `instructionWords`. Only `amm_client_plan` accepts the five
snapshot-bound `prepare_*_transaction` operations. The quote entrypoint exposes
`human_price_ratio_to_q64_64`; hosts normalize RPC responses into canonical snapshots before
calling the client.
17 changes: 17 additions & 0 deletions programs/amm/client/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::env;

fn main() {
let Ok(target_os) = env::var("CARGO_CFG_TARGET_OS") else {
return;
};

// RISC Zero's host-side serde dependency contains guest syscall shims with exported C names.
// They are implementation details of this cdylib and would otherwise leak beside the three
// supported amm_client_* entry points.
if matches!(
target_os.as_str(),
"android" | "dragonfly" | "freebsd" | "linux" | "netbsd" | "openbsd"
) {
println!("cargo:rustc-cdylib-link-arg=-Wl,--exclude-libs,ALL");
}
}
Loading
Loading