Skip to content
Merged
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
41 changes: 41 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[workspace]
members = [
"apps/amm/client",
"programs/token/core",
"programs/token",
"programs/token/methods",
Expand Down
47 changes: 42 additions & 5 deletions apps/amm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.21)
project(AmmUiPlugin LANGUAGES CXX)

find_package(Qt6 6.8 REQUIRED COMPONENTS Core Gui Network Qml Quick QuickControls2)
qt_standard_project_setup(REQUIRES 6.8)

find_package(PkgConfig REQUIRED)
pkg_check_modules(BASE58 REQUIRED IMPORTED_TARGET libbase58)

include(CTest)

if(DEFINED ENV{LOGOS_MODULE_BUILDER_ROOT})
include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake)
else()
message(FATAL_ERROR "LogosModule.cmake not found. Set LOGOS_MODULE_BUILDER_ROOT.")
endif()

set(LOGOS_WALLET_SOURCE_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/../shared/wallet"
CACHE PATH "Path to the shared Logos wallet module"
)
set(LOGOS_WALLET_GENERATED_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/generated_code"
CACHE PATH "Path to generated Logos SDK sources"
)
add_subdirectory("${LOGOS_WALLET_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/shared-wallet")

# ui_qml module with a hand-written C++ backend (QtRO .rep view contract +
# generated *SimpleSource/*ViewPluginBase). Mirrors the LEZ wallet UI module.
logos_module(
Expand All @@ -18,14 +36,33 @@ logos_module(
src/AmmUiPlugin.cpp
src/AmmUiBackend.h
src/AmmUiBackend.cpp
src/AccountModel.h
src/AccountModel.cpp
src/ActiveNetwork.h
src/AmmClient.h
src/AmmClient.cpp
src/NewPositionRuntime.h
src/NewPositionRuntime.cpp
FIND_PACKAGES
Qt6Gui
Qt6Network
LINK_LIBRARIES
Qt6::Gui
Qt6::Network
PkgConfig::BASE58
LINK_TARGETS
logos_wallet_access
EXTERNAL_LIBS
amm_client_ffi
amm_client
)

if(BUILD_TESTING)
add_executable(amm_new_position_runtime_test
tests/cpp/NewPositionRuntimeTest.cpp
src/NewPositionRuntime.cpp
)
target_include_directories(amm_new_position_runtime_test PRIVATE src)
target_link_libraries(amm_new_position_runtime_test PRIVATE
Qt6::Core
PkgConfig::BASE58
logos_wallet_access
)
add_test(NAME amm_new_position_runtime COMMAND amm_new_position_runtime_test)
endif()
39 changes: 25 additions & 14 deletions apps/amm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ Account/keystore sharing follows the runtime:
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.
> Follow-up: the app reconstructs the wallet paths itself because the
> `logos_execution_zone` module only exposes path-taking `create_new`/`open`.
> LEZ's wallet FFI now provides path-free variants (`wallet_ffi_create_new_default`,
> `wallet_ffi_open_default`, plus `wallet_ffi_default_config_path` /
> `_storage_path` / `wallet_ffi_wallet_exists_default`). Once the module surfaces
> those over QtRO, the app can drop its `defaultWalletHome/Config/Storage` logic.

## Setup

Expand Down Expand Up @@ -80,9 +82,11 @@ 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' \
# The core wallet module it depends on. These are the same immutable upstream
# revisions used by this app's flake, including the merged macOS Metal fix.
nix build 'github:logos-blockchain/logos-execution-zone-module?rev=d70225ced646934d2294fd9e8f8b03615c104b80#lgx' \
--override-input logos-execution-zone \
'github:logos-blockchain/logos-execution-zone?rev=a7e06a660940a00093b1760560d37ff84aff5a05' \
--out-link result-core
```

Expand Down Expand Up @@ -131,21 +135,23 @@ core module from `result-core/` and the UI plugin from `result-lgx/`:
4. Choose the core module `.lgx` from `result-core/`, then the UI plugin `.lgx`
from `result-lgx/`

To actually use the Swap view you must also set `AMM_PROGRAM_BIN` and
`TOKENS_CONFIG` (both explained below). Run this **from the repo root** — use
absolute paths (`$(pwd)/…`), because `nix run` may not preserve the working
directory, so relative paths won't resolve:
To actually use the on-chain views (**Swap** and **Liquidity**) you must also
set `AMM_PROGRAM_BIN` and `TOKENS_CONFIG` (both explained below). Both views read
the same two — the AMM program id is derived from `AMM_PROGRAM_BIN`, the token
set from `TOKENS_CONFIG`, and the sequencer from the wallet config. Run this
**from the repo root** — use absolute paths (`$(pwd)/…`), because `nix run` may
not preserve the working directory, so relative paths won't resolve:

```bash
AMM_PROGRAM_BIN=$(pwd)/programs/amm/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/amm.bin \
TOKENS_CONFIG=$(pwd)/amm-tokens.json \
nix run .#amm-ui
```

Without `AMM_PROGRAM_BIN` the Swap view stays disabled; without `TOKENS_CONFIG`
the token picker is empty. Each is detailed below.
Without `AMM_PROGRAM_BIN` the Swap and Liquidity views stay disabled; without
`TOKENS_CONFIG` the token picker is empty. Each is detailed below.

### AMM program binary (required for swaps)
### AMM program binary (required for swaps and liquidity)

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
Expand Down Expand Up @@ -204,6 +210,11 @@ TOKENS_CONFIG=$(pwd)/amm-tokens.json \
nix run .#amm-ui
```

