Skip to content

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

Merged
BitHighlander merged 15 commits into
developfrom
swap-design
May 22, 2026
Merged

feat: asset picker v2, AssetPage inline drill, swap pre-selection#186
BitHighlander merged 15 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
BitHighlander and others added 10 commits May 20, 2026 21:04
… 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.
Picks up keepkey/hdwallet#43 — nodehid adapter now accepts PID 0x0002
(firmware 7.x) so HID fallback works when WebUSB is OS-blocked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
getSwapAssets, getSwappableChainIds, and getCachedBalances all returned
Solana/TRON/TON data regardless of connected device firmware. On firmware
7.10, stale DB cache from a prior 7.14+ session could populate the swap
FROM picker with those chains, and the TO picker showed them as available
destinations. Both paths ultimately hit device signing errors or confusion.

Now all three RPC handlers apply isChainSupported(chain, fwVersion) before
returning to the frontend, so unsupported chains are silently excluded.
…eaks, swap type)

- AssetPage: tx:confirmed events (txid-only, no chain) no longer dropped by the
  chain-match guard — refreshes correctly after SSE-confirmed transactions
- AssetPickerDialog: FromPicker total + HeldTile per-asset USD both masked in
  private mode (were leaking plaintext values)
- CommandPalette: balance amounts in search results now masked in private mode
- swap.ts: buildRelaySwapTx return type includes fromAmountBaseUnits (P2 type gap)
- bun/index.ts: hiveGetPublicKey and hiveSignTx RPC handlers (returns hex strings)
- rpc-schema.ts: hiveGetPublicKey and hiveSignTx schema entries
- docs/handoff-hive-integration.md: full stack integration handoff (hdwallet done, Pioneer remaining)
- bump modules/hdwallet to Hive adapter commit
…er hammer during blue/green

Previously retried every fixed 10s indefinitely on any error, flooding
logs and hammering Pioneer during blue/green deploy windows where the
SSE endpoint is temporarily absent.

- Exponential backoff: 10s base, doubles each failure, 5-min hard cap
- 404 jumps straight to 60s tier (route absent, not a transient glitch)
- Jitter ±10% prevents thundering-herd across concurrent vault instances
- Log throttling: prints on attempt 1 then every power-of-2 (1,2,4,8,16...)
- Backoff state resets to base on any successful connection
Switch modules/hdwallet from develop (8f0fa0da) to master (d83a65c3)
which adds TRON, TON, Zcash/Orchard, BIP-85, EVM clearsigning, and
all missing type-registry fixes. Cherry-pick 8f0fa0da (Hive wallet
adapter) onto master since that commit only lived on develop.
- Dashboard action row: icons 13→18px, each button gets a per-chain
  color (green receive, orange send, blue swap, violet privacy) with
  tinted bg; active state uses colored border instead of gold fill
- Privacy (shield) button added to dashboard action row for Zcash when
  zcashPrivacyEnabled is on; clicking it opens AssetPage pre-selected
  on the privacy tab
- AssetPage: extend initialAction to accept "privacy"; fix race where
  zcashPrivacyEnabled starts false and stomps the incoming view via the
  guard useEffect — gate the guard on settingsLoaded ref so the initial
  action is honoured before settings arrive
- AssetPage pill buttons restyled to match dashboard (colorful inline
  SVG icons, per-pill color/bg, colored border active state)
The orbital box size is width-based only (window.innerWidth - 420) and
can exceed the vertical space the sun Flex is allocated. On typical
viewports the ~440px orbital bled ~90px into the button row, making
the top half of Receive/Send/Swap unclickable when mousing in from above.

Fix:
- overflow:hidden + zIndex:1 on the sun Flex — clips any orbital bleed
- position:relative + zIndex:2 on the action button row — ensures
  buttons always sit above the orbital stacking context
@BitHighlander BitHighlander merged commit 62be61a into develop May 22, 2026
@BitHighlander BitHighlander deleted the swap-design branch May 22, 2026 20:28
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