2026-04-15 12:51:14 +02:00
# AMM UI
A QML UI application for the Automated Market Maker (AMM) program.
See the [Logos QML UI App Tutorial ](https://github.com/logos-co/logos-tutorial/blob/master/tutorial-qml-ui-app.md ) for more information.
2026-06-24 14:50:17 +02:00
## Wallet / chain integration
This app is a `ui_qml` module with a hand-written C++ backend
(`src/AmmUiBackend.*` , plugin in `src/AmmUiPlugin.*` ) that depends on the core
**`logos_execution_zone` ** wallet module. The backend calls the core module's
wallet FFI through `m_logos->logos_execution_zone.*` and exposes an async QtRO
surface (`src/AmmUiBackend.rep` ) plus an account list model to the QML view.
**Onboarding is non-invasive.** The app opens straight to the Trade screen; the
navbar shows **Connect** (opens a password-only modal) or **Connected** + the
account selector. There is no path picking — the wallet uses LEZ's canonical
home, `~/.lee/wallet/` (override with `LEE_WALLET_HOME_DIR` , the same var LEZ
honors), and its config (`wallet_config.json` ) self-initializes.
Account/keystore sharing follows the runtime:
2026-07-13 22:20:12 +02:00
- **Standalone** (`nix run .#amm-ui` ): own core-module instance, but the canonical
2026-06-24 14:50:17 +02:00
`~/.lee/wallet` keystore is shared with the LEZ wallet UI and any other LEZ
app on the machine. A previously-created wallet auto-opens on launch.
- **Inside Basecamp**: the core wallet module is a single shared instance, so on
startup the backend **adopts** the already-open wallet (see
`openOrAdoptWallet()` ), surfacing **shared** accounts across apps.
> Follow-up: the wallet FFI requires explicit `config_path`/`storage_path` even
> though the wallet crate already defines defaults (`~/.lee/wallet`,
> `from_path_or_initialize_default`). A `wallet_ffi_create_new_default()` /
> `_open_default()` upstream would let the app drop its path handling entirely.
2026-04-15 12:51:14 +02:00
## Setup
This project requires Nix with experimental features enabled. If you haven't already, enable them permanently:
```bash
mkdir -p ~/.config/nix & & echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
```
2026-04-29 13:44:30 +02:00
Install the Logos package manager CLI globally (one-time):
```bash
nix profile install 'github:logos-co/logos-package-manager#cli '
```
This makes `lgpm` available as a global command.
## Running the UI standalone
2026-04-15 12:51:14 +02:00
2026-07-13 22:20:12 +02:00
The app is built from the **repository-root** flake (which also provides the
`amm_client_ffi` library it links). From the repo root, launch it with its named
attribute:
2026-04-15 12:51:14 +02:00
```bash
2026-07-13 22:20:12 +02:00
nix run .#amm -ui
2026-04-15 12:51:14 +02:00
```
2026-04-29 13:44:30 +02:00
This builds and runs the application in development mode. The Logos bridge is unavailable in standalone mode, but the UI layout and mock data are fully functional.
2026-07-13 22:20:12 +02:00
Build just the FFI crate with `nix build .#amm_client_ffi` . (Each UI is exposed
under its own name, so future apps are `nix run .#<name>` — there is no bare
`nix run .` default.)
2026-04-29 13:44:30 +02:00
## Running inside Logos Basecamp
This app is a UI plugin that depends on the **core wallet module**
`logos_execution_zone` (see the Wallet / chain integration section above). Both
have to be installed into Basecamp — the UI plugin alone will show the AMM tab
but fail to open it with `Failed to load core dependencies for amm_ui` .
### 1. Build the LGX packages
```bash
# The AMM UI plugin — development variant (requires nix store at runtime)
nix build '.#lgx ' --out-link result-lgx
# Portable variant (self-contained, works without nix)
nix build '.#lgx -portable' --out-link result-lgx-portable
# The core wallet module it depends on. Use the same rev this app pins as the
# `logos_execution_zone` input in flake.nix so the ImageID/ABI match.
nix build 'github:logos-blockchain/logos-execution-zone-module?rev=d2e9400ac06c3cdbfc2405b4f153fff9841a453c#lgx ' \
--out-link result-core
```
### 2. Install into Basecamp
```bash
# Launch Basecamp once to initialise its data directory, then quit (see below)
# Set the data directory path
# macOS:
BASECAMP_DIR="$HOME/Library/Application Support/Logos/LogosBasecampDev"
# Linux:
# BASECAMP_DIR="$HOME/.local/share/Logos/LogosBasecampDev"
# Install the core wallet module first (into the modules dir), then the UI plugin
lgpm --modules-dir "$BASECAMP_DIR/modules" \
install --file result-core/*.lgx
lgpm --ui-plugins-dir "$BASECAMP_DIR/plugins" \
install --file result-lgx/*.lgx
```
> **Note:** Use matching variants throughout — dev with dev, portable with portable. Mixing variants causes loading failures. The portable build uses the `LogosBasecamp` data directory instead of `LogosBasecampDev`.
### 3. Launch Basecamp
```bash
nix build 'github:logos-co/logos-basecamp' --accept-flake-config -o ~/.basecamp-result
~/.basecamp-result/bin/LogosBasecamp
```
The AMM UI appears as a new tab in the Basecamp sidebar.
> **Note:** `nix run 'github:logos-co/logos-basecamp'` currently fails with
> `unable to execute ... No such file or directory` — the flake's default app
> is named `logos-basecamp` but the packaged binary is `LogosBasecamp`. Build
> the package and run the `bin/LogosBasecamp` wrapper directly, as above.
### Installing via the Basecamp UI
Alternatively, use the built-in package manager. Install both packages — the
core module from `result-core/` and the UI plugin from `result-lgx/` :
1. Launch Basecamp
2. Open Package Manager
3. Select "Install from file"
4. Choose the core module `.lgx` from `result-core/` , then the UI plugin `.lgx`
from `result-lgx/`
2026-04-15 12:51:14 +02:00
2026-07-13 23:41:09 +02:00
### AMM program binary (required for swaps)
To execute a swap, the app must submit a transaction against the **exact AMM
program you deployed** (its ELF determines the program id, and therefore every
pool/vault/config PDA and the transaction's target). The app therefore needs the
deployed `amm.bin` bytes at runtime — it does **not** derive them from the wallet
module (whose embedded AMM program may differ from your deployment).
Point the app at your deployed binary with the `AMM_PROGRAM_BIN` environment
variable (absolute path):
```bash
AMM_PROGRAM_BIN=/abs/path/to/amm.bin nix run .#amm -ui
```
This is the same `amm.bin` you deployed via the testnet runbook
(`programs/amm/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/amm.bin` ).
The app reads it, derives the AMM program id (`amm_client_program_id_from_elf` ),
and reads the on-chain AMM config account to discover the TWAP oracle program id
for the pool's current-tick PDA. If `AMM_PROGRAM_BIN` is unset or unreadable, the
Swap view stays disabled (no pool can be resolved).
> **Golden rule (from the runbook):** recompiling the AMM changes its program id
> and *every* derived PDA. After any redeploy, point `AMM_PROGRAM_BIN` at the new
> `amm.bin` — never mix a stale binary with a fresh deployment.
2026-07-14 00:07:12 +02:00
### Token list config (required for the Swap token picker)
The Swap view's token picker is config-driven: it doesn't derive tokens from
chain state, it reads a flat JSON list from the `TOKENS_CONFIG` environment
variable (absolute path). Each entry needs, at minimum, the token's
`definitionId` and **your own** `holding` account address for that token (the
account the wallet will sign transfers from/to for that token):
```json
[
{
"symbol": "TKA",
"name": "Token A",
"definitionId": "9qbX…",
"holding": "4T69…",
"decimals": 18
}
]
```
If `TOKENS_CONFIG` is unset, unreadable, or not a valid JSON array, the token
picker stays empty (a `qWarning` is logged; no swap can be started).
```bash
AMM_PROGRAM_BIN=/abs/path/to/amm.bin TOKENS_CONFIG=/abs/path/to/tokens.json nix run .#amm -ui
```
2026-04-15 12:51:14 +02:00
## Updating Dependencies
To update the pinned versions of dependencies in `flake.lock` :
```bash
nix flake update
```
2026-04-29 13:44:30 +02:00
## Troubleshooting
**Stale QML cache after rebuild:**
```bash
QML_DISABLE_DISK_CACHE=1 ~/.basecamp-result/bin/LogosBasecamp
```
**Reset Basecamp data directory:**
```bash
# macOS
rm -rf ~/Library/Application\ Support/Logos/LogosBasecampDev
# Linux
rm -rf ~/.local/share/Logos/LogosBasecampDev
```