Add Kamino Limit Orders Solana preset#284
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new Solana preset to decode and render Kamino Limit Orders (LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) instructions using the existing IDL-driven visualizer pattern, so transactions no longer fall back to unknown_program raw bytes for this program.
Changes:
- Registered a new
kamino_limitpreset module in the Solana presets registry. - Implemented an IDL-backed
KaminoLimitVisualizerwith raw-data fallback on parse failure. - Bundled the Kamino Limit Orders Anchor IDL JSON and added a preset config allowlist for the program.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/chain_parsers/visualsign-solana/src/presets/mod.rs |
Exposes the new kamino_limit preset module. |
src/chain_parsers/visualsign-solana/src/presets/kamino_limit/mod.rs |
Implements the Kamino Limit Orders IDL-based instruction visualizer and unit tests. |
src/chain_parsers/visualsign-solana/src/presets/kamino_limit/config.rs |
Registers the Kamino Limit Orders program ID in the Solana integration config. |
src/chain_parsers/visualsign-solana/src/presets/kamino_limit/kamino_limit.json |
Adds the bundled Anchor IDL used for parsing/labeling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f437a3f to
2b04c96
Compare
prasanna-anchorage
left a comment
There was a problem hiding this comment.
Approving. Additive new preset (Kamino Limit Orders, program LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF); 4 files, all isolated to presets/kamino_limit/. Same template as the 10+ already-merged Solana presets. Rebased onto current main, clippy clean, 4 preset tests + the rest of the visualsign-solana suite pass locally. config.rs uses HashMap per existing convention; #288's sweep will flip it to BTreeMap when that PR lands.
#297) PR #288 forbade std::collections::HashMap/HashSet via clippy disallowed-types and converted the existing preset configs to BTreeMap, but missed the two presets that landed during the same review window: - exponent_finance (PR #275, merged 2026-05-12 22:00 UTC) - kamino_limit (PR #284, merged 2026-05-11 14:50 UTC) Both still constructed HashMap and passed it where SolanaIntegrationConfigData now expects BTreeMap, so `cargo build -p visualsign-solana` fails on post-#288 main. Verified locally: `cargo build -p visualsign-solana` and `cargo clippy -p visualsign-solana --all-targets -- -D warnings` are clean; `cargo fmt --check` passes. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merges origin/main (3bbf4e7) into the PR #255 branch. Resolves three content conflicts and ports two new presets from main to the wire-data VisualizerContext API introduced by PR #255. Conflicts resolved: - .gitignore: keep both `docs/superpowers/` (PR #255) and `.surfpool/` (main, from #294). - src/chain_parsers/visualsign-solana/src/presets/dflow_aggregator/mod.rs: take main's #286 changes (remaining-accounts surfacing, nested-arg flattening, `mut expanded_fields` + warn-on-parse-fail) on top of PR #255's wire-data API. The raw-data field is now pushed in place via `expanded_fields.push(create_raw_data_field(data, ...))` using `context.data()` instead of the removed `instruction.data`. - src/chain_parsers/visualsign-solana/src/presets/unknown_program/mod.rs: combine main's #288 determinism fix (locally-built `BTreeMap<String, String>` returned alongside the parsed payload, iterated at render time instead of `parsed.named_accounts`'s upstream `HashMap`) with PR #255's wire-data API (`context.program_id()`, `context.data()`, `context.num_accounts()`, `resolve_account_str(context, i)`). Imports remain `BTreeMap`; `HashMap` is no longer referenced. Two new presets ported to the wire-data API (same pattern as the existing `80b076b` port commit): - exponent_finance (from main #275): `current_instruction()` / `instruction.{program_id,data,accounts}` replaced by `context.resolve_program_id()?`, `context.resolve_accounts()?`, `context.data()`. Inline `expanded_fields.push(create_raw_data_field(...))` pattern; the unused `append_raw_data` helper deleted. - kamino_limit (from main #284): same API port. Function helpers (`build_named_accounts`, `build_parsed_fields`, `build_fallback_fields`, `append_raw_data`) retained -- they take `data: &[u8]` and `accounts: &[AccountMeta]` and remain useful. Both new presets' `config.rs` switched from `std::collections::HashMap` to `std::collections::BTreeMap` to satisfy main's #288 disallowed-types lint and the `SolanaIntegrationConfigData.programs: BTreeMap<...>` field shape. Verified: - cargo fmt clean - cargo check --workspace --exclude parser_cli clean - cargo check -p parser_cli clean - cargo test -p visualsign-solana --lib: 148 passed, 0 failed Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Why this PR exists
Kamino Limit Orders (program
LiMoM9rMhrdYrfzUCxQppvxCSG1FcrUK9G8uLq4A1GF) is a Solana DEX/limit-order program with no preset in this parser. Its instructions currently fall through tounknown_programand surface as raw bytes, so wallets cannot show users a human-readable description of operations likecreateOrder,takeOrder, orcloseOrderAndClaimTip.What changed
chain_parsers/visualsign-solana/src/presets/kamino_limit/with three files:mod.rs(visualizer),config.rs(program-instruction allowlist), andkamino_limit.json(IDL bundled at compile time).presets/mod.rs.VisualizerKind::Dex(...)since this is an order-book program.Why this is safe
A new preset adds a new
InstructionVisualizer; no existing program's output changes. The decoder uses the same generic IDL helpers askamino_vault/kamino_borrow/kamino_farms, with no Limit-Orders-specific code paths, so the failure modes are the same as those presets. If the IDL fails to parse (corruption, schema change), the visualizer falls back to a raw-data field — the same fallback every other IDL-based preset uses.The IDL JSON was fetched directly from the on-chain Anchor IDL account via
anchor idl fetch ... --provider.cluster mainnet. A fresh re-fetch produced a byte-identical 40191-byte file (sha256d57e19f4...46ed94), confirming the bundled file matches the canonical on-chain source — the same source Orb's/anchor-idlpage reads via Helius RPC.Checks run (by agent)
make -C src build— greenmake -C src lint(clippy with-D warnings) — greenmake -C src test— all workspace tests passanchor idl fetchinvocations produced byte-identical outputManual steps needed (by human)
None — fully automated by CI.
How this is maintainable
The preset follows the same shape as the three other Kamino presets already in this repo, so a fresh agent or developer who reads any of
kamino_vault,kamino_borrow, orkamino_farmswill know how to update this one.build.rsauto-discoversKaminoLimitVisualizerfrom the directory name, so the only manual registration is the one line inpresets/mod.rs. Workspace clippy (unwrap_used = deny,expect_used = deny,panic = deny) catches regressions, and the module's tests assert the bundled IDL keeps loading and every instruction carries a valid 8-byte discriminator if the JSON is ever refreshed.