Files
r4bbit 60a704661b refactor(amm): drop the Raw suffix from amount/value field names
The `*Raw` suffix on the module's amount/price/balance/LP fields was
redundant — every such field is already a base-unit integer, and there was
no formatted sibling to disambiguate from. Drop it across the whole wire
contract in lockstep: the amm_ffi request/response fields (snake_case
`amount_in_raw` → `amount_in`, serde `rename_all="camelCase"` keeps the JSON
keys mapped), the C++ module API, the QtRO `.rep`, the QML/app that consumes
it, the mjs tests, and the module README.

Examples: expectedOutRaw→expectedOut, minReceivedRaw→minReceived,
maxInRaw→maxIn, requiredInRaw→requiredIn, priceRaw→price, reserve{A,B}Raw→
reserve{A,B}, amount{In,Out}Raw→amount{In,Out}, expectedLpRaw→expectedLp,
lpAmountRaw→lpAmount, {max,min,minimum,actual}Amount{A,B}Raw, minimumLpRaw,
minLpRaw, selectedBalance*Raw, totalSupplyRaw, quote*Raw. This also unifies a
pre-existing inconsistency where resolvePoolAccount already emitted `reserveA`
and resolveTokens already emitted `balance`.

Kept where a formatted UI sibling of the same base name exists, so `Raw`
still disambiguates the base-unit value: amountARaw / amountBRaw (vs the
user-input `amountA`/`amountB`), balanceRaw (vs display `balance`), and
initialPriceRaw (vs formatted `initialPrice`). Also kept the format-boundary
helpers formatRaw / rawLpText / probeRaw / displayRaw / displayQuoteRaw /
boundRaw.

BREAKING: the `amm_module` public API field names change (logoscore /
Basecamp / QtRO consumers must update).
2026-08-20 21:11:48 +02:00
..

AMM UI tests

UI-driven tests for the AMM app, driving the running app through the QML inspector (framework from logos-co/logos-qt-mcp):

  • swap.mjs selects two tokens, enters an amount, submits a swap, and verifies the A/B pool reserves changed on-chain.
  • create-pool.mjs selects the A/C pair (which the setup script leaves unseeded — only A/B is created), submits a pool creation, and verifies the A/C pool now exists on-chain.
  • add-liquidity.mjs selects the seeded A/B pair, asserts the CTA stays disabled until deposit amounts are entered, submits an add, and verifies the A/B pool reserves grew on-chain.
  • custom-token.mjs pastes token D's id (created on-chain by the setup but deliberately absent from the token config) into a Liquidity token slot and verifies the app resolves it, selects it, and persists it to the custom-token store — the "add an unlisted token by id" path. No pool / submit involved.

Isolation

Test runs never touch your personal setup. Everything test-related lives under apps/amm/tests/testnet/ and is git-ignored:

Concern Test (isolated) Your local dev
Wallet home apps/amm/tests/testnet/.wallet/ ~/.lee/wallet/
Token config apps/amm/tests/testnet/amm-tokens.json apps/amm/amm-tokens.json

testnet/setup-amm-testnet.sh bootstraps an isolated wallet from a fixed mnemonic (test test … junk) so the token/holding account ids are deterministic and reproducible across machines, then deploys the programs, creates a seeded pool, and writes the test token config.

Full isolated run

From the repo root, with wallet / spel / cargo / nix on PATH, a local sequencer running, and the guest binaries built (make build-programs):

# 0. Once: build the JS test framework (symlinked where swap.mjs expects it)
nix build .#test-framework -o apps/amm/result-mcp

# 1. Bootstrap the isolated wallet + deploy programs + create the pool.
#    Writes apps/amm/tests/testnet/{.wallet, amm-tokens.json}. Nothing else is touched.
TEST_SEQUENCER_ADDR=http://127.0.0.1:3040 apps/amm/tests/testnet/setup-amm-testnet.sh

# 2. Terminal 1 — launch the UI against ONLY the isolated wallet + test tokens.
#    CUSTOM_TOKEN_CONFIG (where the app persists tokens added by id) defaults to the
#    per-user store; set it to an isolated path so custom-token.mjs controls the store
#    (it clears this file before + after running). Required for custom-token.mjs to
#    avoid touching your real custom-token store.
LEE_WALLET_HOME_DIR=$(pwd)/apps/amm/tests/testnet/.wallet \
  AMM_PROGRAM_BIN=$(pwd)/programs/amm/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/amm.bin \
  TOKENS_CONFIG=$(pwd)/apps/amm/tests/testnet/amm-tokens.json \
  CUSTOM_TOKEN_CONFIG=$(pwd)/apps/amm/tests/testnet/custom-tokens.json \
  nix run .#amm-ui

# 3. Terminal 2 — drive a test; watch it click through the live UI.
node apps/amm/tests/swap.mjs          # swap against the seeded A/B pool
node apps/amm/tests/create-pool.mjs   # create the (unseeded) A/C pool
node apps/amm/tests/add-liquidity.mjs # add liquidity to the seeded A/B pool
node apps/amm/tests/custom-token.mjs  # add token D (unlisted) by id

Headless CI variant (no window, launches the app itself, pass/fail only):

nix build .#integration-test -L

Notes

  • Wallet password. The wallet's key storage is encrypted with a password — the one you enter to unlock it (the UI's Connect modal) so the app can sign transactions. First-time setup reads a throwaway password (the script feeds it via stdin, so it doesn't block), then restore-keys rebuilds the wallet from the test mnemonic and sets the real password to TEST_WALLET_PASSWORD (default test). So unlock the UI with test. Prefer no password? Run with TEST_WALLET_PASSWORD="" and unlock with an empty password.
  • Re-bootstrap. FORCE_BOOTSTRAP=1 apps/amm/tests/testnet/setup-amm-testnet.sh re-restores the isolated .wallet (rewrites only that directory).
  • Overrides. TEST_WALLET_HOME, TEST_MNEMONIC, TEST_WALLET_PASSWORD, TEST_WALLET_DEPTH, TEST_SEQUENCER_ADDR — see the script header.
  • Framework location. swap.mjs loads ../result-mcp by default; override with LOGOS_QT_MCP=/abs/path/to/result-mcp.
  • Artifacts. On failure swap.mjs prints the SwapCard state and saves apps/amm/tests/swap-*.png (git-ignored) for inspection.

Files

  • swap.mjs — the end-to-end swap UI test (A/B pool).
  • create-pool.mjs — the end-to-end create-pool UI test (creates the A/C pool).
  • add-liquidity.mjs — the end-to-end add-liquidity UI test (adds to the A/B pool).
  • testnet/setup-amm-testnet.sh — isolated testnet + wallet bootstrap (TKA/TKB/TKC, seeds the A/B pool only).
  • qml/, cpp/ — the module's own QML/C++ unit tests.