diff --git a/README.md b/README.md index 626c0de37..df1176336 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,14 @@ BSV TypeScript monorepo for the SDK, wallet tooling, overlays, messaging, middle Most applications should start with `@bsv/simple` or `@bsv/sdk`. Wallet builders usually start with `@bsv/wallet-toolbox`. Service operators usually start with the overlay, messaging, middleware, or infra packages. +## Wallet recovery resources + +Wallet builders need both recoverable root key material and wallet records, +including derivation metadata. Start with [Wallet backup and recovery](docs/guides/wallet-backup-recovery.md), +then use the [BRC-38/39 integration guide](docs/guides/wallet-data-portability.md), +[recovery drill](docs/guides/wallet-recovery-drill.md) and +[AI-agent implementation brief](docs/guides/wallet-recovery-agent-brief.md). + ## Contributing The entire stack follows one [contribution policy](./CONTRIBUTING.md), one diff --git a/docs/architecture/brc-100.md b/docs/architecture/brc-100.md index 4cbc1073f..ad0a5a3a3 100644 --- a/docs/architecture/brc-100.md +++ b/docs/architecture/brc-100.md @@ -3,8 +3,8 @@ id: architecture-brc100 title: BRC-100 Wallet Interface kind: meta version: 'n/a' -last_updated: '2026-04-30' -last_verified: '2026-08-26' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: ['architecture', 'BRC-100', 'wallet'] @@ -24,6 +24,18 @@ Without BRC-100, every app would need custom wallet integrations and every walle - Wallets can implement one interface and expose it over localhost, postMessage, JSON APIs, native bridges, or in-process objects. - Other language implementations can target the same method shapes and test against the same conformance vectors. +## Recovery boundary + +BRC-100 standardizes the application/wallet interface; implementing it does not +supply a complete disaster-recovery product. The wallet must preserve both +recoverable keys and its records/derivation metadata. A chain rescan, an OTP or +a key-manager snapshot is not a replacement for wallet-data recovery. + +Use [Wallet backup and recovery](../guides/wallet-backup-recovery.md) for +responsibilities and the [BRC-38/39 guide](../guides/wallet-data-portability.md) +for per-user data portability. Applications should link to their wallet's +recovery controls without collecting wallet secrets. + ## Desktop Flow On desktop, a web app uses `@bsv/simple/browser` or `WalletClient` from `@bsv/sdk`. diff --git a/docs/get-started/choose-your-stack.md b/docs/get-started/choose-your-stack.md index 746119ff9..c90c33637 100644 --- a/docs/get-started/choose-your-stack.md +++ b/docs/get-started/choose-your-stack.md @@ -3,8 +3,8 @@ id: choose-your-stack title: Choose Your Stack kind: meta version: 'n/a' -last_updated: '2026-04-30' -last_verified: '2026-08-26' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: ['decision-guide'] @@ -14,6 +14,11 @@ tags: ['decision-guide'] Start from who controls the keys and how close you need to be to the protocol. +If you run a server/agent wallet or build a wallet product, plan for both +recoverable keys and wallet records from the start. See +[Wallet backup and recovery](../guides/wallet-backup-recovery.md) and the +[agent implementation brief](../guides/wallet-recovery-agent-brief.md). + ```text Browser app using a user's wallet? -> @bsv/simple/browser diff --git a/docs/guides/index.md b/docs/guides/index.md index acaf6e6ad..69f169ecf 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -3,8 +3,8 @@ id: guides-overview title: 'Guides' kind: meta version: '1.0.0' -last_updated: '2026-08-28' -last_verified: '2026-08-28' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: [guides, tutorials, how-to] @@ -16,6 +16,17 @@ Comprehensive step-by-step walkthroughs for building production applications with the ts-stack. Guides use current public APIs, runnable examples, and explicit operational assumptions. +## Wallet recovery learning path + +1. [Wallet backup and recovery](wallet-backup-recovery.md): inventory keys, data, + product state and independent recovery access. +2. [BRC-38/39 wallet data portability](wallet-data-portability.md): implement + encrypted exports, preview and explicit restore/merge using current APIs. +3. [Recovery drill and acceptance checklist](wallet-recovery-drill.md): prove + clean-device/provider-loss recovery and document limits. +4. [AI-agent implementation brief](wallet-recovery-agent-brief.md): give a coding + agent the source map, constraints and acceptance criteria. + ## Available Guides ### 1. [Build a Wallet-Aware App](./wallet-aware-app.md) diff --git a/docs/guides/wallet-backup-recovery.md b/docs/guides/wallet-backup-recovery.md new file mode 100644 index 000000000..0d89d0a2d --- /dev/null +++ b/docs/guides/wallet-backup-recovery.md @@ -0,0 +1,164 @@ +--- +id: wallet-backup-recovery +title: 'Wallet Backup and Recovery' +kind: guide +version: '1.0.0' +last_updated: '2026-09-24' +last_verified: '2026-09-24' +review_cadence_days: 30 +status: stable +tags: [wallet, backup, recovery, brc100, brc38, brc39] +--- + +# Wallet backup and recovery + +**A BRC-100 wallet recovery plan needs both recoverable root key material and +the wallet's records, including derivation metadata.** A seed or private key +alone is not a complete Wallet Toolbox backup. A database or BRC-39 export alone +does not restore the user's signing authority. Build and test both recovery +paths before asking users to depend on the wallet. + +This guide is for wallet builders and storage operators. An application using +`WalletClient` should direct users to their wallet's recovery controls; it +should not request their private keys or implement a wallet backup by listing +only the application's visible transactions. + +## Follow the complete recovery path + +| Task | Resource | +| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| Decide what must survive a lost device or provider | This guide's recovery inventory and responsibility table | +| Implement encrypted file export and import | [BRC-38/39 wallet data portability](wallet-data-portability.md) | +| Prove recovery and handle failures | [Recovery drill and acceptance checklist](wallet-recovery-drill.md) | +| Give an AI coding agent a bounded implementation task | [Wallet recovery agent brief](wallet-recovery-agent-brief.md) | +| Understand storage and wallet boundaries | [Wallet Toolbox](../packages/wallet/wallet-toolbox.md), [BRC-100 architecture](../architecture/brc-100.md) | + +## What must survive + +BSV wallet outputs can depend on protocol identifiers, counterparties, derivation +prefixes/suffixes and custom spending instructions. Wallet-local records also +associate transactions with baskets, labels, certificates and pending work. +These are not all recoverable by scanning the chain with a root key. On-chain +transaction availability is not a substitute for retaining the metadata needed +to identify and spend the user's outputs. + +Keep an inventory for **each profile and network**, with these separate parts: + +| Recovery component | Examples | What it does not replace | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| Key recovery | Root key, or sufficient independently recoverable shares/factors for the product's actual key manager; any required privileged keys | Wallet transaction and derivation records | +| Wallet data | Transactions, outputs and scripts, derivation metadata, baskets, tags, labels, certificates, proof/broadcast state and sync relationships | Root key, application login or key-manager recovery factors | +| Product data and configuration | Profile mapping, contacts/trust decisions, application settings, external content, supported spending modules and independently verified service identities | Neither key nor wallet-data recovery | +| Backup access | BRC-39 passphrase, backup encryption keys, vault access, provider-independent instructions | The protected data itself | + +Inventory external signing devices and custom scripts separately: preserving a +`customInstructions` field does not install the implementation or recover an +external co-signer. A wallet-manager `saveSnapshot()` is another distinct +artifact. Some manager snapshots contain root/privileged key material; treat +them as wallet-equivalent secrets, but do not assume they include the storage +database. Read the chosen manager's contract. + +Avoid circular recovery dependencies. A backup that requires a password +manager, mailbox or cloud account accessible only from the lost wallet/device +does not provide an independent recovery path. A device-bound keystore protects +secrets at rest; verify how those secrets can be recovered after that device +is gone. + +## Choose complementary protections + +| Mechanism | Responsible party | Useful for | Required qualification | +| ----------------------------------------------------- | -------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| Key vault or threshold recovery | User or organizational custodian | Recovering signing authority | Prove recovery without the lost device and with the stated provider/factor unavailable | +| Storage-provider replication | Storage operator | Availability and maintaining another data copy | Monitor lag and failures; replication can propagate mistakes and deletion | +| Versioned database backups and point-in-time recovery | Storage operator | Operator disaster recovery and rollback | Use a database-supported consistent backup, preserve schema/migrations and required external stores, and test restoration | +| Per-user BRC-39 file | User or organizational custodian | User-controlled data recovery and vendor/provider exit | Pair with separate key recovery; verify freshness, completeness, passphrase access and target compatibility | + +These custody and operational roles map to [Assign responsibilities explicitly](#assign-responsibilities-explicitly) +below. The wallet product must still provide and test the key-recovery and +export/import flows that users rely on. + +Keep a retained backup outside the failure domain of the live store. For +example, a user or organizational custodian may keep key-recovery material in +a managed vault with an independent offline copy, while the storage operator +maintains versioned database backups. This does not give the storage operator +custody of the user's root key. Test the vault permissions, decryption keys, +database restore and provider-loss scenario together. A daily backup can leave +up to a day of new wallet records unprotected; choose and disclose a recovery +point objective (maximum acceptable data loss) and recovery time objective +(time to usable recovery) appropriate to the product. + +`WalletStorageManager.addWalletStorageProvider(...)` and `updateBackups()` +provide storage replication building blocks. They do not create an off-site +retention policy, recover keys, or certify a recovery point. The +[SQLite backup example](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox-examples/src/backup.ts) +creates a sensitive data copy; see its +[safety instructions](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox-examples/README.md#security-and-operational-safety). +Do not copy a running SQLite database as an ordinary file and assume its WAL or +journal was captured consistently. Use the database's supported backup process +or a verified closed-database copy. + +## Assign responsibilities explicitly + +| Owner | Must provide and verify | +| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Wallet product | Key recovery, profile/network selection, encrypted data export/import, backup reminders/status, product-data coverage, independent recovery instructions and a tested restore flow | +| Storage operator | Consistent retained data backups, encryption and access control, retention and restore objectives, monitoring, schema compatibility and a rehearsed provider recovery plan | +| User or organizational custodian | Custody of key-recovery material, BRC-39 files and their passphrases, accessible copies, and periodic checks using the product's instructions | +| Application developer | Durable application-specific data where applicable; clear links to the wallet's recovery controls without collecting wallet secrets | + +For hosted storage, document whether the user can recover data when the provider +is permanently unavailable. A provider's successful backup job is not proof +that the user can access or restore that backup. For browser/mobile wallets, +test browser storage eviction, app removal and device replacement; local +IndexedDB or app storage can disappear with the device or profile. + +The [WAB Shamir guide](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox/docs/wab-shamir.md) +describes **key** recovery. Its share threshold, server independence and +authentication requirements must be tested separately from data restoration. +An OTP, phone-number change or recovered share does not retrieve lost wallet +records. Storage operators should also use the +[Wallet Infra operations guide](../infrastructure/wallet-infra.md). + +## Make recovery understandable in the product + +Present separate statuses for key recovery and wallet-data backup. Show the +selected profile/network, last completed export or backup time, last successful +restore test, and any records created since the recovery point. Do not mark a +wallet “fully backed up” merely because a seed was displayed, a download was +started, or a remote replica is reachable. + +Suggested wording to adapt to the product's verified behavior: + +> **Keep both parts.** Your recovery key restores control of this wallet. Your +> wallet-data backup restores the records needed to use it. Keep an accessible +> copy of each, protected separately. + +> **Export wallet data.** This password-protected file contains the selected +> wallet's transaction history and metadata. It does not contain your root key +> or replace your key-recovery instructions. Keep its passphrase recoverable. + +> **Recovery still needs verification.** Import has completed. Before using this +> wallet, we need to check its identity, network, records and current spend state. + +Explain what is excluded, how often to export, where recovery instructions +remain available during an outage, and how to get help without sending private +keys, snapshots, passphrases or exports to support. Make error messages usable +with keyboard navigation and assistive technology; expose stage/progress and +retry instructions without placing secrets or wallet records in telemetry. + +## Treat recovery as an ongoing capability + +Run the [recovery drill](wallet-recovery-drill.md) before release and after +changes to key management, schema, storage backend, archive implementation or +supported device runtime. Test against the exact packages being distributed; +source `main`, an open PR and a published package are different states. Consult +the [package migration ledger](../reference/package-api-migrations.md), +[support policy](../about/versioning.md#support-policy) and +[published security advisories](https://github.com/bsv-blockchain/ts-stack/security/advisories). +Historical security minimums are not recommendations to pin an older version. + +Keep this recovery set aligned with implementation and test evidence. Use +synthetic fixtures for public bug reports and compatibility demos. A short +cross-wallet import/export demonstration is useful interoperability evidence; +it does not establish recovery after total device/provider loss or preservation +of every product's custom state. diff --git a/docs/guides/wallet-data-portability.md b/docs/guides/wallet-data-portability.md new file mode 100644 index 000000000..a99b57dc3 --- /dev/null +++ b/docs/guides/wallet-data-portability.md @@ -0,0 +1,247 @@ +--- +id: wallet-data-portability +title: 'BRC-38/39 Wallet Data Portability' +kind: guide +version: '1.0.0' +last_updated: '2026-09-24' +last_verified: '2026-09-24' +review_cadence_days: 30 +status: stable +tags: [wallet, backup, interoperability, brc38, brc39] +--- + +# BRC-38/39 wallet data portability + +Use this guide with [Wallet backup and recovery](wallet-backup-recovery.md). +BRC-38 describes a single user's portable wallet records. BRC-39 encrypts that +payload in a password-protected file. Neither supplies root-key recovery. +These are wallet implementation/storage APIs, not new methods on the BRC-100 +`WalletClient` interface. + +## Standards, implementation and evidence + +| Authority | Where to inspect | +| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| Plaintext record format | [BRC-38](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0038.md) | +| Encrypted file format | [BRC-39](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0039.md) | +| Incremental provider synchronization | [BRC-40](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0040.md) | +| Current helper signatures, validation and import semantics | [Portable storage implementation](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox/src/storage/portable/index.ts) | +| Executable SQLite export/restore/merge and rejection examples | [Portable storage tests](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox/test/storage/portable.test.ts) | +| Public versions and migration decisions | [Package migration ledger](../reference/package-api-migrations.md) | + +Verified against TS Stack main `b2f1989306b6f64677deff89f39596491e448d97` +on 2026-09-24. Recheck the implementation and installed declarations when +upgrading. Pending sync work, including +[#569](https://github.com/bsv-blockchain/ts-stack/pull/569), is not an available +API contract for this guide. + +## Coverage and limits + +The implementation exports one `user`, its `sourceStorage` metadata and 13 +table arrays: transactions, outputs, output baskets, output tags and maps, +transaction labels and maps, certificates and fields, commissions, linked +proven transactions and proof requests, and sync states. It retains row +relationships, timestamps, tombstones and binary data. This is different from +the 12 entity kinds used in the storage sync protocol; do not use a sync-store +count as the archive schema. + +The export does not contain root keys, unrelated manager snapshots, other +profiles, storage-global monitor events, or product data held outside these +tables. Inventory contacts, permissions, external files and custom signing +dependencies in your product before describing its backup coverage. + +The current helpers read multiple tables and materialize the complete document +and encrypted file in memory. They do not take a database-wide snapshot, +provide streaming archive I/O, expose an archive progress/cancellation API, or +promise a coherent view while other writers change the source. Use a stable +local replica or a database-consistent restored copy. Quiesce its writers and +monitor work while exporting. A lock on one `WalletStorageManager` does not +stop other processes or devices from writing. + +The functions require a concrete `StorageProvider`, such as `StorageKnex` or +`StorageIdb`, not a remote `StorageClient`/`StorageMobile` or an arbitrary +`WalletStorageProvider`. For a remote wallet, first synchronize the selected +identity into a compatible local provider through supported storage APIs, +verify that copy, then export it. Do not cast a remote client to +`StorageProvider` or expose unrestricted database methods to make an example +compile. For mobile, choose and qualify a compatible local provider or a +separate trusted export path; a mobile package export does not by itself add +local persistent storage. + +`WalletStorageManager.syncFromReader(identityKey, reader)` and +`updateBackups()` are available building blocks. Check their completion/error +results and independently verify coverage before declaring the local copy +complete. With a live changing source, a successful transfer alone is not a +point-in-time consistency guarantee. See the +[storage reference](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox/docs/storage.md). + +A local synchronized copy has its own storage identity and sync bookkeeping. +Compare wallet data semantically and record that provenance; do not describe +its export as a byte-for-byte copy of the original provider's database. + +## Integration references + +These public changes provide host-integration examples to inspect alongside +this guide. Status checked on 2026-09-24; an open or merged PR is not evidence +that a store-distributed application version has shipped or passed your drill. + +- [BSV Desktop #90](https://github.com/bsv-blockchain/bsv-desktop/pull/90): open + desktop wallet portability integration. +- [BSV Browser #152](https://github.com/bsv-blockchain/bsv-browser/pull/152): open + native mobile/browser integration. +- [Peacock Wallet #30](https://github.com/p2ppsr/peacock-wallet/pull/30): merged + wallet portability and recovery integration example. + +Use synthetic data and record both implementations' exact versions for +cross-wallet tests. These examples do not establish universal compatibility. + +## API map + +The Node package exports the following helpers at `@bsv/wallet-toolbox`. +Browser and mobile roots export the portable helpers through +`@bsv/wallet-toolbox-client` and `@bsv/wallet-toolbox-mobile` respectively; +use the package appropriate to your runtime and qualify its provider/KDF path. + +| Helper | Result or purpose | +| ------------------------------------------------- | --------------------------------------------------------------- | +| `exportBRC38(storage, identityKey)` | Validated `BRC38WalletData` object | +| `exportBRC38Json(storage, identityKey)` | Canonical plaintext JSON string; highly sensitive | +| `parseBRC38Json(json)` | Parses and validates plaintext records | +| `encryptBRC39(documentOrJson, password)` | Encrypts an existing BRC-38 dataset into `number[]` bytes | +| `exportBRC39(storage, identityKey, password)` | Exports and encrypts in one operation | +| `decryptBRC39(bytes, password)` | Authenticates, decrypts and validates before returning records | +| `importBRC38(storage, documentOrJson, { mode })` | Writes validated records using explicit restore/merge semantics | +| `importBRC39(storage, bytes, password, { mode })` | Decrypts and imports; no selected-profile confirmation UI | + +Use the library's cryptographic defaults. BRC-39 files conventionally use +`wallet.brc39` and media type `application/vnd.brc39.wallet`. Preserve the bytes; +do not stringify the numeric array and label it a BRC-39 file. Do not trim or +case-fold the passphrase. The helper performs the required NFC normalization. +Its default Argon2id memory cost alone is 128 MiB, in addition to the archive +and runtime allocations. Test realistic files on the lowest supported device. + +## Export from a prepared local provider + +This TypeScript function uses real public APIs. The caller must supply a +quiesced, verified local data copy for the selected authenticated profile. +File pickers, secret entry, disk permissions and download completion are host +application responsibilities; the function does not persist a file. + +```ts +import { exportBRC39, type StorageProvider } from '@bsv/wallet-toolbox' + +export async function makeWalletDataFile( + source: StorageProvider, + selectedIdentityKey: string, + expectedChain: string, + passphrase: string +): Promise { + const settings = await source.makeAvailable() + if (settings.chain !== expectedChain) throw new Error('Wrong source network') + const bytes = await exportBRC39(source, selectedIdentityKey, passphrase) + return Uint8Array.from(bytes) +} +``` + +Bind identity/network to the selected profile before starting. Keep that +selection stable through completion or abort the host operation when it +changes. Deliver the encrypted bytes through the platform's file API, retain +older known-good copies, and record completion only after the destination save +succeeds. Store a file digest and timestamp as private verification metadata; +neither proves freshness or completeness by itself. Reopen the saved file and +verify it in an isolated recovery drill. + +## Preview and import into an isolated target + +The following functions illustrate API wiring after the host's resource checks; +they are not a complete untrusted-file admission layer. Before decryption, the +host must bound encoded KDF work/memory parameters as well as file bytes using +a reviewed header parser and a device-qualified policy. A small file can request +expensive Argon2id work. The current helper checks parameter validity but does +not accept a caller-supplied resource ceiling or cancellation signal. Do not +weaken parameters or edit the file to fit a device: refuse it with a supported +recovery path on a suitably provisioned runtime. + +Restore into newly provisioned storage with the correct schema and network. +For `mode: 'restore'`, every data table must be empty, including `users` and +`monitor_events`; only settings may exist. A convenience wallet setup can +create a user before import and therefore make the target ineligible. Never +empty a user's existing store to satisfy this precondition. + +The caller must already have recovered the selected profile's key and derived +its identity independently. Decrypt first to inspect the archive, compare the +identity/network, obtain the user's confirmation of the target and mode, then +invoke import. Do not trust an archive's identity as the selected profile. + +```ts +import { + decryptBRC39, + importBRC38, + type BRC38WalletData, + type StorageProvider +} from '@bsv/wallet-toolbox' + +export async function previewWalletDataFile( + bytes: Uint8Array, + passphrase: string, + recoveredIdentityKey: string, + expectedChain: string +): Promise { + const document = await decryptBRC39(bytes, passphrase) + if (document.user.identityKey !== recoveredIdentityKey) { + throw new Error('Archive belongs to a different wallet') + } + if (document.sourceStorage.chain !== expectedChain) { + throw new Error('Archive belongs to a different network') + } + return document +} + +// Call only after profile/target confirmation. Do not mutate the preview. +export async function restoreConfirmedWalletData( + emptyTarget: StorageProvider, + document: BRC38WalletData +) { + return await importBRC38(emptyTarget, document, { mode: 'restore' }) +} +``` + +Recheck the selected profile and target immediately before committing; reject +a changed selection. Keep the decrypted preview in trusted memory, not logs, +analytics or general application state persistence. Import validates network +compatibility but does not know the UI's active profile or prove possession of +the root key. Import success is data-write evidence, not proof of spendability. + +### Restore versus merge + +| Mode | Current behavior | Recovery implication | +| --------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `restore` | Checks for empty data tables, inserts rows in a storage transaction and retains exported IDs | Use an isolated new target with exclusive access; the emptiness check is not a cross-process lock | +| `merge` | Finds/inserts the archive identity, uses sync processing and remaps IDs/relationships and sync maps | Protect existing state first; this is not whole-database replacement or a single all-or-nothing transaction | + +Do not offer merge as an automatic retry after restore rejects a nonempty +target. Make it an explicit, separately tested product flow for the same wallet +identity. Imported active-storage and sync metadata must not silently authorize +a new endpoint or promote a provider. Restore retains the exported user's +`activeStorage`; the destination retains its own settings. Review authority +and use supported manager operations only after validation. Current import +also normalizes an exact legacy managed-change basket default; the +[managed-change guide](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox/docs/managed-change-policy.md) +and portable tests describe that compatibility behavior. + +## Resource, privacy and failure handling + +Bound file size before reading it into memory, concurrent imports and total +work on the supported device. The current helpers do not expose an +`AbortSignal`; a cancelled UI must not claim that an in-flight write rolled +back. Keep incomplete targets isolated and retain the source/archive for a +controlled retry. Do not lower KDF strength or bypass validation to make an +oversized or malformed file import successfully. + +Wrong passwords, damaged authentication tags, unsupported headers and invalid +records must leave the active wallet unchanged. Preserve the original file and +give a clear retry/support path. There is no passphrase-reset function for an +existing BRC-39 file; changing an application login password does not re-encrypt +old exports. Use the [recovery checklist](wallet-recovery-drill.md) for failure, +large-file and cross-runtime tests. Never upload a real export, passphrase, +root key or manager snapshot to an AI agent or public issue. diff --git a/docs/guides/wallet-recovery-agent-brief.md b/docs/guides/wallet-recovery-agent-brief.md new file mode 100644 index 000000000..f8368ad9d --- /dev/null +++ b/docs/guides/wallet-recovery-agent-brief.md @@ -0,0 +1,106 @@ +--- +id: wallet-recovery-agent-brief +title: 'Wallet Recovery Implementation Brief for AI Agents' +kind: guide +version: '1.0.0' +last_updated: '2026-09-24' +last_verified: '2026-09-24' +review_cadence_days: 30 +status: stable +tags: [wallet, recovery, backup, agents, implementation] +--- + +# Wallet recovery implementation brief for AI agents + +Use this brief to prepare a concrete wallet implementation and its acceptance +evidence. It is technical task guidance; repository contribution instructions +remain in the root +[AGENTS.md](https://github.com/bsv-blockchain/ts-stack/blob/main/AGENTS.md) +and [CONTRIBUTING.md](https://github.com/bsv-blockchain/ts-stack/blob/main/CONTRIBUTING.md). +It does not authorize production data access, a deployment or a real-money +transaction. + +## Read and verify before editing + +1. [Wallet backup and recovery](wallet-backup-recovery.md): the separate key, + wallet-data, product-data and backup-access requirements. +2. [BRC-38/39 portability](wallet-data-portability.md): real API signatures, + concrete-provider constraints, consistency limits and restore/merge semantics. +3. [Recovery drill](wallet-recovery-drill.md): fixture, negative tests and + evidence requirements. +4. The wallet host's key manager, profile storage, file APIs, selected network, + background writers and active-storage transition code. +5. The exact installed declarations and + [portable implementation/tests](wallet-data-portability.md#standards-implementation-and-evidence). + Record source commit and package versions; do not infer availability from + an open PR, an old package README or a generated-looking API name. + +## Copy and adapt this task + +```text +Implement a reviewed wallet backup and recovery flow for this repository. + +First report the current key manager, how keys can be recovered after device +loss, the selected profile/network model, storage provider, product data outside +Wallet Toolbox, and exact installed package versions. Identify gaps before +claiming complete recovery. Use synthetic fixtures; do not request or log real +keys, shares, passphrases, manager snapshots, exports or production records. + +Use TS Stack's wallet-backup-recovery, wallet-data-portability and +wallet-recovery-drill guides. Verify every helper against current declarations. +Use the appropriate Node/browser/mobile package. Remote StorageClient or +StorageMobile is not a concrete StorageProvider: implement and verify the local +copy or trusted export path before wiring exportBRC39 into UI. Do not invent +wallet.exportBRC39(), archive streaming, cancellation or snapshot guarantees. + +Provide encrypted export for the selected profile with a recoverable passphrase, +confirmed file-save completion, freshness information and clear exclusions. +Preserve library format/KDF defaults and enforce tested resource limits. Keep +key recovery and wallet-data backup as separate statuses and instructions. + +For import, recover the expected identity independently, decrypt/validate for +preview, compare identity and network, then confirm target and explicit mode. +Reject profile changes between preview and write. Restore into an isolated, +migrated empty provider without creating a user first; never clear an existing +wallet to make restore pass. Offer merge only as a separate tested flow with a +pre-import backup. Keep imported endpoint/sync metadata from silently changing +storage authority. Leave monitor/broadcast/cutover disabled until acceptance. + +Add meaningful host-level tests for saved-file reopen, wrong password/corrupt +file, wrong profile/network, nonempty target, interruption, stale backups, +resource limits and clean-device/provider-loss recovery. Verify transaction and +derivation records, relationships, tombstones and binary data; balance alone is +insufficient. Exercise restart and a controlled synthetic/testnet spend. Test +each claimed runtime and cross-wallet direction with exact versions. + +Deliver implementation, user instructions, recovery inventory, acceptance +evidence and explicit unresolved limits. Distinguish implemented, locally +tested, device-tested and released behavior. Follow this repository's review +and CI requirements; production recovery/cutover requires separate authority. +``` + +## Review the result + +- Can a new user find both recovery paths from onboarding, settings and an + offline-accessible help page? Is “backup complete” tied to verified evidence? +- Does the implementation keep key material out of the archive and logs while + acknowledging that wallet records themselves are highly sensitive? +- Is each selected profile/network bound throughout the operation, including + asynchronous file selection, preview and commit? +- Does the provider actually implement the required methods without type casts + that hide an unsupported remote-storage path? +- Does the consistency procedure stop every relevant writer to the export + copy, with explicit limits for a continuously changing remote source? +- Are failure states visible and retries safe? Does cancellation avoid claiming + rollback that the underlying API does not supply? +- Are expected records, key control and wallet behavior verified together on a + clean device, including external/custom dependencies? +- Are release/version claims grounded in the + [migration ledger](../reference/package-api-migrations.md) and the exact + installed artifact, with future capabilities labelled as future work? + +Record results using the [drill evidence template](wallet-recovery-drill.md#copyable-evidence-record). +For defects, supply the smallest synthetic reproduction through the root issue +templates. Suspected vulnerabilities belong in the +[private security process](https://github.com/bsv-blockchain/ts-stack/blob/main/.github/SECURITY.md), +not public recovery examples. diff --git a/docs/guides/wallet-recovery-drill.md b/docs/guides/wallet-recovery-drill.md new file mode 100644 index 000000000..fd5507c3c --- /dev/null +++ b/docs/guides/wallet-recovery-drill.md @@ -0,0 +1,155 @@ +--- +id: wallet-recovery-drill +title: 'Wallet Recovery Drill and Acceptance Checklist' +kind: guide +version: '1.0.0' +last_updated: '2026-09-24' +last_verified: '2026-09-24' +review_cadence_days: 30 +status: stable +tags: [wallet, recovery, backup, testing, interoperability] +--- + +# Wallet recovery drill and acceptance checklist + +A successful download or matching balance is not sufficient recovery evidence. +Prove that an independently recovered key and retained data work together after +the original device or provider is unavailable. Start with the +[recovery inventory](wallet-backup-recovery.md#what-must-survive) and +[BRC-38/39 integration guide](wallet-data-portability.md). + +This is a reusable acceptance plan, not a claim that TS Stack or any wallet has +passed every scenario. Use synthetic wallets and local/testnet fixtures. A +production restore, provider promotion or real-money spend needs a separate +operator-approved procedure; do not use this checklist to authorize one. + +## Prepare a representative fixture + +Record exact wallet/package versions, network, storage backend, device/runtime, +schema/migrations, selected profile and recovery point. Use at least two +distinct wallet identities so accidental cross-profile handling is detectable. +Include: + +- incoming and outgoing transactions; spent and unspent outputs; +- derivation prefixes/suffixes, sender identities, scripts and any supported + custom spending instructions; +- multiple baskets, tags, labels and map relationships, including tombstones; +- certificates/fields and their required keys; +- linked proof records, pending broadcast/proof state and sync state; +- product-owned contacts, trust settings or files that need a separate backup; +- enough records and large byte payloads to exercise the supported device's + limits, rather than only an empty wallet. + +Keep an independent expected inventory. The archive has 13 table arrays; +backend sync protocols may count their entity stores differently. Compare +relationships and values, not just a single total or balance. Make explicit +which product data is excluded and how it is restored separately. + +## Rehearse the full sequence + +1. **Protect the original.** Keep existing known-good recovery material and + versioned data copies. Provision an isolated recovery target. Disable its + automatic broadcasting, monitor side effects and writes to production + providers through the host's tested controls. +2. **Establish a recovery point.** Quiesce a local source or use a consistent + database backup. Export the selected profile, save the encrypted file and + verify it can be reopened. Record the time and expected inventory without + logging secrets or plaintext records. +3. **Remove the original dependency.** Use a clean installation/device/profile + with no original browser storage, manager snapshot or cached credentials. + Simulate provider unavailability. Do not actually erase the sole original. +4. **Recover signing authority independently.** Follow the product's key/share + recovery instructions. Derive the identity and compare it with the expected + profile. Test any required privileged keys or external signer separately. +5. **Preview and import data.** Confirm archive identity, network and mode. + Restore into empty, migrated storage with exclusive access. Keep the + recovered copy isolated while checking all expected records and product data. +6. **Reconcile current state.** Verify transaction bytes, relationships, + tombstones, output ownership and derivation. Revalidate proofs and current + spend state through supported services. Resolve pending transactions using + existing transaction identities; do not create replacement payments merely + because confirmation was lost. +7. **Exercise wallet behavior.** Read history and basketed outputs through + normal APIs, prove key control with a harmless challenge, and spend a known + synthetic/testnet fixture under controlled conditions. Include custom + scripts and certificate/decryption behavior if the product supports them. + Key possession alone does not prove those assets are usable. +8. **Restart and verify again.** Confirm state survives restart, repeated reads + agree, and the tested merge/sync retry does not duplicate or lose semantic + records. The `restore` mode intentionally rejects a now-nonempty target; + repeat restoration uses another empty target. +9. **Approve cutover separately.** Resolve active-storage authority, endpoint + trust and sync policy before reconnecting writers or promoting a provider. + Keep the original protected until acceptance is complete; retain evidence + and a rollback plan for the cutover. + +## Minimum acceptance matrix + +| Scenario | Expected result | +| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Clean-device recovery | Same independently derived wallet identity; expected records and tested wallet behavior restored without the original installation | +| Seed/key only | Product explains missing data and offers recovery from an available backup; does not report complete recovery | +| Archive only, missing root key | Data can be inspected by an authorized holder of its passphrase, but product does not claim signing authority | +| Lost provider | Independent key and data copies remain accessible; document any dependency that still prevents recovery | +| Wrong password, truncated file or modified tag | Clear failure; no activation or modification of the existing wallet | +| Unsupported header, invalid fields or broken references | Rejected before import; original archive retained | +| Wrong profile or network | Host blocks before writes; profile switching during preview/commit cannot redirect the import | +| Nonempty restore target | Explicit rejection; no automatic deletion, overwrite or fallback to merge | +| Interrupted import or lost save acknowledgement | Product identifies uncertain/incomplete state and offers a safe retry; no false “backed up” or “restored” status | +| Old backup after new receives/spends | Product shows the recovery point and unresolved gap; stale spendable flags do not authorize a spend | +| Repeated merge/sync | No duplicated semantic transactions/outputs or revived tombstones; compare data rather than demanding zero bookkeeping updates | +| Concurrent source writes | Export uses the documented consistency procedure; no claim that sequential reads form a database snapshot | +| Low-memory device and large file | Enforced product limits, measured peak memory/time and usable failure/progress UI; no weakened cryptography | +| Browser eviction, app uninstall, device loss | Recovery succeeds through independent copies, or the exact unsupported case is clearly disclosed | +| Vendor A export → vendor B import | Same identity/network and compatible row semantics; unsupported product extensions disclosed; test the reverse direction when claimed | +| Key/share or passphrase dependency unavailable | Document the supported combinations and actual failure behavior; no circular recovery assumption | + +For operator backups, additionally restore a retained database backup into a +separate environment, apply only reviewed schema migrations, restore required +external data and secret-store access, and measure actual recovery time/data +loss. Keep monitor/background jobs disabled until their side effects and +replay state have been reviewed. Replicas, backups and service health are +separate evidence. + +## Diagnose failures without destroying evidence + +| Symptom | Safe next step | +| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| File cannot decrypt | Check original bytes and passphrase entry; do not modify KDF/header fields or promise a password reset | +| Import rejects target | Inspect network, schema and emptiness; provision a new isolated store rather than clearing the existing one | +| Data imports but wallet identity differs | Stop before activation; recover the correct key/profile and repeat preview | +| Balance/history differs | Compare full data inventory, backup time, relationships, pending state and product exclusions; do not rely on rescan as a universal repair | +| Proofs are stale or a spend fails | Use supported canonical proof/status recovery; preserve transaction IDs and avoid duplicate payment attempts | +| Merge or sync was interrupted | Preserve both sides; inspect committed state and use the tested retry path or restore the isolated target from its pre-import backup | +| Schema migration fails | Preserve the database and migration journal; follow the version-specific recovery procedure, never delete journal rows blindly | + +## Copyable evidence record + +Store real recovery evidence privately. Public records should use synthetic +fixtures and redact wallet identifiers, balances and storage topology when +they are sensitive. Never include keys, shares, passphrases, manager snapshots +or plaintext/export files. + +```text +Recovery drill ID / date / owner: +Wallet version / source commit / exact package versions: +Runtime / device / network / backend / schema version: +Synthetic fixture ID / profile count / data classes covered: +Key recovery method / unavailable factors tested (no secret values): +Data recovery method / consistent recovery point / archive digest: +Product data included / excluded / separate restoration method: +Source device/provider dependencies removed for the drill: +Restore or merge target and authority decision: +Expected vs actual inventory / relationships / binary-data verification: +Identity / read / controlled spend / restart / retry outcomes: +Negative, resource-limit and cross-wallet scenarios with results: +Observed data-loss interval / restore duration vs declared objectives: +Unresolved gaps / user-visible limitations / remediation owner: +Cutover authorized separately? / rollback evidence: +Reviewer / next drill due / evidence location: +``` + +Use “passed” only for an executed scenario with retained evidence. Keep +unexecuted tests and unsupported recovery paths visible. Feed failures back +into the [product guidance](wallet-backup-recovery.md#make-recovery-understandable-in-the-product) +and [agent implementation brief](wallet-recovery-agent-brief.md). diff --git a/docs/index.md b/docs/index.md index 55be67fc5..de066928f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,8 +3,8 @@ id: home title: ts-stack kind: meta version: 'n/a' -last_updated: '2026-07-27' -last_verified: '2026-08-26' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: [] @@ -23,6 +23,14 @@ This repository is the TypeScript reference stack for BSV application developmen ![BRC-100 desktop and mobile request flows](./assets/diagrams/brc100-wallet-flows.svg) +## Wallet recovery + +Building or operating a wallet? Plan for **both root-key recovery and wallet-data +recovery**. The [recovery guide](guides/wallet-backup-recovery.md) connects +[BRC-38/39 integration](guides/wallet-data-portability.md), a +[restore drill](guides/wallet-recovery-drill.md) and an +[AI-agent brief](guides/wallet-recovery-agent-brief.md). + ## Start Here | You are | Use first | Why | diff --git a/docs/infrastructure/wallet-infra.md b/docs/infrastructure/wallet-infra.md index 2d233edec..80a0ee242 100644 --- a/docs/infrastructure/wallet-infra.md +++ b/docs/infrastructure/wallet-infra.md @@ -2,9 +2,9 @@ id: infra-wallet-infra title: 'Wallet Infrastructure Services' kind: infra -version: '2.0.38' -last_updated: '2026-09-07' -last_verified: '2026-09-07' +version: '2.0.44' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: [wallet, utxo-storage, json-rpc, brc-100, storage-server] @@ -195,6 +195,21 @@ The default task set handles: For `mock`, the reference server uses `MockServices` with shorter task timing so local integration tests complete quickly. +## Backup and recovery + +This service preserves wallet data, while the wallet owns user-key recovery. +Its server identity is not a user's root key. Provide consistent encrypted +backups with retained versions, independent access and documented data-loss +and restore-time objectives. Include schema/migration history and external +stores required by the deployed configuration. Replication does not protect +against every deletion, corruption or provider-loss scenario. + +Follow [Wallet backup and recovery](../guides/wallet-backup-recovery.md) and +[the operator recovery drill](../guides/wallet-recovery-drill.md). Restore into +an isolated environment with monitor/broadcast side effects controlled before +reconnecting writers. A user's [BRC-39 export](../guides/wallet-data-portability.md) +is a separate portability path, not a full service/database backup. + ## Health checks The storage listener exposes `/healthz`. The image health check probes nginx on diff --git a/docs/packages/wallet/index.md b/docs/packages/wallet/index.md index 7aeba82a8..c5d68a24b 100644 --- a/docs/packages/wallet/index.md +++ b/docs/packages/wallet/index.md @@ -4,8 +4,8 @@ title: Wallet kind: meta domain: wallet version: 'n/a' -last_updated: '2026-07-27' -last_verified: '2026-08-26' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: ['domain', 'wallet'] @@ -129,6 +129,14 @@ wallet interface or exposing the scalar. - Don't use wallet packages if you only need transaction building — use [@bsv/sdk](../sdk/bsv-sdk.md) directly - Don't use wallet-toolbox if you only need BRC-100 interface types — import from SDK instead +## Backup and recovery + +Wallet recovery needs both key material and records/derivation metadata. +Browser storage, remote replication and key-manager snapshots each cover only +part of that requirement. Use the [recovery guide](../../guides/wallet-backup-recovery.md), +[BRC-38/39 API guide](../../guides/wallet-data-portability.md) and +[recovery drill](../../guides/wallet-recovery-drill.md) before shipping a wallet. + ## Next Steps - **[@bsv/wallet-toolbox](./wallet-toolbox.md)** — Full wallet implementation diff --git a/docs/packages/wallet/wallet-toolbox-client.md b/docs/packages/wallet/wallet-toolbox-client.md index ec8f5bb14..5f61c9d59 100644 --- a/docs/packages/wallet/wallet-toolbox-client.md +++ b/docs/packages/wallet/wallet-toolbox-client.md @@ -4,8 +4,8 @@ title: '@bsv/wallet-toolbox-client' kind: package domain: wallet version: '2.14.0' -last_updated: '2026-09-23' -last_verified: '2026-09-23' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 npm: 'https://www.npmjs.com/package/@bsv/wallet-toolbox-client' repo: 'https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/client' @@ -67,6 +67,18 @@ The portable local controller coalesces stale height refresh and immutable object loads, applies failed-load backoff, and validates through the asynchronous `InlineBulkFileDataValidator` without importing Node worker or filesystem code. +## Backup and recovery + +Recover both key material and wallet records; a manager snapshot or device +keystore alone is not a complete data backup. IndexedDB can be evicted or lost +with the browser profile. Keep an independent data copy and test recovery on a +clean profile. +Use the [recovery guide](../../guides/wallet-backup-recovery.md), +[BRC-38/39 integration](../../guides/wallet-data-portability.md) and +[recovery drill](../../guides/wallet-recovery-drill.md). The portable helpers +require a concrete provider and a tested consistency/resource-limit strategy. + + ## Install ```bash diff --git a/docs/packages/wallet/wallet-toolbox-examples.md b/docs/packages/wallet/wallet-toolbox-examples.md index e6f133ac1..d694791f8 100644 --- a/docs/packages/wallet/wallet-toolbox-examples.md +++ b/docs/packages/wallet/wallet-toolbox-examples.md @@ -4,8 +4,8 @@ title: '@bsv/wallet-toolbox-examples' kind: package domain: wallet version: '1.1.157' -last_updated: '2026-07-27' -last_verified: '2026-08-26' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 repo: 'https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox-examples' status: stable @@ -16,11 +16,19 @@ tags: ['wallet', 'examples', 'reference'] Reference wallet implementations built with `@bsv/wallet-toolbox`. Demonstrates common wallet construction patterns across different storage backends and deployment contexts. -## Install +## Run from the workspace -```bash -npm install @bsv/wallet-toolbox-examples -``` +This is a private examples workspace, not a supported npm installation target. +Follow the [workspace README](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox-examples) +for setup and safety requirements. + +## Backup example coverage + +The [SQLite backup example](https://github.com/bsv-blockchain/ts-stack/blob/main/packages/wallet/wallet-toolbox-examples/src/backup.ts) +copies sensitive wallet data. It does not back up the root key, establish a +retention policy or prove device-loss recovery. Use the +[complete recovery guide](../../guides/wallet-backup-recovery.md) and +[drill checklist](../../guides/wallet-recovery-drill.md). ## Purpose diff --git a/docs/packages/wallet/wallet-toolbox-mobile.md b/docs/packages/wallet/wallet-toolbox-mobile.md index ec9d2104b..b97830847 100644 --- a/docs/packages/wallet/wallet-toolbox-mobile.md +++ b/docs/packages/wallet/wallet-toolbox-mobile.md @@ -4,8 +4,8 @@ title: '@bsv/wallet-toolbox-mobile' kind: package domain: wallet version: '2.14.0' -last_updated: '2026-09-23' -last_verified: '2026-09-23' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 npm: 'https://www.npmjs.com/package/@bsv/wallet-toolbox-mobile' repo: 'https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/mobile' @@ -67,6 +67,18 @@ The portable local controller coalesces stale height refresh and immutable object loads, applies failed-load backoff, and validates through the asynchronous `InlineBulkFileDataValidator` without importing Node worker or filesystem code. +## Backup and recovery + +Recover both key material and wallet records; a manager snapshot or device +keystore alone is not a complete data backup. App removal or device loss can +remove locally retained secrets and state. +Test the independent key and data recovery paths on a replacement device. +Use the [recovery guide](../../guides/wallet-backup-recovery.md), +[BRC-38/39 integration](../../guides/wallet-data-portability.md) and +[recovery drill](../../guides/wallet-recovery-drill.md). The portable helpers +require a concrete provider and a tested consistency/resource-limit strategy. + + ## Install ```bash diff --git a/docs/packages/wallet/wallet-toolbox.md b/docs/packages/wallet/wallet-toolbox.md index 5572de51c..4728ebda9 100644 --- a/docs/packages/wallet/wallet-toolbox.md +++ b/docs/packages/wallet/wallet-toolbox.md @@ -5,8 +5,8 @@ kind: package domain: wallet npm: '@bsv/wallet-toolbox' version: '2.14.0' -last_updated: '2026-09-23' -last_verified: '2026-09-23' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: ['wallet', 'brc100'] @@ -19,6 +19,21 @@ repo: 'https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wall Use this package when you are building a wallet product, a wallet-like service, or another implementation that must match BRC-100 behavior. +## Backup and recovery + +**Recoverable root key material and wallet records are both required.** A seed +alone cannot reconstruct every BRC-100 output's derivation metadata. BRC-38/39 +exports preserve wallet data, not root keys or unrelated product state. + +Start with [Wallet backup and recovery](../../guides/wallet-backup-recovery.md), +then use [BRC-38/39 integration](../../guides/wallet-data-portability.md), the +[recovery drill](../../guides/wallet-recovery-drill.md) and the +[agent implementation brief](../../guides/wallet-recovery-agent-brief.md). +The integration guide documents concrete-provider requirements, explicit +restore/merge modes and the limits of the current in-memory export helpers. + +## Current capabilities + Wallet Toolbox 2.11 adds the built-in BRC-177 `p nosend expiry` module. It pre-funds expiring `noSend` actions, stores a signed reclaim durably across active/backup storage and restarts, and lets the authoritative local or remote @@ -41,8 +56,9 @@ normal verified lineage resolution remains ambiguous and the outpoint is one of the wallet's verified candidates. Applications must persist `saveSnapshot()` immediately after `completePhoneNumberChange()` succeeds. -Snapshots intentionally carry everything needed to restore sensitive wallet -state; possession of a snapshot is possession of the wallet. Store each +Wallet-manager snapshots can carry root and privileged key material; they do +not include the Wallet Toolbox storage database. Possession of such a snapshot +is possession of the wallet's key material. Store each complete snapshot only in an OS Keychain, hardware-backed keystore, or comparably trusted secret store. Remote storage and credential-bearing Arcade SSE require HTTPS except for explicit loopback development, and transport diff --git a/docs/reference/brc-index.md b/docs/reference/brc-index.md index f7f51282d..a40935cdb 100644 --- a/docs/reference/brc-index.md +++ b/docs/reference/brc-index.md @@ -3,8 +3,8 @@ id: brc-index title: 'BRC Standards Index' kind: reference version: 'n/a' -last_updated: '2026-07-27' -last_verified: '2026-08-26' +last_updated: '2026-09-24' +last_verified: '2026-09-24' review_cadence_days: 30 status: stable tags: [reference, brc, standards] @@ -21,6 +21,9 @@ All Bitcoin Request for Comments (BRC) standards referenced in ts-stack source, | BRC-14 | Script Evaluation & Sighash | Scripts | — | `@bsv/sdk` | | BRC-29 | Peer-to-Peer Payment Protocol | Payments | [spec](../specs/brc-29-peer-payment.md) | `@bsv/paymail`, `@bsv/message-box-client` | | BRC-31 | HTTP Mutual Authentication Handshake | Auth | [spec](../specs/brc-31-auth.md) | `@bsv/auth-express-middleware`, `@bsv/authsocket` | +| BRC-38 | User Wallet Data Format | Wallet | [standard](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0038.md) | `@bsv/wallet-toolbox`; [integration guide](../guides/wallet-data-portability.md) | +| BRC-39 | User Wallet Data Format Encryption Extension | Wallet | [standard](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0039.md) | `@bsv/wallet-toolbox`; [recovery guide](../guides/wallet-backup-recovery.md) | +| BRC-40 | User Wallet Data Synchronization | Wallet | [standard](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0040.md) | `@bsv/wallet-toolbox` | | BRC-42 | Key Derivation Scheme (BKDS) | Crypto | — | `@bsv/sdk`, `@bsv/wallet-toolbox` (heavy BRC-42 vector coverage in sdk/keys + wallet/brc100) | | BRC-43 | Security Levels for BKDS | Crypto | — | `@bsv/sdk` | | BRC-48 | PushDrop Token Protocol | Tokens | — | `@bsv/overlay-topics`, `@bsv/btms` | @@ -87,6 +90,15 @@ Implementations: `@bsv/auth-express-middleware`, `@bsv/authsocket`, `@bsv/sdk` ( Spec: `specs/auth/brc103-mutual-auth.yaml` +### BRC-38/39: Wallet data portability and encryption + +[BRC-38](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0038.md) +defines a single user's portable wallet records; +[BRC-39](https://github.com/bitcoin-sv/BRCs/blob/master/outpoints/0039.md) +defines their encrypted file wrapper. These cover wallet data, not root-key +recovery. Use the [implementation guide](../guides/wallet-data-portability.md) +and [recovery plan](../guides/wallet-backup-recovery.md) together. + ### BRC-42: Key Derivation Scheme (BKDS) Deterministic key derivation for BSV wallets. All BRC-100 wallet keys are derived via BRC-42. diff --git a/infra/wallet-infra/README.md b/infra/wallet-infra/README.md index 109eba5c5..dcd3cdb67 100644 --- a/infra/wallet-infra/README.md +++ b/infra/wallet-infra/README.md @@ -8,6 +8,20 @@ See [Service Resource Profiles](../../docs/reference/service-resource-profiles.m for RPC ceilings, API/monitor role separation, official-image provider settings, and Wallet Storage HPA prerequisites. +## Backup and disaster recovery + +Wallet users need both recoverable root keys and wallet records/derivation +metadata. This service stores data; its server identity key does not replace a +user's root key. Operators must provide consistent encrypted database backups, +versioned retention, independent restore access and measured recovery objectives. +Replication and `/healthz` do not prove backup recoverability. + +Use [Wallet backup and recovery](../../docs/guides/wallet-backup-recovery.md), +[BRC-38/39 per-user portability](../../docs/guides/wallet-data-portability.md) and +[the recovery drill](../../docs/guides/wallet-recovery-drill.md). Include schema, +required external stores and secret-store access in an isolated operator +restore test; review background-job side effects before activating the copy. + ## Key Features 1. #### Out-of-the-Box UTXO Management diff --git a/packages/wallet/wallet-toolbox-examples/README.md b/packages/wallet/wallet-toolbox-examples/README.md index 7c629112f..269c55bbf 100644 --- a/packages/wallet/wallet-toolbox-examples/README.md +++ b/packages/wallet/wallet-toolbox-examples/README.md @@ -53,8 +53,14 @@ Treat the following boundaries as security decisions: ## Documentation -[The Docs](https://bsv-blockchain.github.io/wallet-toolbox) are available here on Github pages. -[Example code](https://docs.bsvblockchain.org/guides/sdks/ts/examples) is available over on our gitbook. +Use the maintained [Wallet Toolbox docs](https://bsv-blockchain.github.io/ts-stack/packages/wallet/wallet-toolbox/) +and [workspace examples](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox-examples). + +The [SQLite backup example](src/backup.ts) copies wallet data through storage +replication; it does not export the root key or establish independent retention. +Follow [Wallet backup and recovery](https://bsv-blockchain.github.io/ts-stack/guides/wallet-backup-recovery/), +[BRC-38/39 integration](https://bsv-blockchain.github.io/ts-stack/guides/wallet-data-portability/) and the +[recovery drill](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-drill/) to build a complete flow. The Toolbox is richly documented with code-level annotations. This should show up well within editors like VSCode. diff --git a/packages/wallet/wallet-toolbox/README.md b/packages/wallet/wallet-toolbox/README.md index bd799f33b..2efec936d 100644 --- a/packages/wallet/wallet-toolbox/README.md +++ b/packages/wallet/wallet-toolbox/README.md @@ -6,6 +6,28 @@ A [BRC-100](https://github.com/bitcoin-sv/BRCs/blob/master/wallet/0100.md) conforming wallet implementation for the BSV blockchain, built on the [BSV SDK](https://bsv-blockchain.github.io/ts-stack/packages/sdk/). Provides persistent storage, protocol-based key derivation, transaction monitoring, chain tracking, and signing — everything needed to build wallet-powered applications on BSV. +## Backup and recovery: keep both keys and wallet data + +**A root key or seed alone is not a complete BRC-100 wallet backup.** Users +need recoverable key material **and** wallet records, including derivation +metadata, transactions and basketed outputs. A database copy or BRC-39 file +preserves data; it does not replace root-key recovery. Wallet-manager snapshots +can contain keys and must be protected as secrets, but are not storage backups. + +Wallet builders must provide both recovery paths, explain what their product +backs up, and test restoration after device or storage-provider loss. Storage +replication helps availability but does not replace versioned, independently +accessible backups and a tested restore procedure. + +- [Wallet backup and recovery](https://bsv-blockchain.github.io/ts-stack/guides/wallet-backup-recovery/) — recovery inventory, product/operator responsibilities and user guidance. +- [BRC-38/39 integration](https://bsv-blockchain.github.io/ts-stack/guides/wallet-data-portability/) — current export/import APIs, provider constraints, restore versus merge and limits. +- [Recovery drill and checklist](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-drill/) — clean-device recovery, negative tests and evidence template. +- [AI-agent implementation brief](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-agent-brief/) — source-grounded task and review guidance. + +These guides cover the recovery design. The measurements below describe +specific tests and do not establish that every wallet product has complete +key-and-data disaster recovery. + ## Backup and sync: tested results **Live E2E testing used a large wallet in the native desktop client**, covering @@ -29,7 +51,7 @@ Timing compares successive candidates, not a controlled comparison against upstr ### SQLite migration recovery -The unpublished 2.13.2 candidate runs SQLite migration DDL and the migration +SQLite migration handling introduced in 2.13.2 runs migration DDL and the migration journal update transactionally. Foreign-key enforcement is disabled before the migration transaction for table rebuilds and restored after success or failure. Failed migrations can be retried after reopening the database without partial diff --git a/packages/wallet/wallet-toolbox/client/README.md b/packages/wallet/wallet-toolbox/client/README.md index 82fc1f70d..db3492fac 100644 --- a/packages/wallet/wallet-toolbox/client/README.md +++ b/packages/wallet/wallet-toolbox/client/README.md @@ -13,6 +13,20 @@ Use this package in: For Node servers, use [`@bsv/wallet-toolbox`](https://www.npmjs.com/package/@bsv/wallet-toolbox). For React Native / mobile, use [`@bsv/wallet-toolbox-mobile`](https://www.npmjs.com/package/@bsv/wallet-toolbox-mobile). +## Backup and recovery + +A BRC-100 wallet needs both recoverable keys and wallet records/derivation +metadata. BRC-39 exports contain wallet data, not root keys or manager snapshots. +IndexedDB can be evicted or lost with the browser profile. Keep an independent +data copy and test recovery on a clean profile. + +Read [Wallet backup and recovery](https://bsv-blockchain.github.io/ts-stack/guides/wallet-backup-recovery/), +[BRC-38/39 integration](https://bsv-blockchain.github.io/ts-stack/guides/wallet-data-portability/) and the +[recovery checklist](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-drill/). +Portable helpers require a concrete local `StorageProvider`; a remote client +is not one. Qualify the local-copy path and device memory limits before adding +export/import UI. + ## Large wallet records Compatible providers negotiate authenticated, integrity-checked transfers for diff --git a/packages/wallet/wallet-toolbox/docs/README.md b/packages/wallet/wallet-toolbox/docs/README.md index 5f3f25f08..3d66a585d 100644 --- a/packages/wallet/wallet-toolbox/docs/README.md +++ b/packages/wallet/wallet-toolbox/docs/README.md @@ -2,7 +2,11 @@ The documentation is split into various pages, each covering a set of related functionality. The pages are as follows: -- [Examples](https://bsv-blockchain.github.io/wallet-toolbox-examples/) - Getting started and specialized examples. +- [Backup and recovery](https://bsv-blockchain.github.io/ts-stack/guides/wallet-backup-recovery/) — Both key material and wallet records are required. +- [BRC-38/39 integration](https://bsv-blockchain.github.io/ts-stack/guides/wallet-data-portability/) — Current portable data APIs and import/export limits. +- [Recovery drill](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-drill/) — Acceptance checklist and evidence template. +- [Agent implementation brief](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-agent-brief/) — Source map and implementation guidance. +- [Examples](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox-examples) — Current workspace examples and safety instructions. - [Setup](./setup.md) — Classes supporting wallet setup, experimentation and customization. - [Wallet](./wallet.md) — Top level `Wallet` class and related APIs. - [Client](./client.md) — Browser deployment friendly toolbox subset. @@ -18,7 +22,7 @@ The documentation is split into various pages, each covering a set of related fu [BRC-100](https://brc.dev/100) defines a Unified, Vendor-Neutral, Unchanging, and Open BSV Blockchain Standard Wallet-to-Application Interface which is implemented in this library within the WalletClient class. The API is laid out here as a swagger openapi document to offer a fast-track to understanding the interface which is implemented across multiple substrates. The JSON api is generally considered a developer friendly introduction to the WalletClient, where an binary equivalent ABI may be preferred for production use cases. -- [Wallet API Swagger UI](https://bsv-blockchain.github.io/ts-sdk/swagger) +- [BRC-100 wallet API](https://bsv-blockchain.github.io/ts-stack/specs/brc-100-wallet/) ## Open RPC @@ -47,11 +51,13 @@ npm install @bsv/wallet-toolbox Here's a simple example of using the toolbox to create and fund a testnet wallet using SQLite for persistent storage: ```ts -import { InternalizeActionArgs, PrivateKey, Utils } from '@bsv/sdk' +import { InternalizeActionArgs, Utils } from '@bsv/sdk' import { Setup } from '@bsv/wallet-toolbox' -const rootKeyHex = PrivateKey.fromRandom().toString() -console.log(`MAKE A SECURE COPY OF YOUR WALLET PRIVATE ROOT KEY: ${rootKeyHex}`) +// Test fixture only: supply a recoverable test key; never log it. +// Production wallets use their reviewed secret-store/key-recovery integration. +const rootKeyHex = process.env.TEST_WALLET_ROOT_KEY +if (!rootKeyHex) throw new Error('Configure a test wallet root key first') const { wallet } = await Setup.createWalletSQLite({ filePath: './myTestWallet.sqlite', diff --git a/packages/wallet/wallet-toolbox/docs/wab-shamir.md b/packages/wallet/wallet-toolbox/docs/wab-shamir.md index 3dbcc2578..21ec89535 100644 --- a/packages/wallet/wallet-toolbox/docs/wab-shamir.md +++ b/packages/wallet/wallet-toolbox/docs/wab-shamir.md @@ -1,6 +1,10 @@ # WAB Shamir Key Recovery -This guide covers the Shamir Secret Sharing key recovery system, which provides secure wallet backup and recovery using a configurable threshold scheme. +This guide covers Shamir Secret Sharing **key recovery** using a configurable +threshold scheme. Recovering the key does not restore wallet records, output +derivation metadata or product data. Pair this flow with an independent data +backup and the [wallet recovery plan](https://bsv-blockchain.github.io/ts-stack/guides/wallet-backup-recovery/); +test both together using the [recovery drill](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-drill/). ## Overview diff --git a/packages/wallet/wallet-toolbox/mobile/README.md b/packages/wallet/wallet-toolbox/mobile/README.md index 2b47db48a..72de3fa75 100644 --- a/packages/wallet/wallet-toolbox/mobile/README.md +++ b/packages/wallet/wallet-toolbox/mobile/README.md @@ -13,6 +13,20 @@ Use this package in: For Node servers, use [`@bsv/wallet-toolbox`](https://www.npmjs.com/package/@bsv/wallet-toolbox). For browsers, use [`@bsv/wallet-toolbox-client`](https://www.npmjs.com/package/@bsv/wallet-toolbox-client). +## Backup and recovery + +A BRC-100 wallet needs both recoverable keys and wallet records/derivation +metadata. BRC-39 exports contain wallet data, not root keys or manager snapshots. +App removal or device loss can remove locally retained secrets and state. +Test the independent key and data recovery paths on a replacement device. + +Read [Wallet backup and recovery](https://bsv-blockchain.github.io/ts-stack/guides/wallet-backup-recovery/), +[BRC-38/39 integration](https://bsv-blockchain.github.io/ts-stack/guides/wallet-data-portability/) and the +[recovery checklist](https://bsv-blockchain.github.io/ts-stack/guides/wallet-recovery-drill/). +Portable helpers require a concrete local `StorageProvider`; a remote client +is not one. Qualify the local-copy path and device memory limits before adding +export/import UI. + ## Large wallet records Compatible providers negotiate authenticated, integrity-checked transfers for