feat(carpincho-wallet): amulet faucet, per-origin gating, activity & utils tabs, vault backup, and 3-step onboarding#88
Conversation
Private key import/export, shared runtime config for the extension worker, content-script injection on all URLs, configurable password strength, and the Amulet DevNet faucet UI. Imported as a subtree from the darkpool line on top of the canton-barebones-splice wallet-service.
The darkpool default targeted the FiveNorth devnet validator. On the canton-barebones-splice line the wallet-service runs locally, so default the RPC endpoint to http://localhost:3010/rpc (still overridable via runtime config).
Add the amulet.tap JSON-RPC method that prepares the fixed 100 AMT DevNet tap command for the receiver party, so Carpincho can sign it locally. Wires the real SDK path (via getTokenSdk), the mock handler, and the supportedMethods lists.
The Amulet SDK resolves relative registry endpoints (e.g. /registry/transfer-instruction/v1/transfer-factory) against the configured registryUrl. Passing it as a raw string made the SDK fail to parse those URLs, breaking amulet.tap and cip56 transfers; wrap it in new URL() like the sibling call sites.
…t at the vault boundary Default the minimum zxcvbn score to 3 when VITE_MIN_PASSWORD_SCORE is unset or invalid (was 1, fail-open), while still honoring an explicit lower override for local dev. Enforce isPasswordAcceptable in setup()/changePassword() so the score gate no longer lives only in the disablable submit button.
…clear clipboard Gate ExportPrivateKeyView behind a fresh password confirmation (verifyPassword) so an unattended unlocked popup cannot leak the raw key in two clicks. Copy now goes through copySecret, which best-effort wipes the clipboard after 60s if it still holds the key.
…er-origin approval The content script injects on all origins, but the background returned account identity (party ids, public keys) and queued signing for any site with no approval. Add an origin permission model: connect from an unapproved origin is queued for an explicit popup approval, account queries answer from an empty snapshot until approved, and signing is refused for unapproved origins. Surface the requesting origin on every approval card, and broadcast wallet events only to connected dApp tabs.
This is a developer wallet; a low default is intentional so devs are not forced into complex passwords. Restore the default zxcvbn score of 1 when the env var is unset; the boundary enforcement in setup()/changePassword() still applies the configured score.
…der request path copySecret now delegates to copyText via an onSuccess hook instead of duplicating the write/toast/catch chain; collapse the two identical allow branches in the direct-provider gatekeeper into one guard; and read the wallet snapshot and connection state concurrently in handleProviderRequest instead of sequentially.
…at the source Move the injected-provider gate's per-method policy out of three hand-maintained lists in directProvider.ts into a single access-tier mapping next to the method definitions in provider/methods.ts. The mapping is exhaustive over known methods (satisfies Record) and unknown methods fail safe to RESTRICTED, so a newly added RPC method cannot silently reach an unapproved origin.
The private-key export re-auth gate duplicated the verify-password form (input, a11y wiring, incorrect-password handling) already in SecurityPanel. Extract a ConfirmPasswordForm component and use it in both; it takes an initialError so SecurityPanel can still surface a changePassword failure on the verify step.
…igin permission model Document the new amulet.tap faucet method in the wallet-service README/AGENTS, and update carpincho's architecture/README for the per-origin injected-provider gate (account access gated until an origin is approved via connect), the per-method access tiers in methods.ts, the boundary-enforced password gate, and the connected-origins set now scoping account access and event broadcasts.
Drop the now-unused COG_ICON, render the monogram synchronously when a dApp has no favicon, and cover status independence and the favicon fallback.
These message constants/types are re-declared locally in contentScript.ts and were never imported from messages.ts; the Theme alias was superseded by ThemeMode.
…ter focus ring The disconnect control now builds on PLAIN_ICON_BUTTON_CLASS (overriding to a danger hover) and the network pill regains focus-visible:shadow-focus, matching the rest of the app's keyboard focus treatment.
…ter redesign Drop the removed COG_ICON, add GLOBE_ICON, and list @radix-ui/react-avatar (dApp favicon with monogram fallback in ConnectionFooter).
…awaiting variants
… in a fixed-height list
…e with a status badge
…ind shared Badge and SectionLabel primitives
There was a problem hiding this comment.
Pull request overview
Brings a feature-complete Carpincho wallet onto the canton-barebones-splice base by adding an Amulet DevNet faucet (amulet.tap) in wallet-service, introducing per-origin injected-provider gating, redesigning the home surface (Assets / Activity / Utils), adding whole-vault backup, and reworking first-run onboarding into a 3-step flow (Vault → RPC → Account).
Changes:
- Add
amulet.tapJSON-RPC method in wallet-service and integrate faucet UX in the wallet. - Enforce per-origin injected-provider access tiers and gate
connectbehind explicit approval. - Add whole-vault export/import, new Utils tooling surface, and 3-step onboarding with automatic RPC reachability probing.
Reviewed changes
Copilot reviewed 140 out of 143 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| carpincho-wallet/test/views/OnboardingFlow.test.tsx | Update onboarding tests for 3-step flow |
| carpincho-wallet/test/views/HomeView.test.ts | Update approval payload layout assertions |
| carpincho-wallet/test/views/homeHooks.test.tsx | Add connect/origin pending-action tests |
| carpincho-wallet/test/views/CreateVault.test.tsx | Update vault stub for vault backup APIs |
| carpincho-wallet/test/views/CreateFirstAccount.test.tsx | New test for first-account step UI |
| carpincho-wallet/test/views/ConfigureRpcStep.test.tsx | New tests for RPC gating step |
| carpincho-wallet/test/vault/passwordStrength.test.ts | New tests for score parsing/defaults |
| carpincho-wallet/test/vault/passwordAcceptance.test.tsx | New acceptance test for score-based gating |
| carpincho-wallet/test/vault/keypair.test.ts | New tests for public-key derivation |
| carpincho-wallet/test/vault/exportVault.test.tsx | New tests for whole-vault export |
| carpincho-wallet/test/utils/json.test.ts | New tests for loose JSON parsing/formatting |
| carpincho-wallet/test/utils/download.test.ts | New tests for secure-context JSON download |
| carpincho-wallet/test/useWalletServiceTest.test.tsx | New tests for RPC probe hook |
| carpincho-wallet/test/providerAccessTier.test.ts | New tests for method access tiers |
| carpincho-wallet/test/extensionManifest.test.ts | Assert <all_urls> + gating rationale |
| carpincho-wallet/test/extensionDirectProvider.test.ts | Test per-origin connect/list/sign gating |
| carpincho-wallet/test/extensionDappConnection.test.tsx | Add host/icon propagation assertions |
| carpincho-wallet/test/extensionBridge.test.ts | Update manifest content-script match expectations |
| carpincho-wallet/test/config/runtimeConfig.test.ts | New tests for chrome storage mirroring |
| carpincho-wallet/test/components/UtilsPanel.test.tsx | New tests for Utils modal flow |
| carpincho-wallet/test/components/utils/UtilsList.test.tsx | New tests for faucet + util selection |
| carpincho-wallet/test/components/utils/JsonField.test.tsx | New tests for JSON field validation/format |
| carpincho-wallet/test/components/utils/ExerciseChoiceUtil.test.tsx | New tests for exercise util submission |
| carpincho-wallet/test/components/utils/CreateContractUtil.test.tsx | New tests for create util submission |
| carpincho-wallet/test/components/utils/ActiveContractsUtil.test.tsx | New tests for ACS util loading/filtering |
| carpincho-wallet/test/components/ui/DetailRow.test.tsx | New tests for copyable detail rows |
| carpincho-wallet/test/components/TransferDetailsSheet.test.tsx | New tests for transfer metadata sheet |
| carpincho-wallet/test/components/TransferCard.test.tsx | New tests for incoming/outgoing cards |
| carpincho-wallet/test/components/TokenRow.test.tsx | Update tests for balance-first rows |
| carpincho-wallet/test/components/TokenReceive.test.tsx | Wrap receive view in TooltipProvider |
| carpincho-wallet/test/components/TokenHoldingDetail.test.tsx | Update detail view + copy affordance tests |
| carpincho-wallet/test/components/TokenDetailSheet.test.tsx | Update vault stub for vault backup APIs |
| carpincho-wallet/test/components/SendConfirm.test.tsx | Update assertions for JsonView rendering |
| carpincho-wallet/test/components/JsonView.test.tsx | New tests for JsonView primitives/objects |
| carpincho-wallet/test/components/HomeTabs.test.tsx | Update tabs (Assets/Activity/Utils) + badge logic |
| carpincho-wallet/test/components/Header.test.tsx | Update vault stub for vault backup APIs |
| carpincho-wallet/test/components/DarUploadPanel.test.tsx | New tests for DAR upload panel |
| carpincho-wallet/test/components/CreateAccountForm.test.tsx | Update vault stub for vault backup APIs |
| carpincho-wallet/test/components/Copyable.test.tsx | New tests for generic copy control |
| carpincho-wallet/test/components/Collapsible.test.tsx | New tests for collapsible primitive |
| carpincho-wallet/test/components/AssetsPanel.test.tsx | Update assets tests + auto-accept setting |
| carpincho-wallet/test/components/ActivityList.test.tsx | Update activity tests for JsonView + copy rows |
| carpincho-wallet/test/components/AccountsDialog.test.tsx | Update vault stub for vault backup APIs |
| carpincho-wallet/test/components/AccountCard.test.tsx | Update vault stub for vault backup APIs |
| carpincho-wallet/test/cip56/amuletPreapproval.test.ts | Add test for tapAmulet flow |
| carpincho-wallet/test/api/walletService.test.ts | New tests for admin upload + MV3 storage |
| carpincho-wallet/src/wc/client.ts | Carry dApp icon into connected session model |
| carpincho-wallet/src/vite-env.d.ts | Add VITE_MIN_PASSWORD_SCORE typing |
| carpincho-wallet/src/views/onboarding/OnboardingFlow.tsx | Implement 3-step onboarding flow |
| carpincho-wallet/src/views/onboarding/CreateFirstAccount.tsx | Split account step from connection concerns |
| carpincho-wallet/src/views/onboarding/ConfigureRpcStep.tsx | New RPC reachability gating step |
| carpincho-wallet/src/views/HomeView.tsx | Add pending-connect state and wire into UI |
| carpincho-wallet/src/views/home/useProviderRequestHandler.ts | Bridge connect/sign/execute into pending states |
| carpincho-wallet/src/views/home/usePendingActions.ts | Add approve/reject connect handling |
| carpincho-wallet/src/views/home/useExtensionRequests.ts | Pass origin through to request handler |
| carpincho-wallet/src/views/home/types.ts | Add origin to pending action types |
| carpincho-wallet/src/views/home/PendingActionsSection.tsx | Show requesting origin on approval cards |
| carpincho-wallet/src/vault/VaultContext.tsx | Add export/import vault + enforce strength boundary |
| carpincho-wallet/src/vault/types.ts | Add vault envelope + import result types |
| carpincho-wallet/src/vault/passwordStrength.ts | Add env-driven min score + async readiness |
| carpincho-wallet/src/vault/keypair.ts | Add public-key derivation + stricter hex parsing |
| carpincho-wallet/src/utils/network.ts | Add networkId display helper |
| carpincho-wallet/src/utils/download.ts | Add secure-context JSON download utility |
| carpincho-wallet/src/utils/clipboard.ts | Add secret clipboard clearing + onSuccess callback |
| carpincho-wallet/src/theme/ThemeContext.ts | Remove unused Theme type alias |
| carpincho-wallet/src/provider/methods.ts | Add per-method access tier classification |
| carpincho-wallet/src/hooks/useWalletServiceTest.ts | New hook for probing wallet-service RPC |
| carpincho-wallet/src/extension/messages.ts | Remove unused legacy event/message types |
| carpincho-wallet/src/extension/directProvider.ts | Enforce access tiers + per-origin gating behavior |
| carpincho-wallet/src/extension/dappConnection.ts | Add host/icon support for footer connection info |
| carpincho-wallet/src/extension/background.ts | Gate events to connected origins + origin checks |
| carpincho-wallet/src/config/runtimeConfig.ts | Move to v2 + mirror into chrome.storage.local |
| carpincho-wallet/src/components/VaultPanel.tsx | New vault settings panel (password/auto-lock) |
| carpincho-wallet/src/components/UtilsPanel.tsx | New Utils tab with modal tool surfaces |
| carpincho-wallet/src/components/utils/UtilsList.tsx | New faucet row + ledger tools list |
| carpincho-wallet/src/components/utils/UpdateIdResult.tsx | New update-id success banner with copy |
| carpincho-wallet/src/components/utils/JsonField.tsx | New validated JSON textarea for ledger tools |
| carpincho-wallet/src/components/utils/ExerciseChoiceUtil.tsx | New generic exercise util |
| carpincho-wallet/src/components/utils/CreateContractUtil.tsx | New generic create util |
| carpincho-wallet/src/components/ui/Tooltip.tsx | Tooltip width handling + optional side prop |
| carpincho-wallet/src/components/ui/SectionLabel.tsx | New shared section label primitive |
| carpincho-wallet/src/components/ui/PendingActionCard.tsx | Use JsonView for payload rendering |
| carpincho-wallet/src/components/ui/JsonView.tsx | New themed read-only JSON tree |
| carpincho-wallet/src/components/ui/FileDropInput.tsx | New shared file chooser “dropzone” UI |
| carpincho-wallet/src/components/ui/DetailRow.tsx | New copyable detail row component |
| carpincho-wallet/src/components/ui/CopyableLabel.tsx | New label + copy affordance component |
| carpincho-wallet/src/components/ui/Copyable.tsx | New generic copy icon button |
| carpincho-wallet/src/components/ui/Collapsible.tsx | New collapsible wrapper components |
| carpincho-wallet/src/components/ui/Badge.tsx | New compact status pill component |
| carpincho-wallet/src/components/TransferDetailsSheet.tsx | New transfer metadata sheet |
| carpincho-wallet/src/components/TransferCard.tsx | New transfer card variants + copyable parties |
| carpincho-wallet/src/components/TokenRow.tsx | Redesign token row to be balance-first |
| carpincho-wallet/src/components/TokenReceive.tsx | Switch party-id display to DetailRow |
| carpincho-wallet/src/components/TokenHoldingDetail.tsx | Use DetailRow + add copy affordance |
| carpincho-wallet/src/components/TokenDetailSheet.tsx | Update holdings section layout + badges |
| carpincho-wallet/src/components/SendConfirm.tsx | Replace raw JSON with JsonView |
| carpincho-wallet/src/components/SecurityPanel.tsx | Remove legacy security panel |
| carpincho-wallet/src/components/PasswordStrengthIndicator.tsx | Remove embedded recommendations tooltip |
| carpincho-wallet/src/components/NewPasswordFields.tsx | Move recommendations tooltip to label area |
| carpincho-wallet/src/components/menu/screens.ts | Restructure menu around Vault section |
| carpincho-wallet/src/components/menu/MenuSheet.tsx | Wire vault backup + vault panel screens |
| carpincho-wallet/src/components/HomeTabs.tsx | Replace Transfers with Activity + add Utils tab |
| carpincho-wallet/src/components/DarUploadPanel.tsx | New dev-only DAR upload utility |
| carpincho-wallet/src/components/CopyPartyIdButton.tsx | Delegate to Copyable component |
| carpincho-wallet/src/components/ConfirmPasswordForm.tsx | New shared verify-password gate form |
| carpincho-wallet/src/components/AutoAcceptSetting.tsx | Move auto-accept toggle to Assets settings row |
| carpincho-wallet/src/components/AssetsPanel.tsx | Add auto-accept setting + section label |
| carpincho-wallet/src/components/AccountsDialog.tsx | Tweak list spacing for new row styling |
| carpincho-wallet/src/components/AccountListRow.tsx | Restyle row and focus/primary states |
| carpincho-wallet/src/cip56/amuletPreapproval.ts | Add tapAmulet faucet helper + API type |
| carpincho-wallet/src/App.tsx | Update onboarding routing comment for new steps |
| carpincho-wallet/src/api/walletService.ts | Add MV3 runtime config loading + DAR upload API |
| carpincho-wallet/README.md | Document per-origin approval requirement |
| carpincho-wallet/public/manifest.json | Widen matches/host_permissions to <all_urls> |
| carpincho-wallet/package.json | Add Avatar/Collapsible/JsonView deps |
| carpincho-wallet/.env.example | Document VITE_MIN_PASSWORD_SCORE |
| canton-barebones/wallet-service/test/rpc.test.ts | Add tests for URL registry + amulet.tap |
| canton-barebones/wallet-service/src/rpc.ts | Implement amulet.tap + URL registry handling |
| canton-barebones/wallet-service/src/mock.ts | Add amulet.tap mock handler |
| canton-barebones/wallet-service/README.md | Document amulet.tap method |
| canton-barebones/wallet-service/AGENTS.md | Update scope to include faucet tap |
| .gitignore | Ignore .env.fivenorth |
Comments suppressed due to low confidence (1)
carpincho-wallet/src/vault/passwordStrength.ts:67
isPasswordAcceptableno longer enforces the (still-present) 8-character minimum thatVaultContext.setup()/changePassword()require. This can let the UI treat short passwords as valid and enable submission, only to have the vault boundary reject them. Keeping the length check here keeps UI gating consistent with the vault boundary.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <label | ||
| htmlFor={id} | ||
| className="cursor-pointer rounded-md border border-dashed border-border bg-surface px-4 py-6 text-center hover:border-primary/60" | ||
| > |
There was a problem hiding this comment.
Fixed in 990b5a6. Changed the prompt copy at both call sites to click-only wording ("Click to choose a .dar file." / "Click to choose a .json backup."). Drop handlers were not added: this UI runs in an MV3 extension action popup, where dragging a file from the OS file manager defocuses and closes the popup before any drop can land.
…icon Drop the full-width Refresh button: the template field now narrows the already-fetched ACS client-side as you type, and a small animated refresh icon above the list re-fetches the snapshot. Relabel the field to "Template id" with an example placeholder. In the expanded card, render the contract id as a DetailRow so it matches the other fields, and keep the chevron pinned to the top-right.
…ct id Broaden the active-contracts filter so a query matches either the template id (exact/suffix) or a case-insensitive substring of the contract id. Relabel the field to "Filter" with a "Template or contract id" placeholder.
…earch field Rotate the refresh icon a full turn on each click (and keep spinning while a fetch is in flight) so the action reads even when the local re-filter is instant. Drop the "Filter" label in favour of a leading magnifier and a clear button, matching the accounts search field; the input keeps an aria-label.
Add a dedicated spin-fast keyframe (500ms/turn) and use it for the refresh icon so a click reads as a quick, deliberate rotation instead of a languid one-second turn.
…stActiveContracts
…y, Export/Import button labels
…ount Extract an in-memory insertAccount helper shared by addAccount and the import merge so a multi-account restore runs a single PBKDF2 derive + AES-GCM re-encryption and one accountsChanged broadcast instead of one per imported account.
…ackup markers Replace the hand-rolled null/object narrowing in backup.ts with the shared isRecord guard, type BACKUP_KIND/BACKUP_VERSION by the CarpinchoBackup interface so the on-disk format markers have one source of truth, and drop the export-only IIFE in the export panel for a named handler.
…in architecture VaultContext now exposes exportEncryptedVault/importEncryptedVault over an encrypted CarpinchoBackup container (plaintext envelope build/merge is internal), add the backup.ts module, and note the create-first-account restore-from-backup tab.
Add data-testid hooks to every interactive control, list row, modal/sheet container, and copy affordance across onboarding, accounts, assets/send/receive, activity & transfers, utils/ledger tools, DAR upload, connection settings & footer, and the drawer menu, so end-to-end tooling never relies on text, role, or DOM-position selectors. Extend the prop-fixed shared primitives that hide their DOM node (Sheet, Select, TabTrigger, MenuRow, FileDropInput, Collapsible, DetailRow, AmountField, ConfirmPasswordForm) with a forwarded testId prop, matching the existing Copyable/DangerConfirm convention. Document data-testid coverage as a hard requirement for new UI in AGENTS.md.
…ompts The popup action surface only supports click-to-choose; OS file drag-and-drop closes the popup before any drop lands.
Summary
No related issue. Brings the most feature-complete Carpincho wallet (from the darkpool line) onto the
canton-barebones-splicebase, then carries it through a full feature, UX, and security pass so splice gets the best wallet without the darkpool-specific dApp work. Adds the Amulet DevNet faucet to the wallet-service, hardens the injected-provider and vault security models, redesigns the home surface around Assets / Activity / Utils, adds whole-vault backup, and reworks first-run onboarding into a three-step flow.canton-barebones-splicewill later merge intomain.Scope has grown well past the original import: 138 files, +7134 / -1568.
Changes
wallet-service
amulet.tapJSON-RPC method (prepares the fixed 100 AMT DevNet faucet command for the receiver party; Carpincho signs locally), with the real SDK path viagetTokenSdk, a mock handler,supportedMethodswiring, and unit coverage.registryUrlas aURLso the SDK resolves relative registry endpoints (e.g./registry/transfer-instruction/v1/transfer-factory); a raw string brokeamulet.tapand cip56 transfers.Injected-provider security (per-origin gating)
connectis queued for a popup approval, signing is refused, and wallet events broadcast only to connected dApp tabs.provider/methods.ts(exhaustive over known methods viasatisfies Record; unknown methods fail safe to RESTRICTED), consumed by the background gatekeeper instead of three hand-maintained lists.http://localhost:3010/rpcfor the local stack (darkpool defaulted to the FiveNorth devnet validator).Vault & password security
exportVault()/importVault()onVaultContext(envelope{ v: 1, accounts: [...] }), a secure-contextdownloadJsonutility, and a backup export/import UI. Import validates each entry's Ed25519 derivation and partyId shape, skips duplicates, and hardens clipboard hygiene. This replaces per-account private-key import/export (SecurityPanel/PrivateKeyPanelremoved).FileDropInputbetween DAR and vault import.VITE_MIN_PASSWORD_SCOREis unset/invalid and enforce the score at the vault boundary (setup()/changePassword()), not only in the UI. Default stays 1 for the dev wallet.ConfirmPasswordFormused by the verify-password flows.Home surface (Assets / Activity / Utils)
TransferCardinto needs-action and awaiting variants and add aTransferDetailsSheetfor transfer metadata.AutoAcceptSettingon the Assets tab; auto-accept now applies to all incoming transfers, not just Amulet. Asset rows show token balance instead of a UTXO count.LedgerToolsPanelwith a master/detail Utils tab (UtilsPanel/UtilsList) opened in a modal: Amulet faucet (Tap Amulet moved here from Assets), Create Contract, Exercise Choice, Active Contracts, and a DAR dropzone, backed by a validatedJsonFieldfor ledger command payloads andledger/contracts.ts.Copyable/CopyableLabelprimitives, acopyLabelonDetailRow, copyable detail-sheet and transaction rows, and copyable counterparty party ids on transfer cards. Replace raw<pre>JSON blocks with a themedJsonViewtree (per-node copy, collapsible), falling back to plain text for non-object payloads.Collapsible,JsonView,Copyable,CopyableLabel,DetailRow,FileDropInput.Onboarding
useWalletServiceTesthook), then create the first account. Previously two steps.Docs & chore
amulet.tap, and carpincho README/architecture/AGENTS to the per-origin gate, access tiers, the Activity/Utils redesign, vault backup, the vault-centric drawer, and the new onboarding flow..env.fivenorthto.gitignore.Acceptance criteria
amulet.tapprepares a valid DevNet tap command end-to-end against LocalNet and Carpincho signs it locallyconnectrequires explicit user approvalTest plan
Automated tests
npm --prefix canton-barebones/wallet-service test— covers the newamulet.tapmethod (test/rpc.test.ts).npm --prefix carpincho-wallet test. Notable coverage:test/extensionDirectProvider.test.ts,test/providerAccessTier.test.ts,test/extensionDappConnection.test.tsx.test/vault/exportVault.test.tsx,test/vault/importVault.test.tsx,test/components/VaultBackupPanel.test.tsx,test/components/VaultPanel.test.tsx,test/utils/download.test.ts.test/vault/passwordStrength.test.ts,test/vault/passwordAcceptance.test.tsx,test/vault/verifyPassword.test.tsx.test/components/ActivityPanel.test.tsx,test/components/TransferCard.test.tsx,test/components/TransferDetailsSheet.test.tsx,test/components/AutoAcceptSetting.test.tsx.test/components/UtilsPanel.test.tsx,test/components/utils/*.test.tsx,test/ledger/contracts.test.ts.test/components/Copyable.test.tsx,test/components/JsonView.test.tsx,test/components/ui/DetailRow.test.tsx,test/utils/json.test.ts.test/views/OnboardingFlow.test.tsx,test/views/ConfigureRpcStep.test.tsx,test/views/CreateVault.test.tsx,test/views/CreateFirstAccount.test.tsx,test/useWalletServiceTest.test.tsx,test/views/homeHooks.test.tsx.Manual verification
./scripts/dev-stack.sh up), load the unpacked extension (npm run carpincho:build:extension), walk first-run onboarding (vault → Configure RPC → first account), connect a dApp and approve the per-origin prompt, exercise the Amulet faucet tap from the Utils tab (requires an active DevNet mining round), and round-trip a whole-vault backup export/import.Breaking changes
connectnow see an approval prompt; account/sign requests from unapproved origins are refused.SecurityPanel/PrivateKeyPanelgone). The Transfers tab is replaced by the Activity tab, and the default wallet-service RPC endpoint is nowhttp://localhost:3010/rpc.Checklist
Screenshots
None.