feat: asset picker v2, AssetPage inline drill, swap pre-selection#186
Merged
Conversation
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
… 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
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan