feat: Create Pool view - #210
Conversation
295c4ef to
35c2dd7
Compare
bf72123 to
2b3ecad
Compare
00e595a to
2594ff2
Compare
2594ff2 to
e8c70fb
Compare
|
Still work in progress, although a lot of progress have been made. Expect things to still be buggy and the code to have architectural smells. For this to properly be implemented and run smoothly may require some changes in LEZ, SPEL and integration with ATA.
Also, I am still maturing the code itself. As the Create Pool view comes with a lot of details itself, the implementation have a lot of code, specifically on protocol.rs. This file is responsible for the business logic, while the API is responsible just to present information in a user-friendly manner. Something I took freedom to explore and implement was the automatic decimals of tokens - as the token program didnt had decimals, at least not in the direct code itself (might be in metadata once we standarize it), I analyzed the common decimals used by tokens overall the crypto world versus their total supply. This works only in QML, it's not part of business logic, and the definition is that the higher the total supply available of a token, the more decimals they have - I found this to be a fair way of demonstrating to the end-user how valuable their balance is, compared to the total supply. Currently the PR include a testnet configuration with a bunch of tokens I deployed in order to test the application, this tokens have several different configurations and name sizes - the configuration only contains the AccountId of the TokenDefinition, the rest is read from LEZ, and statically determined as the normalized PDA pool address. Additionally, would be very useful to have another issue/pr implementing a TokenProgram UI. I plan on extracting part of this implementation (such as chain detection, wallet and transaction) to a separate PR as a library, however we might want to decide that |
38a86de to
ca0b67d
Compare
57855e6 to
0605477
Compare
2dc502a to
1692581
Compare
Add program-neutral wallet access, a stable account model, reusable QML controls, transaction confirmation, submitted-transaction presentation, and isolated contract tests.
The Logos.Wallet QML plugin was installed with an ELF "$ORIGIN" rpath. macOS dyld does not expand "$ORIGIN", so loading the plugin failed with Cannot load library liblogos_wallet_qmlplugin.dylib: Library not loaded: @rpath/liblogos_wallet_qml.dylib even though liblogos_wallet_qml.dylib sits in the same directory. Select the rpath per platform: @loader_path on Apple, $ORIGIN elsewhere, so @rpath/liblogos_wallet_qml.dylib resolves to the sibling library.
Add a "Create Pool" flow to the AMM app that lets a user open a new liquidity position — seeding a pool's initial liquidity — from token selection and amount entry, through a confirmation dialog, to on-chain submission. - client crate (apps/amm/client): pure, testable protocol logic — account decoding, pair/position modelling, and quote/plan computation — exposed to the app over a C ABI (config/networks.json drives network selection). - C++ runtime + backend: AmmClient, ActiveNetwork, and NewPositionRuntime, wired into AmmUiBackend (new resolve/quote/submit slots). - QML flow: NewPositionForm, NewPositionFlow state, NewPositionConfirmation- Dialog, TokenSelectorModal, and reusable Amm* presentational components (theme, surfaces, buttons) + AmountMath.js. - tests: C++ (NewPositionRuntimeTest, ActiveNetworkTest) and QML (tst_NewPositionForm, tst_LiquidityPage, tst_TokenAmountInput, …).
Keep wallet assets as token choices without automatically selecting a pair. Keep pool-probe amounts internal so active-pool quotes do not populate the form before user input.
…BIN/TOKENS_CONFIG/wallet
The create-pool / new-position flow carried its own network layer:
AMM_UI_NETWORK + AMM_UI_DEVNET_FILE (a devnet.json) or a bundled
config/networks.json supplied the AMM program id and token set, and a
JSON-RPC channel/checkpoint "identity probe" gated the flow to a verified
network. Main already exposes all of this the way the Swap view consumes it,
so collapse onto those sources instead of a parallel system:
- ammProgramId <- $AMM_PROGRAM_BIN (derived like swapExactInput's program id;
doubles as the quote's network fingerprint so a quote can't
be replayed against a different deployment)
- tokenIds <- $TOKENS_CONFIG (amm-tokens.json), same as the Swap picker
- sequencer <- the wallet config (already surfaced via syncWalletState)
networkSnapshot() builds the ActiveNetworkSnapshot from those; status is
"ready"/"config_missing", gated to "loading" until wallet state resolves so no
module reads happen during construction. The channel probe is gone — submit
needs no channelId (the wallet module supplies the channel via
submitPublicTransaction), so the whole verification apparatus was overhead.
Removes: AMM_UI_NETWORK / AMM_UI_DEVNET_FILE, devnet.json / networks.json, the
ActiveNetwork class (+ its test) and its QNetwork channel probe, and Qt6Network.
ActiveNetwork.h keeps only the ActiveNetworkSnapshot struct. Run command drops
the AMM_UI_* vars:
```
LEE_WALLET_HOME_DIR=… AMM_PROGRAM_BIN=… TOKENS_CONFIG=… nix run .#amm-ui
```
774e340 to
44b355a
Compare
LogosWalletProvider::submitPublicTransaction passed the RISC0 instruction
words to send_generic_public_transaction as a QVariantList<u32>. That param
is a byte string (bstr): the module's QtRO glue mangles a list-of-u32 crossing
the module process boundary, so the guest deserialized a corrupted Instruction
variant and panicked, e.g.
Guest panicked: called `Result::unwrap()` on an `Err` value:
Custom("invalid value: integer `53765`, expected variant index 0 <= i < 10")
(53765 = 0x0000D205 — the guest read a 4-byte word where 0x05, the AddLiquidity
variant, is a single byte.) This broke every submit through the shared provider,
including the new-position / add-liquidity flow.
Send the little-endian bytes of the u32 words as a QByteArray instead — the same
encoding the AMM swap path already uses (it calls the module directly and never
went through this provider). signingRequirements stays a QVariantList<bool>;
only the instruction needed the bstr encoding.
…path networkSnapshot() rebuilt the new-position network context on every call — deriving ammProgramId from $AMM_PROGRAM_BIN and resolving the $TOKENS_CONFIG token ids, which run tokenList()'s remote account_id_from_base58 conversions. It is called on the quote hot path (every keystroke) and, critically, from inside runtime reply callbacks: after a create-pool submit, pool activation runs refreshContext() from within a quoteNewPosition reply, so the nested synchronous remote calls reentered the module connection and hung the reply. refreshNewPositionContext never completed, contextLoading never cleared, and the token selectors (gated on !contextLoading) stayed disabled — the view became unusable after creating a pool. $AMM_PROGRAM_BIN and $TOKENS_CONFIG are fixed for the process lifetime, so resolve ammProgramId and the token ids once and cache them; networkSnapshot() now returns the cached values with no per-call remote work. (Still gated to "loading" until wallet state resolves, so the one-time resolve happens at startup, not inside a callback.)
This is a Work in progress
Addresses #30
To run with devnet use
The devnet file should be in the following format, for example:
local-devnet.json:
{ "channelId": "0101010101010101010101010101010101010101010101010101010101010101", "sequencerAddress": "http://127.0.0.1:3040", "ammProgramId": "6a7fc14b8c4091208b04956113091766a3921eaa802d17d46bdfccac87dd7ebb", "tokenDefinitionIds": [ "1a23fb2d6b4b9de5dd99eabdea87387ba98a18be7c02311e577239b686ca7884", "9007fe66e65b3a496aa49fda60cab6ab218b6569b54c2df510806429f37cdfbe" ] }