Menese Protocol Integration
Repository
Section titled “Repository”- SDK: https://github.com/Menese-Protocol/MeneseSDK-V0
- mSOL/ICP-SOL integration: https://github.com/Menese-Protocol/MeneseSDK-V0/tree/main/msol-icp-sol-integration
- Sovereign Send integration: https://github.com/Menese-Protocol/MeneseSDK-V0/tree/main/sovereign-send-integration
- Billing guide: https://github.com/Menese-Protocol/MeneseSDK-V0/blob/main/msol-icp-sol-integration/developer-billing-integration-guide.md
OhShii is a Partner dApp
Section titled “OhShii is a Partner dApp”OhShii Launcher is an allowlisted partner on Menese’s Sovereign Send canister. This means:
- Free address derivation — the launcher’s vouched users don’t pay 45B cycles per
getMyAddress() - No subscription required — the launcher uses the per-tx fee model, not the MeneseSDK subscription
- 20% revenue share — of the 0.1% protocol fee on
sendSol/signSendoperations - Backend canister allowlisted — can call
registerPartnerUsers()to vouch for users
Partner vs non-partner
Section titled “Partner vs non-partner”| Partner (OhShii) | Non-partner | |
|---|---|---|
getMyAddress() cost | Free (vouched users) | 45B cycles (caller pays) |
| Subscription needed | No | Yes ($20-$323/mo) or cycles |
| Revenue share | 20% of 0.1% protocol fee | None |
| User registration | Backend calls registerPartnerUsers() | Must use registerSession(developerKey) |
depositSol() fee | 0% (pool’s own fee applies) | 0% (same) |
sendSol() fee | 0.1% atomic | 0.1% atomic |
Partner configuration (by Menese team)
Section titled “Partner configuration (by Menese team)”- Allowlisted backend canister:
vil43-piaaa-aaaal-qsibq-cai(prod) - Partner fee-share address:
BuqZagKKiRFUfxNFRKK7w3JymQgxuCy2rxFBdQTysMW4(assigned by Menese)
Canister IDs
Section titled “Canister IDs”| Canister | ID | Role |
|---|---|---|
| Sovereign Send | fxjsq-raaaa-aaaab-agdaa-cai | Signing canister — 0.1% fee model, no subscription |
| ICP-SOL Swap Pool (chain-key) | w2vjc-2yaaa-aaaab-ae6zq-cai | SOL↔ICP swaps at minimal slippage. NOT an oracle — legacy CROSSCHAIN_ORACLE_* code symbols are kept for API stability |
| ckSOL minter | crmds-kqaaa-aaaaf-qf5aq-cai | mSOL minting/redemption |
| mSOL ledger (ICRC-2) | 2ykjj-eyaaa-aaaae-af4ma-cai | mSOL token |
| MeneseSDK (legacy) | urs2a-ziaaa-aaaad-aembq-cai | Old subscription model — not used by OhShii’s current flows |
| ICP Ledger | ryjl3-tyaaa-aaaaa-aaaba-cai | ICP token |
Architecture Overview
Section titled “Architecture Overview”Conversion Flows
Section titled “Conversion Flows”Flow 1: SOL → ICP (via Sovereign Send — sign-only path)
Section titled “Flow 1: SOL → ICP (via Sovereign Send — sign-only path)”Status: Implemented — uses sign-only for reliable broadcasting. ICP arrives automatically in ~30-60s after Solana confirms.
Frontend code path: sovereignSend.js → depositSolForIcp(lamports, identityOrAgent)
Why sign-only instead of autonomous depositSol:
- The autonomous path (
depositSol) uses canister HTTP outcalls to broadcast — these can fail silently due to stale blockhash or HTTP errors, returningokwhile the SOL doesn’t actually move. - The sign-only path (
signDeposit) lets the launcher frontend fetch a fresh blockhash and broadcast directly via Solana RPC, which is faster (~0 cycles) and more reliable.
Broadcast honesty: broadcastSolTx tries the RPCs sequentially (first
acceptance wins) and then polls getSignatureStatuses until the transaction is
confirmed/finalized — RPC acceptance alone is never reported as success
(with skipPreflight, a stale-blockhash tx is accepted and then silently
dropped). The tx signature is always surfaced with a Solana explorer link, on
failures too.
Key facts:
signDeposithas 0% Sovereign Send fee — the pool applies its own 0.15% LP fee- Min deposit: 0.05 SOL
- Always reserve 935,880 lamports for Solana (890,880 rent-exempt minimum + 45,000 priority fee) via
maxSendLamports()— a transfer that would drop the derived account below the rent-exempt minimum is rejected. - No second call needed after broadcast — ICP release is automatic
- Cached users can deposit even if
registerPartnerUsersis temporarily failing
Flow 2: ICP → SOL (via the chain-key swap pool)
Section titled “Flow 2: ICP → SOL (via the chain-key swap pool)”Status: Implemented and working.
Frontend code path: solSwap.js → swapIcpToSol(e8s, solAddress, identityOrAgent)
Key facts:
- The swap pool pulls ICP via ICRC-2
transfer_fromafter the user’sicrc2_approve - OhShii charges a governance-configurable gateway fee (default 30 bps = 0.3%) in ICP. The fee is read live from the backend (
get_solana_gateway_fee_config; the frontend falls back to 30 bps if the query fails) and set viaadmin_set_solana_gateway_feethrough an approved ONS proposal (hard cap 1000 bps = 10%). It is collected on the backend canister’s default account (the DAO fee treasury) - The fee is charged only after the swap returns
ok— a user whose swap fails never loses the fee. If the fee transfer itself fails after a successful swap, the swap still succeeds and the uncollected fee is logged (the DAO’s loss, never the user’s) - The pool has its own fee (0.15% for LPs + dynamic spread up to 0.3%)
- The pool reserves are limited, so a large swap can exceed them — the UI reads
getCanisterInfoand blocks amounts whose quoted output exceeds the current reserve
Flow 3: SOL → mSOL (via Sovereign Send sign-only + ckSOL minter)
Section titled “Flow 3: SOL → mSOL (via Sovereign Send sign-only + ckSOL minter)”Status: Not available in the app. The frontend code (depositSolForMsol) signs, broadcasts, confirms the tx on Solana (getSignatureStatuses polling) and then calls expectCkSolDeposit(txHash, lamports) so the minter verifies the deposit on-chain and mints, but no part of the UI exposes this flow.
1. User sends SOL to derived address (same as Flow 1)2. Frontend: fetchSolanaBlockhash() via RPC3. Frontend: sovereignSend.signDeposit(CKSOL_MINTER, lamports, blockhash)4. Frontend: broadcastSolTx(signedTxBase64) via Solana RPC5. Frontend: cksol.expectCkSolDeposit(txHash, lamports) ← verifies on-chain6. ckSOL minter mints mSOL to user's principalNote: Unlike Flow 1, mSOL minting requires a second call (expectCkSolDeposit) to verify the Solana deposit. This is because the ckSOL canister verifies the tx on-chain before minting.
Flow 4: mSOL → SOL (redemption)
Section titled “Flow 4: mSOL → SOL (redemption)”Status: Not available in the app. The frontend code (redeemMsolToSol()) performs the ICRC-2 approve on the mSOL ledger (spender = ckSOL minter, amount + fee headroom) before requestCkSolRedemption, and the broadcast is confirmation-polled, but the UI has no redeem action.
1. Frontend: icrc2_approve(MSOL_LEDGER, spender=CKSOL_MINTER, amount)2. Frontend: cksol.requestCkSolRedemption(lamports, solAddress, memo)3. ckSOL burns mSOL, signs SOL transfer, returns signedTxBase644. Frontend: broadcasts signedTxBase64 to Solana via RPC5. User receives SOL at their Solana addressFlow 5: mSOL → ICP (two-step, presented as one action)
Section titled “Flow 5: mSOL → ICP (two-step, presented as one action)”Status: Not available in the app — phase 1 is redeemMsolToSol() (Flow 4), and like Flow 4 it is not exposed in the UI.
Phase 1 — mSOL → SOL: 1. Approve mSOL for burning 2. Redeem via ckSOL → get signed SOL tx 3. Broadcast to Solana 4. Poll derived SOL address until balance arrives (~15-30s)
Phase 2 — SOL → ICP: 5. depositSol(ICP_SOL_SWAP, balance) 6. ICP arrives automatically (~30-60s)Progress indicator: Approving → Redeeming → Broadcasting → Waiting for SOL → Converting to ICP → Complete
Summary: Where does mSOL fit?
Section titled “Summary: Where does mSOL fit?”mSOL is a separate Menese product, not an intermediate step in SOL↔ICP, and the OhShii app does not currently expose it. The flows above would let a user:
- Convert SOL to mSOL
- Convert mSOL back to SOL when they want native SOL
- Convert mSOL to ICP via the two-step flow (mSOL → SOL → ICP)
- Convert SOL directly to ICP without touching mSOL at all
User Registration (Partner Flow)
Section titled “User Registration (Partner Flow)”Registration is lazy: it runs only when the user explicitly enters a SOL→ICP flow (the SOL→ICP mode on the Solana tab, or the Solana participation box on a DAO page) and the gateway is verifiably healthy — never eagerly on tab mount. This stops the partner map from growing with visitors who never deposit and keeps a disabled/paused gateway from generating any Menese traffic.
1. Frontend (on SOL→ICP intent): backend.register_menese_user()2. Backend: sovereignSend.registerPartnerUsers([caller_principal])3. User is now vouched — free getMyAddress() and signDeposit()4. Frontend: sovereignSend.getMyAddress() → user's derived SOL addressThe backend rate-limits registrations (Shield: per-caller + global caps, PoW under Defcon) and records each vouched principal in a stable working set.
Revocation (incident response)
Section titled “Revocation (incident response)”admin_remove_menese_user(opt vec principal), invoked by the authorized caller
(an approved ONS proposal, “Revoke Menese Vouched Users”), calls Sovereign Send’s
removePartnerUsers. Passing null/empty revokes every principal in the
stable vouched working set in one call; passing a list revokes exactly those
principals (the explicit path forwards them verbatim, including principals the
working set does not record). The backend also self-reports its partner
state via the anonymous get_menese_partner_status query (last registration
outcome, vouched-set size, cached fee-treasury address).
Graceful degradation when registration is unavailable
Section titled “Graceful degradation when registration is unavailable”If registerPartnerUsers fails (allowlist reset, Sovereign Send maintenance, etc.):
- Cached users (anyone who previously called
getMyAddress): can still derive addresses and sign deposits.cachedUserssurvives allowlist resets. These users are NOT blocked. - New users (never used the Solana tab before): cannot get a derived address. The UI shows a warning that the Solana Gateway is temporarily unavailable for new users.
- ICP → SOL (swap-pool path): unaffected — does not use Sovereign Send.
- The deposit button remains enabled for users who have an address loaded.
- Registration is retried on next page load.
Fee Structure
Section titled “Fee Structure”Fees the launcher pays (to Menese/pool)
Section titled “Fees the launcher pays (to Menese/pool)”| Operation | Fee | Paid to |
|---|---|---|
getMyAddress() | Free (partner) | — |
depositSol() | 0% Sovereign Send + pool’s 0.15% LP fee | Pool LPs |
sendSol() | 0.1% atomic | Menese protocol |
swapIcpToSol() | 0.15% LP fee + dynamic spread (max 0.3%) | Pool LPs + swap pool |
Fees the launcher charges (to users)
Section titled “Fees the launcher charges (to users)”| Operation | Fee | Collected by |
|---|---|---|
| ICP → SOL | Governance-configurable, default 0.3% (30 bps); hard cap 10% | Backend canister (DAO fee treasury) — only after the swap succeeds |
| SOL → ICP | No OhShii fee | — |
The fee is stored on-chain (SolanaGatewayFeeConfig, get_solana_gateway_fee_config
query) and set by admin_set_solana_gateway_fee through the ONS “Set Solana Gateway Fee”
proposal. The frontend reads it live and falls back to 30 bps if the
query fails (it never silently drops to 0).
The gateway fee is a separate ICP transfer from the user’s wallet to the backend, made by the app after the swap succeeds; the swap pool itself does not collect it.
Revenue share (from Menese)
Section titled “Revenue share (from Menese)”- 20% of the 0.1% protocol fee on
sendSol/signSendoperations - Distributed in SOL on Solana, 7-day epochs, minimum 0.05 SOL
- Partner fee-share address:
BuqZagKKiRFUfxNFRKK7w3JymQgxuCy2rxFBdQTysMW4 - Applies to
sendSol/signSendonly. OhShii’s conversion flows use fee-freesignDepositdeposits and the ICP↔SOL swap pool — neither carries the 0.1% protocol fee — so OhShii usage generates no material fee-share. Consistent with this, the address holds only about the Solana rent-exempt minimum.
Solana Treasury (DAO management)
Section titled “Solana Treasury (DAO management)”The SystemStatus page’s “Menese / Solana Gateway” section shows the SOL balance of both surfaced addresses (public keyless RPC
getBalance) with explorer links. There is no movement/sweep tooling because OhShii’s flows do not accrue a fee-share (see below) — there is nothing to move.
Addresses surfaced
Section titled “Addresses surfaced”- Partner fee-share address
BuqZagKKiRFUfxNFRKK7w3JymQgxuCy2rxFBdQTysMW4— the address Menese assigns for the 20% share onsendSol/signSend. Read-only. - Menese protocol fee treasury —
getFeeTreasuryAddress()on Sovereign Send returns a single global address (the sink for the 0.1% protocol fee), identical for every caller. The backend fetches and caches it (admin_fetch_menese_treasury_address, invoked by the authorized caller) so the status page can read it via the anonymousget_menese_partner_statusquery and show its balance. It is Menese-controlled, not derived from the OhShii backend’s principal.
Fee-share and OhShii’s flows
Section titled “Fee-share and OhShii’s flows”The 20% partner fee-share is 20% of the 0.1% protocol fee on sendSol/signSend (peer-to-peer SOL transfers). OhShii’s Gateway does not use those operations: SOL→ICP goes through fee-free signDeposit, and ICP→SOL goes through the ICP↔SOL swap pool (the pool’s own LP fee, not the Sovereign Send protocol fee). OhShii usage therefore generates no material fee-share — consistent with the partner fee-share address holding only the rent-exempt minimum. Any share Menese does attribute is distributed Menese-side (SOL on Solana, 7-day epochs, min 0.05 SOL).
Partner status — how to verify per environment
Section titled “Partner status — how to verify per environment”The live Sovereign Send canister exposes getPartnerUserCount : (principal) -> (nat) query (a public query). To confirm the currently-deployed backend is a working partner, query getPartnerUserCount(<active backend principal>) and treat > 0 as registered. It reflects whichever backend is actually deployed. getShieldStatus() returns only aggregate counts and cannot prove membership of a specific principal.
This check is wired into the product in two places:
- SystemStatus page — the “Menese / Solana Gateway” section resolves the active backend from the deployed environment, queries
getPartnerUserCount(activeBackend)anonymously, and renders GREEN only when membership is proven AND the shield resolved AND the circuit breaker is off AND cycles are above the reserve AND the pool is unpaused (reachable-but-unproven renders amber, failures render red). - Backend self-report — the anonymous
get_menese_partner_statusquery returns the last registration outcome, the stable vouched-set size, and the cached Menese protocol fee-treasury address as the cheap complement to the authoritative live query.
Derivation Shield v3 — Cycle Drain Protection
Section titled “Derivation Shield v3 — Cycle Drain Protection”Ed25519 (Solana) doesn’t support hierarchical public key derivation like secp256k1/BIP-32. Unlike ckBTC (which derives child keys locally from a cached master public key), each Solana address derivation requires a threshold Schnorr signing call (~30B cycles).
Defense in Sovereign Send
Section titled “Defense in Sovereign Send”Sovereign Send (operated by Menese) protects itself against cycle drain with a circuit breaker on its own cycle balance, a global throttle on new derivations, and a caller allowlist for partner canisters. Cached users keep working when the circuit breaker is engaged.
Cost model
Section titled “Cost model”- Unknown callers: attach 45B cycles per derivation
- Cached users (anyone who derived before): free, bypass all layers
- Allowlisted partners + vouched users (the launcher): free derivation
Sovereign Send API Reference
Section titled “Sovereign Send API Reference”Core operations
Section titled “Core operations”| Method | Type | Fee | Description |
|---|---|---|---|
getMyAddress() | update | free (partner) | Get user’s derived SOL address |
signSend(to, lamports, blockhash) | update | 0.1% atomic | Sign SOL transfer — caller broadcasts |
sendSol(to, lamports) | update | 0.1% atomic | Autonomous send — not used by OhShii (see Flow 1 for why the sign-only path is preferred) |
signDeposit(target, lamports, blockhash, borrowParams?) | update | 0% | Sign-only deposit — RECOMMENDED |
depositSol(target, lamports, borrowParams?) | update | 0% | Autonomous deposit — not used by OhShii (see Flow 1) |
Partner management (called by allowlisted backend)
Section titled “Partner management (called by allowlisted backend)”| Method | Description |
|---|---|
registerPartnerUsers(Principal[]) | Vouch for users — max 50K per partner |
removePartnerUsers(Principal[]) | Remove previously vouched users |
Registered treasury targets for depositSol
Section titled “Registered treasury targets for depositSol”| Target | Canister | What you get |
|---|---|---|
| ICP-SOL Swap | w2vjc-2yaaa-aaaab-ae6zq-cai | ICP at swap-pool rate |
| mSOL (ckSOL) | crmds-kqaaa-aaaaf-qf5aq-cai | mSOL |
| SOL Borrow V3 | p7teu-wyaaa-aaaab-afnvq-cai | USDC loan against SOL collateral |
Implementation Status
Section titled “Implementation Status”| Component | Status | Notes |
|---|---|---|
| ICP → SOL swap | Working | Swap-pool direct call; governance-configurable gateway fee charged only after a successful swap; reserve-exhaustion guard in the UI |
| Price/quote queries | Working | Swap-pool query calls (both directions surfaced in the UI) |
| User registration (partner) | Working | Backend register_menese_user(), LAZY (on SOL→ICP intent, gateway-health-gated); graceful degradation for cached users |
| Partner revocation | Working | admin_remove_menese_user (ONS proposal) → removePartnerUsers, bulk revoke from the stable vouched set |
| SOL address derivation | Working | Sovereign Send getMyAddress() (cached users survive allowlist resets); lazy, gateway-health-gated |
| SOL balance check | Working | Via PublicNode/dRPC/Ankr RPCs; visibility-gated 10s poll with failure backoff |
| SOL → ICP deposit | Working | Sign-only (signDeposit + frontend broadcast) with on-chain confirmation polling; tx signature + explorer link surfaced |
| Broadcast confirmation | Working | Sequential RPC fallback + getSignatureStatuses polling; success reported only after confirmed/finalized |
| DAO-page Solana onramp | Working | SolanaDaoParticipationBox (SOL → ICP → LGE) on Active campaigns, fail-closed on gateway/pause/breaker/Guest-cap, hands off to the shared LGE purchase panel |
| Gateway health surfacing | Working | Shared SolanaGatewayStatus (SolanaTab + DAO box) + SystemStatus “Menese / Solana Gateway” section (env-aware getPartnerUserCount; green only when every check is proven) |
| SOL → mSOL deposit | Not exposed | Confirmed broadcast + expectCkSolDeposit in the frontend code; no UI |
| mSOL balance display | Not exposed | Hidden together with the whole mSOL surface |
| mSOL → SOL redemption | Not exposed | ICRC-2 approve in the frontend code; no redeem UI |
| mSOL → ICP conversion | Not exposed | Depends on the redemption above |
| Gateway fee (DAO-managed) | Working | SolanaGatewayFeeConfig on-chain, admin_set_solana_gateway_fee + ONS proposal, frontend reads live with a safe 30 bps fallback |
| Solana treasury visibility (DAO) | Working | SystemStatus section: partner fee-share + Menese protocol fee-treasury balances via public RPC, explorer links |
| Solana treasury movement / auto-sweep | Not applicable | OhShii’s flows (signDeposit + swap pool) don’t carry the 0.1% protocol fee, so no fee-share accrues — nothing to sweep |
| SOL→ICP awaiting-credit verification | Working | waitForIcpCredit polls the user’s ICP balance after Solana confirmation; timeout escalates with signature + explorer link + depositId (Menese-side, non-custodial) |
| ICP→SOL live status polling | Working | pollSwapUntilSettled surfaces the pool SwapRecord status (Pending/Refunded/Failed/Completed) in the LIVE flow; the error path re-attaches to a swap record the failed call may have created |
| Fault attribution | Working | Every gateway error is tagged with one owner (OhShii-config / Menese / Dfinity-minter / ICPSwap / network-user) + the correct next action (utils/crosschainFaults.js) |
| Swap history | Working | Newest-first (createdAt desc) + “Load more” pagination in SolanaTab |
| Dust display | Working | Rent-exempt-only residues render as “≈0 SOL” with tap-to-reveal exact + a precise why-note (0.00089088 rent + 0.000045 fee = 0.00093588 reserved); spendable math untouched |
| Treasury panel note | Working | ONS treasury panel carries a “Solana (Menese) gateway — visibility only” row: the DAO’s Solana revenue is the ICP gateway fee (already in the ICP row); no SOL is sweepable |
Solana RPC Configuration
Section titled “Solana RPC Configuration”The frontend uses an ordered list of Solana RPCs with sequential fallback (first success wins). Source of truth: src/frontend/src/utils/solConstants.js (SOLANA_RPCS).
| Provider | URL | Notes |
|---|---|---|
| Helius (primary, keyed) | https://mainnet.helius-rpc.com/?api-key=… | Domain-restricted API key (Helius Allowed Domains, Origin/Referer check). Skipped entirely when no key is configured |
| PublicNode (fallback 1) | https://solana-rpc.publicnode.com | Free, public, no API key |
| dRPC (fallback 2) | https://solana.drpc.org | Free, public |
| Ankr (fallback 3) | https://rpc.ankr.com/solana | Free, public |
The three public RPCs match the Menese SDK order. The Helius key is domain-restricted; on other origins (e.g. local development) the Helius call fails and the loop falls through to the public RPCs.
The frontend’s Content Security Policy (connect-src in src/frontend/.ic-assets.json5) allows these RPC hosts.
Stuck-state observability & recovery boundaries
Section titled “Stuck-state observability & recovery boundaries”Design invariant: observability is DERIVED from on-chain state the user can already read
for their own principal (tx signature, ICP block/balance, pool SwapRecord, getMySwaps,
Sovereign-Send depositId) plus client-side localStorage. There is NO per-user on-chain
error/status log — that would be a Sybil/DDoS vector.
SOL → ICP (deposit consumed, ICP not credited): after the Solana tx confirms, the UI polls
the user’s ICP balance (waitForIcpCredit) and, if no credit is observed in ~4 minutes,
escalates with the exact references (tx signature + Solscan link + Sovereign-Send depositId).
This state is Menese-side: every recovery method on the swap pool is admin-gated by Menese’s
key, and OhShii/DAO/guardian has NO lever to move funds inside the pool. The user’s reference
set is what Menese needs to investigate.
ICP → SOL (swap errored or hangs): the pool’s SwapRecord is authoritative. The live flow
polls getSwap(swapId) and renders Refunded (ICP returned by the pool), Failed
(escalate to Menese with the swap id) or Completed. Funds on the user’s OWN derived SOL
address are always re-spendable by retry — only the rent-exempt residue stays.
Fault owners: every error carries exactly one of ohshii-config (DAO toggle — wait),
menese (pool/Sovereign Send — retry/escalate with references), dfinity-minter (ckBTC side),
icpswap (ckBTC/ICP pool — self-service reclaim), network-user (retry/wait/top-up).
Integration notes
Section titled “Integration notes”- User registration goes through the backend’s
registerPartnerUsers, not a frontendregisterSession(developerKey). - Addresses come from Sovereign Send’s
getMyAddress(), not MeneseSDK’sgetMySolanaAddress(). - No
swapSolToIcp()call followssignDeposit()— ICP release is automatic in the partner flow. - Deposits use
signDeposit()+ frontend broadcast rather than the autonomousdepositSol()(see Flow 1). - A send never spends the full SOL balance: 935,880 lamports (890,880 rent-exempt + 45,000 fee) stay reserved via
maxSendLamports(). The ~0.00089 SOL rent-exempt residue stays on the derived address (Sovereign Send has no close-account method). - Cached users can still deposit when
registerPartnerUsersfails; the SOL→ICP deposit button is disabled only when the user has no address.
Frontend Code Map
Section titled “Frontend Code Map”| File | Purpose |
|---|---|
src/frontend/src/utils/solConstants.js | All canister IDs, RPC URLs, fee constants, utility functions |
src/frontend/src/utils/sovereignSend.js | SOL→ICP, SOL→mSOL, mSOL→SOL, mSOL→ICP, RPC helpers incl. broadcast + confirmation polling |
src/frontend/src/utils/solSwap.js | ICP→SOL (swap pool), price/quote queries, governance fee read (legacy autonomous-SDK paths removed) |
src/frontend/src/hooks/useSolanaGatewayHealth.js | Shared live gateway-health snapshot (partner count, shield/breaker, pool pause + reserves); fail-closed contract |
src/frontend/src/components/common/SolanaGatewayStatus.jsx | Shared in-page status surface (SolanaTab + DAO participation box) |
src/frontend/src/components/common/SolanaTxProgress.jsx | Shared tx progress/error callout with Solscan explorer link |
src/frontend/src/components/common/MeneseGatewaySection.jsx | SystemStatus “Menese / Solana Gateway” section (env-aware partner proof + treasury visibility) |
src/frontend/src/components/SolanaDaoParticipationBox.jsx | DAO-page SOL → ICP → LGE onramp (sibling of the Bitcoin box) |
src/frontend/src/components/TokenManagement/SolanaTab.jsx | Full Solana swap UI |
src/frontend/src/components/TokenManagement/BridgeTab.jsx | Cross-Chain Gateway tab wrapper (Bitcoin + Solana); filename kept for API stability |