The swap-submission plan derived the pool's vaults from the canonical token
order (compute_vault_pda(pool, canonical_token_a/b) via derive_pair), but the
guest asserts the provided vaults against the pool's stored vault_a_id /
vault_b_id, which are in the pool's *creation* order. compute_pool_pda_seed
canonicalizes, so the pool address is order-independent, but NewDefinition
stores def_a/def_b (and their vaults) as created — so for a pool created in
non-canonical order, the plan put vault_b in the vault_a slot and the guest
panicked with "Vault A was not provided", reverting the swap.
Read the pool account in swapExactInput and pass its data to
swap_exact_in_plan, which now uses pool.vault_a_id / pool.vault_b_id verbatim
for the vault slots (pool / current_tick / clock stay from derive_pair, since
those are order-independent). This restores the order-agnostic behavior the
original swap client had before it was rewired onto the canonical derive_pair
in 737b2f6.
Adds a regression test that builds a non-canonically-created pool (stored
def_a = the smaller-valued token) and asserts the plan emits the pool's stored
vaults, guarding that they differ from the canonical derivation.
lez-programs
Essential programs for the Logos Execution Zone (LEZ) — a zkVM-based execution environment built on RISC Zero. Programs run inside the RISC Zero zkVM (riscv32im-risc0-zkvm-elf target) and interact with the LEZ runtime via the nssa_core library.
Programs
| Program | Description |
|---|---|
| token | Fungible and non-fungible token program — create definitions, mint/burn tokens, transfer, initialize accounts, print NFTs |
| amm | Constant-product AMM — add/remove liquidity and swap via chained calls to the token program |
| ata | Associated Token Account program — derives and initializes deterministic token holding accounts for a given owner and token definition |
| stablecoin | Collateral-backed position program — open collateral positions as a foundation for stablecoin debt issuance |
| twap_oracle | TWAP oracle — provides canonical on-chain price accounts consumed by other programs (e.g. stablecoin) |
Apps
| App | Description |
|---|---|
| amm | QML-based UI for interacting with the AMM program |
Running Apps
Apps live under apps/ and are standalone UI applications. Each app has its own README.md with full details.
Apps use Nix flakes. Enable flakes if you haven't already:
mkdir -p ~/.config/nix && echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
Example (apps/amm)
The AMM UI is built from the repository-root flake (which also provides the
amm_client_ffi library it links). Run it from the repo root by its named
attribute — there is no bare nix run . default, so future apps are
nix run .#<name>:
# Run the app (from the repo root)
nix run .#amm-ui
# Update pinned dependencies
nix flake update
To use the Swap view, also set AMM_PROGRAM_BIN (your deployed amm.bin) and
TOKENS_CONFIG (your token list) — use absolute paths, from the repo root:
AMM_PROGRAM_BIN=$(pwd)/programs/amm/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/amm.bin \
TOKENS_CONFIG=$(pwd)/apps/amm/amm-tokens.json \
nix run .#amm-ui
See apps/amm/README.md for full details on both variables.
Prerequisites
-
Rust — install via rustup. The pinned toolchain version is set in
rust-toolchain.toml. -
RISC Zero toolchain — required to build guest ZK binaries:
cargo install cargo-risczero cargo risczero install -
SPEL toolchain — provides
spelandwalletCLI tools. Install from logos-co/spel. -
LEZ — provides
walletCLI. Install from logos-blockchain/logos-execution-zone
Build & Test
# Lint the entire workspace (skips expensive guest ZK builds)
make clippy
# Format check
make fmt
# Run unit tests for all programs (no zkVM, no ZK proof generation)
RISC0_DEV_MODE=1 cargo test -p token_program -p amm_program -p ata_program -p stablecoin_program -p twap_oracle_program
# Run integration tests (dev mode skips ZK proof generation)
RISC0_DEV_MODE=1 cargo test -p integration_tests
# Run all tests
make test
Integration tests live in programs/integration_tests/tests/ and cover token, amm, and ata programs end-to-end through the zkVM using RISC0_DEV_MODE=1 to skip proof generation. Each test file corresponds to a program:
programs/integration_tests/tests/token.rsprograms/integration_tests/tests/amm.rsprograms/integration_tests/tests/ata.rs
stablecoin and twap_oracle are tested via their own unit tests (cargo test -p stablecoin_program -p twap_oracle_program).
Compile Guest Binaries
The guest binaries are compiled to the riscv32im-risc0-zkvm-elf target. This requires the RISC Zero toolchain.
cargo risczero build --manifest-path <PROGRAM>/methods/guest/Cargo.toml
Binaries are output to:
<PROGRAM>/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/<PROGRAM>.bin
Deployment
# Deploy a program binary to the sequencer
wallet deploy-program <path-to-binary>
# Example
wallet deploy-program programs/token/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/token.bin
wallet deploy-program programs/amm/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/amm.bin
wallet deploy-program programs/ata/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/ata.bin
wallet deploy-program programs/stablecoin/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/stablecoin.bin
wallet deploy-program programs/twap_oracle/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/twap_oracle.bin
To inspect the ProgramId of a built binary:
spel inspect <path-to-binary>
Interacting with Programs via spel
Generate an IDL
The IDL describes the program's instructions and can be used to interact with a deployed program.
Using the idl-gen crate (no external toolchain required — this is what CI uses):
make idl
Using the spel CLI (requires the SPEL toolchain):
spel generate-idl programs/token/methods/guest/src/bin/token.rs > artifacts/token-idl.json
spel generate-idl programs/amm/methods/guest/src/bin/amm.rs > artifacts/amm-idl.json
spel generate-idl programs/ata/methods/guest/src/bin/ata.rs > artifacts/ata-idl.json
spel generate-idl programs/stablecoin/methods/guest/src/bin/stablecoin.rs > artifacts/stablecoin-idl.json
spel generate-idl programs/twap_oracle/methods/guest/src/bin/twap_oracle.rs > artifacts/twap_oracle-idl.json
Generated IDL files are committed under artifacts/. CI will fail if a program's IDL is missing or out of date.
Invoke Instructions
Use spel --idl <IDL> <INSTRUCTION> [ARGS...] to call a deployed program instruction:
spel --idl artifacts/token-idl.json <instruction> [args...]
spel --idl artifacts/amm-idl.json <instruction> [args...]
spel --idl artifacts/ata-idl.json <instruction> [args...]
spel --idl artifacts/stablecoin-idl.json <instruction> [args...]
spel --idl artifacts/twap_oracle-idl.json <instruction> [args...]