fix: phase-one wallet hardening integration - #55
Conversation
Let users choose between the toolbar pop-up and Chrome side panel via Settings > Display mode. Side panel reuses the same React app with fluid layout; dApp approvals route to the panel with popup-window fallback. Co-authored-by: Cursor <cursoragent@cursor.com>
When display mode is side panel, always notify the panel and never fall back to approval popup windows if sidePanel.open() fails. Co-authored-by: Cursor <cursoragent@cursor.com>
Covers the case where an approval arrived while the panel was hidden or the runtime message was missed before the panel remounted. Co-authored-by: Cursor <cursoragent@cursor.com>
Open the side panel on the user-gesture chain before provider requests that may need approval. Persist connect/sign/tx pending state to chrome.storage.session so the side panel can restore after SW restarts. Also restyle the display mode settings icon to match other settings icons. Co-authored-by: Cursor <cursoragent@cursor.com>
Use the same solid/hollow evenodd split as the theme icon — a window frame with a cut-out side panel — instead of two thin filled blocks. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep fluid w-full h-full layout on SendReviewScreen from the side panel work. Co-authored-by: Cursor <cursoragent@cursor.com>
Exposes the wallet's existing internal fee estimation
(wallet:estimateTransactionFee -> vault.estimateTransactionFee, WASM
auto-calc) as a public dApp-callable provider method, so dApps can show
the required fee without duplicating transaction-building logic.
- Register nock_estimateTransactionFee in PROVIDER_METHODS (defined
locally until @nockbox/iris-sdk >= 0.3.0 is published) and
isProviderMethod()
- New background handler: gated on approved origin + unlocked vault
(read-only, no approval popup, same gating as nock_getWalletInfo);
validates params and returns { fee } in canonical nicks (string)
…mation Previously, omitting fee in nock_sendTransaction failed with 'Missing fee', forcing dApps to ask users for a fee or duplicate wallet/WASM transaction-building logic. Now, when a dApp omits fee: - The background estimates it via vault.estimateTransactionFee before showing the approval popup (estimation failure rejects the request up front with -32603, no dangling pending request) - The approval popup labels the fee as '(estimated)' - On approval, undefined is passed to vault.sendTransactionV2 so WASM auto-calculates the exact fee at build time, eliminating the 'Insufficient fee' late-failure for this path - The dApp response reports the actual fee used (walletTx.fee) Explicitly-provided fees keep the existing behavior verbatim: parsed with allowZero, respected as-is, and echoed back in the response.
For omitted-fee nock_sendTransaction, approval now passes the wallet's fresh estimate as the fee (matching the popup send flow) instead of undefined. The undefined branch in sendTransactionV2 reserves a 2-NOCK placeholder for note selection, so an account that could afford amount + estimate but not amount + 2 NOCK failed at approval with 'Insufficient available funds'. Passing the concrete estimate sizes note selection to the fee actually shown and charged. Also drops the '~' prefix on the popup fee since the displayed value is now applied verbatim rather than approximated. Addresses review feedback (P2) on PR #52.
Fixes the failing typecheck-and-format CI check. Co-authored-by: Cursor <cursoragent@cursor.com>
chrome.sidePanel and chrome.tabs are unavailable in content scripts, so the previous content-script open call never ran. Open the panel synchronously in the onMessage listener instead, where Chrome preserves the dApp click gesture (any await consumes it), using an in-memory display mode cache. Co-authored-by: Cursor <cursoragent@cursor.com>
- Replace the 15 numbered wallet icons with a new 29-icon pack: 5 kept classics (styles 1, 2, 3, 8, 14 - default unchanged) plus 24 new iris-themed icons, normalised to the shared tintable-SVG convention (var(--fill-0) placeholder, container-sized root). - Add shared/walletStyles.ts as the single source of truth: icon registry with visual families (picker groups similar icons together), a 17-colour palette (7 existing + 10 new in the same poppy scheme), and a deterministic assignment sequence that round-robins across icon families and strides the colour rainbow so consecutive wallets always look distinct; combinations only repeat after all 493 are used. - Switch persisted iconStyleId to stable string ids with transparent migration of legacy numeric ids (retired styles fall back to default). - Drive AccountIcon and WalletStylingScreen from the shared registry. https://claude.ai/code/session_01EPxCTHkLN8QM5iuNR5qqrn
feat: replace wallet icon pack and rework style assignment logic
…1-fee-sidepanel-integration
|
| Filename | Overview |
|---|---|
| extension/background/index.ts | Integrates display-mode routing, approval persistence and validation, advisory-fee handling, and hardened raw-transaction approval. |
| extension/shared/vault.ts | Adds transaction-intent verification and reconciles reservations, fees, inputs, change, and history with the transaction produced by WASM. |
| extension/shared/transaction-fee.ts | Introduces bounded advisory-fee retry and strict reconciliation helpers for built transaction inputs and amounts. |
| extension/shared/pending-approval-state.ts | Adds serializable pending-approval snapshots with filtering, expiration handling, and queue promotion. |
| extension/content/index.ts | Hardens the page-to-extension message envelope and supplies authoritative extension-side display context. |
| extension/popup/hooks/useApprovalDetection.ts | Updates approval discovery and routing to support both popup and side-panel surfaces. |
| extension/shared/constants.ts | Defines display-mode, auto-lock, runtime-message, and approval-related constants used by the integrated hardening flow. |
| package.json | Adds the Vitest-based test command and development dependency. |
| .github/workflows/ci.yml | Runs the test suite as part of the required CI workflow. |
Sequence Diagram
sequenceDiagram
participant D as dApp
participant B as Background worker
participant U as Approval UI
participant V as Vault/WASM
participant N as Network
D->>B: Provider transaction request
B->>V: Estimate advisory fee when omitted
B->>U: Display approval request
U->>B: Approve
B->>B: Revalidate origin, account, and requester
B->>V: Reserve notes and build transaction
alt Advisory fee is underfunded
B->>V: Reserve remaining available notes
B->>V: Retry build once
end
V-->>B: Actual inputs, fee, and change
B->>N: Broadcast built transaction
B->>V: Reconcile reservations and history
B-->>D: Transaction result
Reviews (1): Last reviewed commit: "fix: harden advisory fees and raw signin..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9a62b42ec
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| method === PROVIDER_METHODS.SEND_TRANSACTION || | ||
| method === PROVIDER_METHODS.GET_WALLET_INFO || | ||
| method === PROVIDER_METHODS.SIGN_TX || | ||
| method === PROVIDER_METHODS.ESTIMATE_TRANSACTION_FEE || |
There was a problem hiding this comment.
Bypass SDK mapping for the locally added fee method
When a dApp calls nock_estimateTransactionFee without an api field—the supported default-provider request shape—resolveSourceApiVersion treats it as API 0 and this classification sends it through mapRpcRequest from @nockbox/iris-sdk 0.2.0. That SDK predates this locally added method, so the request is rejected before reaching the new switch handler; the outgoing bridge repeats the same unsupported mapping. Special-case this method as a pass-through, or provide explicit request/response mappings until the SDK is upgraded.
Useful? React with 👍 / 👎.
Summary
0as Never.Review scope
This is the phase-one release integration artifact and supersedes merging #51 and #52 independently. It is intentionally a draft: do not merge before the planned human review and cross-repository release ordering are complete.
Validation
npm run format:checknpm run typechecknpm test— 24 tests, including approval restoration/invalidation and advisory-fee retry/reconciliation coveragenpm run buildThe transaction-intent invariant is also covered in nockbox/iris-rs#29: signing preserves the witnessless spends hash while legitimately changing the raw transaction ID.
Manual acceptance checklist