## Validation

New Position validation commands and acceptance criteria live in
[VALIDATION.md](VALIDATION.md).

## Updating Dependencies

To update the pinned versions of dependencies in `flake.lock`:
Expand Down
52 changes: 52 additions & 0 deletions apps/amm/VALIDATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# AMM UI Validation

Validation for the New Position flow covers the shipped Rust client, QML
syntax, and the complete module build.

## Commands

Run from the repository root:

```bash
cargo +1.94.0 test -p amm_client
cargo +1.94.0 clippy -p amm_client --all-targets -- -D warnings
logos_qml=$(nix build github:logos-co/logos-design-system/6176f0d7a5dfeb64a7f0f98e7ca2bf71a4804772 --no-link --print-out-paths)
amm_qml=$(nix build ./apps/amm#packages.x86_64-linux.default --no-link --print-out-paths)
qt_qml=$(nix-store --query --requisites "$amm_qml" | rg -m1 -- '-qtdeclarative-[0-9]')
qt_svg=$(nix-store --query --requisites "$amm_qml" | rg -m1 -- '-qtsvg-[0-9]')
export QT_QPA_PLATFORM=offscreen QT_QUICK_BACKEND=software QT_PLUGIN_PATH="$qt_svg/lib/qt-6/plugins"
amm_import="$amm_qml/lib/qml"
test -f "$amm_import/Logos/Wallet/qmldir"
"$qt_qml/bin/qmltestrunner" -import "$qt_qml/lib/qt-6/qml" -import "$logos_qml/lib" -import "$amm_import" -input apps/shared/wallet/tests/qml
"$qt_qml/bin/qmltestrunner" -import "$qt_qml/lib/qt-6/qml" -import "$logos_qml/lib" -import "$amm_import" -input apps/amm/tests/qml
"$qt_qml/bin/qmllint" -I "$qt_qml/lib/qt-6/qml" -I "$logos_qml/lib" -I "$amm_qml/lib" -I "$amm_import" apps/amm/qml/pages/LiquidityPage.qml apps/amm/qml/components/liquidity/NewPositionForm.qml apps/amm/qml/components/liquidity/LiquidityConfirmationSummary.qml
```

When shared AMM program types or instruction signatures change, also run the
affected Rust checks:

```bash
RISC0_DEV_MODE=1 cargo +1.94.0 test -p amm_program
cargo +1.94.0 build -p idl-gen --release
./target/release/idl-gen programs/amm/methods/guest/src/bin/amm.rs > /tmp/amm-idl.json
diff artifacts/amm-idl.json /tmp/amm-idl.json
```

Live wallet/sequencer validation uses the configured Network and an External
Wallet Provider. Open the AMM UI, select two TokenProgram-scoped fungible token
definitions, preview an active or missing Pool, submit, and verify the returned
transaction ID is displayed.

## Acceptance Checklist

- Context exposes Wallet-Scoped Holdings and configured token definitions.
- Unsupported fee tiers are disabled and explain why.
- Active pool fee tier is fixed to the stored pool fee.
- Missing pool flow accepts an editable `X Token A = Y Token B` ratio and
scales either deposit from the minimum that mints more than
`MINIMUM_LIQUIDITY`.
- Active Pool flow keeps the reserve ratio and previews expected LP output.
- `new_definition` and `add_liquidity` account lists match the committed AMM IDL
order.
- Submit re-quotes and surfaces `quote_changed` when the request no longer
matches the preview hash.
24 changes: 24 additions & 0 deletions apps/amm/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "amm_client"
version = "0.1.0"
edition = "2021"

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

[dependencies]
alloy-primitives = { version = "1", default-features = false }
amm_core = { workspace = true }
borsh = { workspace = true }
clock_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0" }
hex = "0.4"
nssa_core = { workspace = true }
risc0-zkvm = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = "0.10"
token_core = { workspace = true }
twap_oracle_core = { workspace = true }

[dev-dependencies]
pretty_assertions = "1"
20 changes: 20 additions & 0 deletions apps/amm/client/include/amm_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef AMM_CLIENT_H
#define AMM_CLIENT_H

#ifdef __cplusplus
extern "C" {
#endif

char *amm_config_id(const char *request_json);
char *amm_token_ids(const char *request_json);
char *amm_pair_ids(const char *request_json);
char *amm_context(const char *request_json);
char *amm_quote(const char *request_json);
char *amm_plan(const char *request_json);
void amm_free(char *value);

#ifdef __cplusplus
}
#endif

#endif
Loading
Loading