Skip to content

feat: asset picker v2, AssetPage inline drill, swap pre-selection#186

Open
BitHighlander wants to merge 7 commits into
developfrom
swap-design
Open

feat: asset picker v2, AssetPage inline drill, swap pre-selection#186
BitHighlander wants to merge 7 commits into
developfrom
swap-design

Conversation

@BitHighlander
Copy link
Copy Markdown
Collaborator

Summary

  • Asset picker v2 — square tile grid with 64px icons, full CAIP display, 2-step chain→asset flow for the TO side; real logos and correct provider color keys
  • Sidebar inline drill — clicking a chain in the sidebar now opens the AssetPage inline instead of full-screen, keeping context
  • Token asset page — dedicated per-token AssetPage with balance, price, and swap pre-selection
  • Swap pre-selection — navigating to a token's page pre-selects it as the FROM asset in SwapDialog
  • NEAR Intents ERC-20 fixes — swap-parsing and swap.ts fixes for NEAR Intents routes originating from ERC-20 sources

Test plan

  • Open asset picker — tiles render with 64px icons, chain filter works, 2-step chain→asset flow for TO side
  • Click a chain in the sidebar — AssetPage opens inline (not full-screen)
  • Click a token in AssetPage — opens token detail view
  • Click "Swap" from a token page — SwapDialog opens with that token pre-selected as FROM
  • NEAR Intents ERC-20 swap: quote and execute without "swap instructions" error

FROM picker: held-assets card grid sorted by USD value, with filter
search and an empty-wallet state.

TO picker: 2-step flow — chain selection grid (grouped: same network /
already hold / all supported / not routable) → asset list within the
chosen chain (sectioned: held / native / tokens). NetSwitchBanner shows
same-network vs cross-chain context. Unavailable-route view surfaces
alternative chains for the same symbol.

Implements the v2 handoff from the design bundle.
Chain cards and NetSwitchBanner now use AssetIcon (real coin logos)
instead of color-dot initials. Falls back to a color dot only when
chainMetaForCaip2 has no nativeCaip (unknown chains).

PROVIDER_COLORS keys corrected to match SwapProvider type
('thorchain' not 'THORChain', etc.) so provider dots actually render.
…first TO flow

FROM: flat list of all held assets ranked by USD, square tiles, 64px icons, full CAIP-19.
TO step 1: square network tiles — supported vs not-routable only (no same-network, no held-grouping).
TO step 2: paginated asset list (20/page) with text search, 64px icons, full CAIP-19.
Provider color keys corrected to match SwapProvider type.
Clicking a chain in the sidebar, orbital ring, donut chart, or donut
legend now sets drilledChainId and shows tokens + action buttons in the
dashboard center panel. The sidebar stays visible. Receive/Send/Swap
actions still route to AssetPage. Also moved the ViewPicker button from
TopNav to the dashboard hero area (top center).
UX
- Sidebar chain clicks drill inline (toggle drilledChainId) instead of opening full-screen AssetPage
- Token AssetPage: token-specific header with icon, name, contract address + explorer link, CAIP, price per unit
- Tokens section hidden when viewing a specific token
- ViewPickerButton moved from TopNav to Dashboard top-center
- Sidebar scrollbar: invisible by default, thin + semi-transparent on hover via .kk-sidebar-scroll class

Swap pre-selection
- AssetPage synthesizes SwapAsset from selectedToken and passes as initialFromAsset prop
- SwapDialog uses initialFromAsset directly, bypassing Pioneer's 19-asset GetAvailableAssets list
- Fixes USDC on Base (and any long-tail token) auto-selecting correctly as FROM asset

NEAR Intents ERC-20 fixes
- Normalize double 0x prefix on relay.to in parseQuoteResponse (Pioneer bug: "0x0x833589...")
- Detect isDirectTransfer (relay.to === token contract) and skip approval flow — NEAR Intents uses direct transfer(), not transferFrom() via router
- ERC-20 broadcast fallback: don't short-circuit to "not enough gas" on RPC insufficient-funds; fall through to Pioneer for ERC-20 relay txs where native balance is already verified sufficient
@BitHighlander BitHighlander requested a review from pastaghost as a code owner May 20, 2026 23:29
… cleanup

swap-tracker/registerWithPioneer:
- networkId now uses CAIP-2 from the CAIP-19 ("eip155:8453" not "base") — the
  swap monitor routes confirmation checking by networkId.startsWith('eip155:')
- sellAsset.address uses nearIntentsDepositAddress (from quote.meta.depositAddress)
  not inboundAddress, which was the token contract for ERC-20 routes
- amountBaseUnits uses fromAmountBaseUnits (integer string) not fromAmount (decimal)
- nearIntentsData.depositAddress included so the monitor can poll 1Click directly

swap-parsing: extract nearIntentsDepositAddress from txParams.recipientAddress
types: add nearIntentsDepositAddress to SwapQuote/PendingSwap, fromAmountBaseUnits to SwapResult/PendingSwap
swap.ts: thread fromAmountBaseUnits through buildRelaySwapTx and executeSwap
swap.ts: isDirectTransfer no longer skips the token balance check — only the
  approval check is gated; stale/insufficient balances now caught before signing

AssetPickerDialog: remove unused ReactNode/rpcRequest/EVM_CONTRACT_RE/t,
  fix invalid isTruncated Chakra prop, add CAIP/contract search, filter
  excludeCaip from tokenFallback results, make Notify button non-interactive
Root cause: firmware ethereum.c hashed only the LSB of chainId for EIP-1559
transactions (`hash_rlp_field((uint8_t*)&chain_id, 1)`), while the RLP length
calculation used the full multi-byte size. On little-endian ARM, chain_id=8453
(0x2105) hashed as 0x05 instead of 0x82 0x21 0x05, producing a different
keccak pre-image — signature recovered to a random address with 0 ETH.

Chains with chainId <= 255 (ETH=1, OP=10, BSC=56, Polygon=137) were
coincidentally correct because their full RLP encoding fit in 1 byte.
Affected: Base (8453), Arbitrum (42161), Avalanche (43114).

Firmware fix: replace hash_rlp_field((uint8_t*)&chain_id, sizeof(uint8_t))
with hash_rlp_number(chain_id) at ethereum.c:865 — the legacy EIP-155 path
already used hash_rlp_number correctly.

Vault workaround (swap.ts): force legacy gasPrice for chainId >= 256 in both
buildRelaySwapTx and buildEvmSwapTx so transactions use the correctly-
implemented EIP-155 signing path until users update firmware.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant