diff --git a/docs/packages/wallet/wallet-toolbox-client.md b/docs/packages/wallet/wallet-toolbox-client.md index 3394e1d8fa..55c1a25ad0 100644 --- a/docs/packages/wallet/wallet-toolbox-client.md +++ b/docs/packages/wallet/wallet-toolbox-client.md @@ -72,6 +72,11 @@ 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. +BEEF requests and schema-declared storage response bytes use the existing +negotiated compact binary JSON codec. Legacy peers retain numeric-array JSON +and identical transaction/proof bytes. Authentication and payload ceilings +remain unchanged; upgrade both clients and active storage for the savings. + ## Backup and recovery Recover both key material and wallet records; a manager snapshot or device diff --git a/docs/packages/wallet/wallet-toolbox-mobile.md b/docs/packages/wallet/wallet-toolbox-mobile.md index ccd68a5f05..ebc8344936 100644 --- a/docs/packages/wallet/wallet-toolbox-mobile.md +++ b/docs/packages/wallet/wallet-toolbox-mobile.md @@ -72,6 +72,11 @@ 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. +BEEF requests and schema-declared storage response bytes use the existing +negotiated compact binary JSON codec. Legacy peers retain numeric-array JSON +and identical transaction/proof bytes. Authentication and payload ceilings +remain unchanged; upgrade both clients and active storage for the savings. + ## Backup and recovery Recover both key material and wallet records; a manager snapshot or device diff --git a/docs/packages/wallet/wallet-toolbox.md b/docs/packages/wallet/wallet-toolbox.md index 7b245db059..261a50bfe3 100644 --- a/docs/packages/wallet/wallet-toolbox.md +++ b/docs/packages/wallet/wallet-toolbox.md @@ -19,6 +19,11 @@ 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. +BEEF requests and schema-declared storage response bytes use the existing +negotiated compact binary JSON codec. Legacy peers retain numeric-array JSON +and identical transaction/proof bytes. Authentication and payload ceilings +remain unchanged; upgrade both clients and active storage for the savings. + ## Optional registry descriptions ProtoMap, BasketMap and CertMap supply descriptive metadata, not permission grants. diff --git a/docs/reference/package-api-migrations.md b/docs/reference/package-api-migrations.md index 4798f0bf2c..ddb72bb404 100644 --- a/docs/reference/package-api-migrations.md +++ b/docs/reference/package-api-migrations.md @@ -54,9 +54,9 @@ and clean-consumer tests remain the executable type authority. | `@bsv/verifast` | `0.3.6` | `0.3.7` | patch | [API and usage](../packages/sdk/verifast.md) | Valid typed verification calls and worker protocols remain compatible. Custom module factories and WASM adapters must return the exact documented binary and boolean shapes; coercive network, height, flag, byte, batch, verdict, lifecycle, or disposed-instance values now fail closed. Keep THIRD_PARTY_NOTICES.md and LICENSES/ with every JavaScript and WebAssembly distribution. SDK consumers may retain ^2.1.8 or install the proposed SDK3 candidate. The immutable SDK2.8.11 reference has nine pre-existing SDK cold-leaf/UMD import defects; all historical floor versions are not qualified by this matrix. SDK3 removes the obsolete DID token API; use the identity-key DID and optional BRC52 adapters described in docs/guides/identity-did-vc-migration.md. No other public API or wire migration is introduced by the peer alternative. | | `@bsv/wallet-helper` | `0.1.8` | `0.1.9` | patch | [API and usage](../packages/helpers/wallet-helper.md) | getAddress now derives with forSelf: true and returns the caller-owned side of the bilateral relationship. Applications that stored or coordinated the previous peer-owned result must regenerate and exchange the corrected address before sending value. Amount must be an integer from 1 through 1,000 and counterparties must be valid public keys. Valid canonical transaction-builder flows remain supported; malformed, ambiguous, or wallet-mutated results now fail closed. Distributors must retain THIRD_PARTY_NOTICES.md and LICENSES/ with the package. SDK consumers may retain ^2.1.6 or install the proposed SDK3 candidate. The immutable SDK2.8.11 reference has nine pre-existing SDK cold-leaf/UMD import defects; all historical floor versions are not qualified by this matrix. SDK3 removes the obsolete DID token API; use the identity-key DID and optional BRC52 adapters described in docs/guides/identity-did-vc-migration.md. No other public API or wire migration is introduced by the peer alternative. | | `@bsv/wallet-relay` | `0.5.1` | `0.5.2` | patch | [API and usage](../packages/wallet/wallet-relay.md) | Enable signed QR codes and distribute only HTTPS pairing origins and relay API URLs. Root-relative API paths and loopback HTTP remain supported. Configure onApprovalRequired for every method not deliberately listed in autoApproveMethods; unsigned pairing URIs and implicit approval are no longer accepted. Existing relay sessions, custom RPC method names, and supported wallet RPC byte encodings remain valid, and host applications continue to provide their matching Express runtime and type graph. Version 0.5 defaults to two missed pongs; set maxMissedHeartbeats to 1 to retain the prior heartbeat policy. Heartbeat intervals must fit the Node timer range. Preserve Cache-Control: no-store at proxies, prefer the stable bsv-wallet-relay plus token WebSocket subprotocols over the legacy token query parameter, and configure edge rate limiting in addition to the bounded in-process defaults. The 24-hour connected-session lifetime no longer renews on reconnect, malformed wallet calls fail with code 400, and WalletRelayClient retains at most 100 log entries unless maxLogEntries is configured. The QR remains a short-lived bearer invitation: keep it private and require explicit operation approval. Relay envelopes, cryptographic framing, and wallet RPC encodings remain unchanged. SDK consumers may retain ^2.4.1 or install the proposed SDK3 candidate. The immutable SDK2.8.11 reference has nine pre-existing SDK cold-leaf/UMD import defects; all historical floor versions are not qualified by this matrix. SDK3 removes the obsolete DID token API; use the identity-key DID and optional BRC52 adapters described in docs/guides/identity-did-vc-migration.md. No other public API or wire migration is introduced by the peer alternative. | -| `@bsv/wallet-toolbox` | `2.14.5` | `2.14.7` | patch | [API and usage](../packages/wallet/wallet-toolbox.md) | No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. | -| `@bsv/wallet-toolbox-client` | `2.14.5` | `2.14.7` | patch | [API and usage](../packages/wallet/wallet-toolbox-client.md) | No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. | -| `@bsv/wallet-toolbox-mobile` | `2.14.5` | `2.14.7` | patch | [API and usage](../packages/wallet/wallet-toolbox-mobile.md) | No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. | +| `@bsv/wallet-toolbox` | `2.14.5` | `2.14.7` | patch | [API and usage](../packages/wallet/wallet-toolbox.md) | No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply. | +| `@bsv/wallet-toolbox-client` | `2.14.5` | `2.14.7` | patch | [API and usage](../packages/wallet/wallet-toolbox-client.md) | No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply. | +| `@bsv/wallet-toolbox-mobile` | `2.14.5` | `2.14.7` | patch | [API and usage](../packages/wallet/wallet-toolbox-mobile.md) | No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply. | | `create-bsv-app` | `1.1.2` | `1.1.2` | none | [API and usage](../packages/helpers/create-bsv-app.md) | Existing CLI flags, network choices, and generated project structure are unchanged. Regenerate or update dependencies after the patched packages are published. Distributors must retain THIRD_PARTY_NOTICES.md and LICENSES/ with the package. | `none` means the source manifest matches the recorded npm baseline. Any other @@ -515,8 +515,8 @@ CLI entry points: `{"wallet-relay":"./bin/init.mjs"}`. - Package documentation: [docs/packages/wallet/wallet-toolbox.md](../packages/wallet/wallet-toolbox.md) - Source: [packages/wallet/wallet-toolbox](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox) -- Release note: WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Public Argon2id declarations reference the typed hash-wasm package while retaining the same generic binary/string contract and emitted runtime bytes. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. -- Migration: No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. +- Release note: WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Public Argon2id declarations reference the typed hash-wasm package while retaining the same generic binary/string contract and emitted runtime bytes. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. BEEF request data and schema-declared storage response bytes use the existing negotiated compact binary JSON encoding. Legacy peers retain numeric-array JSON, existing authentication and payload bounds, and byte-for-byte transaction/proof content. +- Migration: No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply. | Public subpath | Runtime target(s) | Declaration target(s) | | ---------------- | ---------------------------------------------------- | -------------------------- | @@ -529,8 +529,8 @@ CLI entry points: `{"wallet-relay":"./bin/init.mjs"}`. - Package documentation: [docs/packages/wallet/wallet-toolbox-client.md](../packages/wallet/wallet-toolbox-client.md) - Source: [packages/wallet/wallet-toolbox/client](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/client) -- Release note: WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. -- Migration: No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. +- Release note: WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. BEEF request data and schema-declared storage response bytes use the existing negotiated compact binary JSON encoding. Legacy peers retain numeric-array JSON, existing authentication and payload bounds, and byte-for-byte transaction/proof content. +- Migration: No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply. | Public subpath | Runtime target(s) | Declaration target(s) | | ---------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | @@ -541,8 +541,8 @@ CLI entry points: `{"wallet-relay":"./bin/init.mjs"}`. - Package documentation: [docs/packages/wallet/wallet-toolbox-mobile.md](../packages/wallet/wallet-toolbox-mobile.md) - Source: [packages/wallet/wallet-toolbox/mobile](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/mobile) -- Release note: WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. -- Migration: No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. +- Release note: WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. BEEF request data and schema-declared storage response bytes use the existing negotiated compact binary JSON encoding. Legacy peers retain numeric-array JSON, existing authentication and payload bounds, and byte-for-byte transaction/proof content. +- Migration: No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply. | Public subpath | Runtime target(s) | Declaration target(s) | | ---------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | diff --git a/governance/package-release-notes.json b/governance/package-release-notes.json index dc417956d6..a488c27c20 100644 --- a/governance/package-release-notes.json +++ b/governance/package-release-notes.json @@ -210,22 +210,22 @@ "name": "@bsv/wallet-toolbox", "publishedVersion": "2.14.5", "releaseType": "patch", - "summary": "WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Public Argon2id declarations reference the typed hash-wasm package while retaining the same generic binary/string contract and emitted runtime bytes. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged.", - "migration": "No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages." + "summary": "WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Public Argon2id declarations reference the typed hash-wasm package while retaining the same generic binary/string contract and emitted runtime bytes. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. BEEF request data and schema-declared storage response bytes use the existing negotiated compact binary JSON encoding. Legacy peers retain numeric-array JSON, existing authentication and payload bounds, and byte-for-byte transaction/proof content.", + "migration": "No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply." }, { "name": "@bsv/wallet-toolbox-client", "publishedVersion": "2.14.5", "releaseType": "patch", - "summary": "WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged.", - "migration": "No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages." + "summary": "WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. BEEF request data and schema-declared storage response bytes use the existing negotiated compact binary JSON encoding. Legacy peers retain numeric-array JSON, existing authentication and payload bounds, and byte-for-byte transaction/proof content.", + "migration": "No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply." }, { "name": "@bsv/wallet-toolbox-mobile", "publishedVersion": "2.14.5", "releaseType": "patch", - "summary": "WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged.", - "migration": "No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages." + "summary": "WalletPermissionsManager retires signed no-send ownership and reference aliases after createAction or signAction reports sending or unproven, including sendWith-only calls and successful members of an undelayed review error. Failed or unreported actions retain their originator binding for retry or abort. Cleanup visits only the retired transaction's references and preserves aliases reused by newer actions. Adds an SDK3 peer alternative while retaining the existing SDK2.8.0 floor. Fixes WAB faucet redemption for an empty wallet when storage adds a service charge. Local signer decisions for independently validated commission and derived change are retained privately through the permissions wrapper and bound by the SDK before signing. UMP pins anchor verified token-update lineage: password and token updates supersede their pinned predecessor, while unrelated historical continuations cannot override the anchor. Explicit overlay history is linked past confirmed Merkle anchors. Updates with missing pin ancestry remain indeterminate instead of selecting an unrelated continuation. Every retained token spend proves control through its unlocking script, including confirmed updates and hash rotation; funding paths do not establish token lineage. BRC-177 anchors fund both the protected action and an economic reclaim. Protected actions pay the bounded reclaim allowance surplus as fee and produce no automatically generated wallet change; ordinary change planning and its positive output cap remain unchanged. BEEF request data and schema-declared storage response bytes use the existing negotiated compact binary JSON encoding. Legacy peers retain numeric-array JSON, existing authentication and payload bounds, and byte-for-byte transaction/proof content.", + "migration": "No public API, wire, database, or consumer migration is required. Pending no-send actions and retryable failures retain the same originator-bound abort behavior; positively queued or broadcast actions no longer retain session ownership records. Upgrade the SDK to a release exposing completeBoundAction.outputAuthorizationVersion=1 alongside wallet-toolbox 2.14.6. SDK2 peers keep their existing strict behavior; they do not obtain this fee-bearing faucet fix. The main SDK3.1 candidate retains the separate SDK3 retirement migration; SDK2 hosts require a coordinated additive backport or that migration. Serialized or cross-package-instance result adapters discard local authority and fail closed. Signup interruption/retry persistence is unchanged; reconcile any previous faucet transaction before repeating a failed signup. No API or schema migration is required for pin continuity. Retire a support pin only after unpinned lookup independently returns the verified current token. Deploy overlay 2.6.4 plus overlay-topics 2.0.1 or an equivalent history decider for confirmed ancestry. Stored WAB pins remain lineage anchors; the client follows verified descendants without needing an administrative pin rewrite. No API, wire or database migration is required for the BRC-177 funding fix. A protected action can pay the difference between its delivery need and the reclaim floor as miner fee. Funding/reclaim fees remain the wallet owner's responsibility; upgrade the active storage implementation as well as client packages. No API, database or peer migration is required for compact BEEF transport. Upgrade clients and active storage to obtain both request and response savings; older peers retain ordinary JSON. Existing payload ceilings still apply." }, { "name": "create-bsv-app", diff --git a/packages/wallet/wallet-toolbox/CHANGELOG.md b/packages/wallet/wallet-toolbox/CHANGELOG.md index efb9ca8d76..9d1a2e14cf 100644 --- a/packages/wallet/wallet-toolbox/CHANGELOG.md +++ b/packages/wallet/wallet-toolbox/CHANGELOG.md @@ -6,6 +6,11 @@ attention to changes that materially alter behavior or extend functionality. ## wallet-toolbox 2.14.7 +- BEEF requests and schema-declared storage response bytes use the existing + negotiated compact binary JSON codec. Legacy peers retain numeric-array + JSON and identical transaction/proof bytes. Existing authentication and + payload ceilings remain unchanged; no API or database migration is required. + - BRC-177 anchors cover both the protected action and an economic reclaim. Protected actions keep their only managed input bound to the named anchor, create no wallet change, and pay the bounded reclaim surplus as miner fee. diff --git a/packages/wallet/wallet-toolbox/src/signer/methods/__tests/internalizeAction.storageArgs.test.ts b/packages/wallet/wallet-toolbox/src/signer/methods/__tests/internalizeAction.storageArgs.test.ts new file mode 100644 index 0000000000..ddca7b0fe0 --- /dev/null +++ b/packages/wallet/wallet-toolbox/src/signer/methods/__tests/internalizeAction.storageArgs.test.ts @@ -0,0 +1,49 @@ +import { Beef, MerklePath, Script, Transaction, UnlockingScript } from '@bsv/sdk' +import { internalizeAction } from '../internalizeAction' +import type { Wallet } from '../../../Wallet' +import { stringifyJsonRpc } from '../../../storage/remoting/BinaryJson' + +describe('signer internalizeAction storage arguments', () => { + test('passes the AtomicBEEF to storage as bytes so negotiated binary JSON carries it compactly', async () => { + const tx = new Transaction() + tx.addInput({ sourceTXID: '00'.repeat(32), sourceOutputIndex: 0, unlockingScript: new UnlockingScript() }) + tx.addOutput({ satoshis: 1000, lockingScript: Script.fromHex('51') }) + const txid = tx.id('hex') + const beef = new Beef() + beef.mergeBump(new MerklePath(800000, [[{ offset: 0, hash: txid, txid: true }]])) + beef.mergeTransaction(tx) + + const received: unknown[] = [] + const wallet = { + getServices: () => ({ getChainTracker: async () => ({ isValidRootForHeight: async () => true }) }), + storage: { + internalizeAction: async (args: unknown) => { + received.push(args) + return { accepted: true, isMerge: false, txid, satoshis: 0 } + } + } + } as unknown as Wallet + + await internalizeAction( + wallet, + { identityKey: `02${'11'.repeat(32)}`, userId: 1 }, + { + tx: beef.toBinaryAtomic(txid), + outputs: [ + { + outputIndex: 0, + protocol: 'basket insertion', + insertionRemittance: { basket: 'tokens', tags: [] } + } + ], + description: 'internalize as bytes' + } + ) + + const sent = received[0] as { tx: unknown } + expect(sent.tx).toBeInstanceOf(Uint8Array) + expect(Array.from(sent.tx as Uint8Array)).toEqual(beef.toBinaryAtomic(txid)) + const wire = JSON.parse(stringifyJsonRpc({ params: [sent] }, true)) + expect(wire.params[0].tx.$bsvBinary).toBe('base64') + }) +}) diff --git a/packages/wallet/wallet-toolbox/src/signer/methods/internalizeAction.ts b/packages/wallet/wallet-toolbox/src/signer/methods/internalizeAction.ts index d4c5a3aba8..28fd7bf912 100644 --- a/packages/wallet/wallet-toolbox/src/signer/methods/internalizeAction.ts +++ b/packages/wallet/wallet-toolbox/src/signer/methods/internalizeAction.ts @@ -71,7 +71,7 @@ export async function internalizeAction( const r: StorageInternalizeActionResult = await wallet.storage.internalizeAction({ ...args, - tx: ab.toBinaryAtomic(txid) + tx: ab.toUint8ArrayAtomic(txid) }) return r diff --git a/packages/wallet/wallet-toolbox/src/storage/methods/createAction.ts b/packages/wallet/wallet-toolbox/src/storage/methods/createAction.ts index fd15d728f2..7270e470cc 100644 --- a/packages/wallet/wallet-toolbox/src/storage/methods/createAction.ts +++ b/packages/wallet/wallet-toolbox/src/storage/methods/createAction.ts @@ -445,10 +445,11 @@ async function buildSdkInputFromOutput( unlockLen: number | undefined ): Promise { if (i == null && !unlockLen) throw new WERR_INTERNAL(`vin ${vin} non-fixedInput without unlockLen`) - const sourceTransaction = + const sourceRawTx = vargs.includeAllSourceTransactions && vargs.isSignAction ? await storage.getRawTxOfKnownValidTransaction(o.txid) : undefined + const sourceTransaction = sourceRawTx == null ? undefined : Uint8Array.from(sourceRawTx) return { vin, sourceTxid: o.txid!, diff --git a/packages/wallet/wallet-toolbox/src/storage/methods/listOutputsKnex.ts b/packages/wallet/wallet-toolbox/src/storage/methods/listOutputsKnex.ts index 3dd8d39f99..4f652e1f36 100644 --- a/packages/wallet/wallet-toolbox/src/storage/methods/listOutputsKnex.ts +++ b/packages/wallet/wallet-toolbox/src/storage/methods/listOutputsKnex.ts @@ -334,6 +334,6 @@ export async function listOutputs( await hydrateKnexWalletOutput(dsk, output, vargs, labelsByTransactionId, tagsByOutputId, beef, trx) ) } - if (vargs.includeTransactions) result.BEEF = beef.toBinary() + if (vargs.includeTransactions) result.BEEF = beef.toUint8Array() return result } diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/StorageClientBase.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/StorageClientBase.ts index bb326b5b10..2f75c0efb1 100644 --- a/packages/wallet/wallet-toolbox/src/storage/remoting/StorageClientBase.ts +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/StorageClientBase.ts @@ -95,6 +95,12 @@ import { pruneBeefForTxids } from '../../utility/beefForTxids' const syncChunkResponseRetryLimit = 4 const minimumSyncChunkRoughSize = 64 * 1024 +/** Hold proof data as bytes so negotiated binary JSON carries it compactly. */ +function withBeefBytes(args: T): T { + if (args.inputBEEF == null || args.inputBEEF instanceof Uint8Array) return args + return { ...args, inputBEEF: Uint8Array.from(args.inputBEEF) } +} + function isSyncChunkResponseTooLarge(error: unknown): boolean { return error instanceof Error && /WalletStorageClient rpcCall: network error 413(?:\s|$)/.test(error.message) } @@ -499,13 +505,13 @@ export abstract class StorageClientBase implements WalletStorageProvider { if (pruned != null) { args = { ...args, - inputBEEF: pruned.toBinary() + inputBEEF: pruned.toUint8Array() } } } } } - return await this.rpcCall('createAction', [auth, args]) + return await this.rpcCall('createAction', [auth, withBeefBytes(args)]) } /** @@ -523,14 +529,17 @@ export abstract class StorageClientBase implements WalletStorageProvider { } async prepareNoSendExpiry(auth: AuthId, args: ValidCreateActionArgs): Promise { - return await this.rpcCall('prepareNoSendExpiry', [auth, args]) + return await this.rpcCall('prepareNoSendExpiry', [auth, withBeefBytes(args)]) } async activateNoSendExpiry( auth: AuthId, args: StorageActivateNoSendExpiryArgs ): Promise { - return await this.rpcCall('activateNoSendExpiry', [auth, args]) + return await this.rpcCall('activateNoSendExpiry', [ + auth, + { ...args, target: withBeefBytes(args.target) } + ]) } async armNoSendExpiry(auth: AuthId, args: StorageArmNoSendExpiryArgs): Promise { diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/StorageServer.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/StorageServer.ts index 8ff0ceeb89..51306cd04a 100644 --- a/packages/wallet/wallet-toolbox/src/storage/remoting/StorageServer.ts +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/StorageServer.ts @@ -7,7 +7,7 @@ import { SYNC_TRANSFER_MAX_BYTES, SYNC_TRANSFER_PART_BYTES } from './SyncTransfer' -import { syncChunkBinary } from './syncChunkBinary' +import { syncChunkBinary, tableRowsBinary } from './syncChunkBinary' /** * StorageServer.ts * @@ -186,11 +186,23 @@ const pagedLimitArgument = new Map([ ['findProvenTxReqs', 0] ]) +const binaryRowResults = new Map([ + ['findOutputsAuth', 'outputs'], + ['findProvenTxReqs', 'provenTxReqs'] +]) + interface RpcDispatchResult { found: boolean result?: unknown } +/** Copy a result's schema-defined byte fields for the already negotiated binary JSON codec. */ +function binaryRpcResult(method: string, result: unknown): unknown { + if (method === 'getSyncChunk') return syncChunkBinary(result as SyncChunk) + const table = binaryRowResults.get(method) + return table != null && Array.isArray(result) ? tableRowsBinary(table, result) : result +} + function requiredAuthenticatedIdentityKey(req: Request): string { const identityKey = (req as AuthRequest).auth?.identityKey if (typeof identityKey !== 'string' || identityKey.trim() === '' || identityKey === 'unknown') { @@ -656,8 +668,7 @@ export class StorageServer { 400 ) } - const result = - useBinary && method === 'getSyncChunk' ? syncChunkBinary(dispatch.result as SyncChunk) : dispatch.result + const result = useBinary ? binaryRpcResult(method, dispatch.result) : dispatch.result // JSON-RPC success responses must carry a result member. Preserve an // explicit null for void storage methods rather than letting // JSON.stringify silently omit an undefined result. diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClientBase.inputBeef.test.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClientBase.inputBeef.test.ts index 4c67dbcbda..bd7ab23aa9 100644 --- a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClientBase.inputBeef.test.ts +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageClientBase.inputBeef.test.ts @@ -1,5 +1,6 @@ import { BEEF_V1, Beef, Script, Transaction, UnlockingScript, Validation, type WalletInterface } from '@bsv/sdk' import { StorageClientBase } from '../StorageClientBase' +import { parseJsonRpc, stringifyJsonRpc } from '../BinaryJson' class CapturingStorageClient extends StorageClientBase { calls: Array<{ method: string; params: unknown[] }> = [] @@ -93,8 +94,119 @@ describe('StorageClientBase createAction inputBEEF pruning', () => { await client.createAction(auth, args) const sentArgs = client.calls[0].params[1] as Validation.ValidCreateActionArgs - expect(sentArgs).toBe(args) - expect(sentArgs.inputBEEF).toBe(originalBytes) + expect(sentArgs.inputBEEF).toBeInstanceOf(Uint8Array) + expect(Array.from(sentArgs.inputBEEF!)).toEqual(Array.from(originalBytes!)) + expect(args.inputBEEF).toBe(originalBytes) + }) + + test('passes inputBEEF that is already bytes through unchanged', async () => { + const required = makeTransaction(1000) + const beef = new Beef() + beef.mergeTransaction(required) + const args = Validation.validateCreateActionArgs({ + description: 'forward byte proof data', + inputs: [ + { + outpoint: `${required.id('hex')}.0`, + unlockingScript: '00', + inputDescription: 'declared byte input' + } + ], + inputBEEF: beef.toUint8Array(), + outputs: [{ satoshis: 1, lockingScript: '51', outputDescription: 'replacement output' }] + }) + const client = new CapturingStorageClient({} as WalletInterface, 'https://storage.example.test') + + await client.createAction(auth, args) + + expect(client.calls[0].params[1]).toBe(args) + }) + + test('sends pruned inputBEEF as bytes that negotiated binary JSON tags', async () => { + const required = makeTransaction(1000) + const beef = new Beef() + beef.mergeTransaction(required) + beef.mergeTransaction(makeTransaction(2000)) + const args = Validation.validateCreateActionArgs({ + description: 'prune and send bytes', + inputs: [ + { + outpoint: `${required.id('hex')}.0`, + unlockingScript: '00', + inputDescription: 'declared input' + } + ], + inputBEEF: beef.toBinary(), + outputs: [{ satoshis: 1, lockingScript: '51', outputDescription: 'replacement output' }] + }) + const client = new CapturingStorageClient({} as WalletInterface, 'https://storage.example.test') + + await client.createAction(auth, args) + + const sentArgs = client.calls[0].params[1] as Validation.ValidCreateActionArgs + expect(sentArgs.inputBEEF).toBeInstanceOf(Uint8Array) + const wire = JSON.parse(stringifyJsonRpc({ params: client.calls[0].params }, true)) + expect(wire.params[1].inputBEEF.$bsvBinary).toBe('base64') + }) + + test('sends no-send expiry inputBEEF as bytes', async () => { + const required = makeTransaction(1000) + const beef = new Beef() + beef.mergeTransaction(required) + const target = Validation.validateCreateActionArgs({ + description: 'expiry target with proof data', + inputs: [ + { + outpoint: `${required.id('hex')}.0`, + unlockingScript: '00', + inputDescription: 'declared input' + } + ], + inputBEEF: beef.toBinary(), + outputs: [{ satoshis: 1, lockingScript: '51', outputDescription: 'replacement output' }] + }) + const client = new CapturingStorageClient({} as WalletInterface, 'https://storage.example.test') + + await client.prepareNoSendExpiry(auth, target) + await client.activateNoSendExpiry(auth, { + target, + fundingReference: 'ref', + fundingTxid: '33'.repeat(32), + anchorVout: 0 + }) + + expect((client.calls[0].params[1] as Validation.ValidCreateActionArgs).inputBEEF).toBeInstanceOf(Uint8Array) + expect((client.calls[1].params[1] as { target: Validation.ValidCreateActionArgs }).target.inputBEEF).toBeInstanceOf( + Uint8Array + ) + expect(target.inputBEEF).not.toBeInstanceOf(Uint8Array) + }) + + test.each([false, true])('preserves a large BEEF request with binary negotiation %s', async binary => { + const required = makeTransaction(1000) + required.addOutput({ satoshis: 0, lockingScript: Script.fromASM(`OP_FALSE OP_RETURN ${'ff'.repeat(150_000)}`) }) + const beef = new Beef() + beef.mergeTransaction(required) + const originalBytes = beef.toBinary() + const args = Validation.validateCreateActionArgs({ + description: 'forward large proof data', + inputs: [{ outpoint: `${required.id('hex')}.0`, unlockingScript: '00', inputDescription: 'large input' }], + inputBEEF: originalBytes, + outputs: [{ satoshis: 1, lockingScript: '51', outputDescription: 'replacement output' }] + }) + const client = new CapturingStorageClient({} as WalletInterface, 'https://storage.example.test') + await client.createAction(auth, args) + const envelope = { jsonrpc: '2.0', method: 'createAction', params: client.calls[0].params, id: 1 } + const wire = stringifyJsonRpc(envelope, binary) + const decoded = parseJsonRpc(wire, binary).params[1].inputBEEF + expect(Array.from(decoded)).toEqual(originalBytes) + expect(args.inputBEEF).toEqual(originalBytes) + if (binary) { + expect(JSON.parse(wire).params[1].inputBEEF.$bsvBinary).toBe('base64') + expect(Buffer.byteLength(wire)).toBeLessThan(Buffer.byteLength(stringifyJsonRpc(envelope, false)) / 2) + } else { + expect(JSON.parse(wire).params[1].inputBEEF).toEqual(originalBytes) + } }) test('preserves BEEF V1 when client-side pruning is required', async () => { diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageServerRpc.test.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageServerRpc.test.ts index f39dc49649..8399932766 100644 --- a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageServerRpc.test.ts +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/StorageServerRpc.test.ts @@ -1,5 +1,5 @@ import { parseJsonRpc } from '../BinaryJson' -import { validateSyncChunkEntities } from '../entityValidationHelpers' +import { validateEntities, validateSyncChunkEntities } from '../entityValidationHelpers' import { type Request, type Response } from 'express' import { TelemetryEvent, WalletLoggerInterface, Transaction, Script, MerklePath } from '@bsv/sdk' import { toBinaryBaseBlockHeader } from '../../../services/Services' @@ -178,6 +178,69 @@ describe('StorageServer JSON-RPC boundary', () => { expect(chunk.provenTxs[0].rawTx).toBe(bytes) }) + test.each([false, true])('encodes only declared row bytes when binary is negotiated: %s', async binary => { + const bytes = Array.from({ length: 2048 }, (_, i) => i % 256) + const time = { created_at: new Date(), updated_at: new Date() } + const outputs = [{ ...time, outputId: 1, lockingScript: bytes, extraNumbers: bytes }] + const reqs = [{ ...time, provenTxReqId: 1, rawTx: bytes, inputBEEF: bytes, extraNumbers: bytes }] + const server = makeServer({ findOutputsAuth: async () => outputs, findProvenTxReqsAuth: async () => reqs }) + for (const { method, params, rows, fields } of [ + { + method: 'findOutputsAuth', + params: [{ identityKey: 'alice' }, { partial: {} }], + rows: outputs, + fields: ['lockingScript'] + }, + { method: 'findProvenTxReqs', params: [{ partial: {} }], rows: reqs, fields: ['rawTx', 'inputBEEF'] } + ]) { + const captured = makeResponse() + await invoke( + server, + 'handleRpcRequest', + makeRequest( + { jsonrpc: '2.0', method, params, id: 1 }, + binary ? { [BINARY_ENCODING_HEADER]: BINARY_ENCODING } : {} + ), + captured.response + ) + expect(captured.statusCode).toBe(200) + for (const field of fields) { + if (binary) expect(captured.body.result[0][field].$bsvBinary).toBe('base64') + else expect(captured.body.result[0][field]).toEqual(bytes) + } + expect(captured.body.result[0].extraNumbers).toEqual(bytes) + expect(validateEntities(parseJsonRpc(JSON.stringify(captured.body), binary).result)).toEqual(rows) + } + expect(outputs[0].lockingScript).toBe(bytes) + expect(reqs[0].rawTx).toBe(bytes) + }) + + test.each([false, true])( + 'retains the response ceiling for large row bytes with binary negotiation %s', + async binary => { + const bytes = Array.from({ length: 150_000 }, (_, i) => i % 256) + const now = new Date() + const rows = [{ provenTxReqId: 1, rawTx: bytes, created_at: now, updated_at: now }] + const server = makeServer({ findProvenTxReqsAuth: async () => rows }, { maxRpcResponseBytes: 300_000 }) + const captured = makeResponse() + await invoke( + server, + 'handleRpcRequest', + makeRequest( + { jsonrpc: '2.0', method: 'findProvenTxReqs', params: [{ partial: {} }], id: 1 }, + binary ? { [BINARY_ENCODING_HEADER]: BINARY_ENCODING } : {} + ), + captured.response + ) + expect(captured.statusCode).toBe(binary ? 200 : 413) + if (binary) { + expect(validateEntities(parseJsonRpc(JSON.stringify(captured.body), true).result)).toEqual(rows) + expect(Buffer.byteLength(JSON.stringify(captured.body))).toBeLessThan(300_000) + } + expect(rows[0].rawTx).toBe(bytes) + } + ) + test('accounts for HTML escaping when enforcing the response-size ceiling', async () => { const server = makeServer({ getSettings: () => ({ value: '<'.repeat(25) }) }, { maxRpcResponseBytes: 100 }) const captured = makeResponse() diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/__test/tableRowsBinary.test.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/tableRowsBinary.test.ts new file mode 100644 index 0000000000..144c231afe --- /dev/null +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/__test/tableRowsBinary.test.ts @@ -0,0 +1,26 @@ +import { tableRowsBinary } from '../syncChunkBinary' +import { parseJsonRpc, stringifyJsonRpc } from '../BinaryJson' + +describe('schema-defined row bytes', () => { + test('copies large declared byte fields without mutating rows or tagging unrelated numbers', () => { + const bytes = Array.from({ length: 128 }, (_, i) => i) + const row = { rawTx: bytes, inputBEEF: bytes, extraNumbers: bytes } + const result = tableRowsBinary('provenTxReqs', [row]) + const wire = JSON.parse(stringifyJsonRpc(result, true)) + expect(wire[0].rawTx.$bsvBinary).toBe('base64') + expect(wire[0].inputBEEF.$bsvBinary).toBe('base64') + expect(wire[0].extraNumbers).toEqual(bytes) + expect(Array.from(parseJsonRpc(JSON.stringify(wire), true)[0].rawTx)).toEqual(bytes) + expect(row.rawTx).toBe(bytes) + expect(result[0]).not.toBe(row) + }) + + test.each([undefined, new Uint8Array(128), [1, 2], Array(128).fill(-1), Array(128).fill(256), Array(128).fill(1.5)])( + 'preserves absent, typed, small or invalid declared bytes: %p', + value => { + const row = { lockingScript: value } + expect(tableRowsBinary('outputs', [row])[0].lockingScript).toBe(value) + expect(row.lockingScript).toBe(value) + } + ) +}) diff --git a/packages/wallet/wallet-toolbox/src/storage/remoting/syncChunkBinary.ts b/packages/wallet/wallet-toolbox/src/storage/remoting/syncChunkBinary.ts index b632d31b89..728e42abc8 100644 --- a/packages/wallet/wallet-toolbox/src/storage/remoting/syncChunkBinary.ts +++ b/packages/wallet/wallet-toolbox/src/storage/remoting/syncChunkBinary.ts @@ -16,19 +16,26 @@ function isLargeByteArray(value: unknown): value is number[] { return true } +/** Copy one table's schema-defined byte fields for the already negotiated binary JSON codec. */ +export function tableRowsBinary( + table: keyof typeof binaryFields, + rows: Array> +): Array> { + return rows.map(row => { + const copy = { ...row } + for (const field of binaryFields[table]) { + if (isLargeByteArray(copy[field])) copy[field] = Uint8Array.from(copy[field]) + } + return copy + }) +} + /** Copy schema-defined byte fields for the already negotiated binary JSON codec. */ export function syncChunkBinary(chunk: SyncChunk): Record { const result: Record = { ...chunk } - for (const [name, fields] of Object.entries(binaryFields)) { + for (const name of Object.keys(binaryFields) as Array) { const rows: unknown = Reflect.get(chunk, name) - if (!Array.isArray(rows)) continue - result[name] = rows.map((row: Record) => { - const copy = { ...row } - for (const field of fields) { - if (isLargeByteArray(copy[field])) copy[field] = Uint8Array.from(copy[field]) - } - return copy - }) + if (Array.isArray(rows)) result[name] = tableRowsBinary(name, rows) } return result } diff --git a/packages/wallet/wallet-toolbox/test/wallet/list/listOutputs.test.ts b/packages/wallet/wallet-toolbox/test/wallet/list/listOutputs.test.ts index 22206d3144..872752e06a 100644 --- a/packages/wallet/wallet-toolbox/test/wallet/list/listOutputs.test.ts +++ b/packages/wallet/wallet-toolbox/test/wallet/list/listOutputs.test.ts @@ -4,8 +4,10 @@ import { ListOutputsArgs, OriginatorDomainNameStringUnder250Bytes, OutputTagStringUnder300Bytes, + Validation, WalletOutput } from '@bsv/sdk' +import { StorageKnex } from '../../../src/storage/StorageKnex' import { _tu, TestWalletProviderNoSetup } from '../../utils/TestUtilsWalletStorage' import path from 'node:path' @@ -257,6 +259,16 @@ describe('listOutputs test', () => { } }) + test('8b_BEEF from Knex storage is bytes so negotiated binary JSON carries it compactly', async () => { + for (const { storage } of ctxs) { + if (!(storage.getActive() instanceof StorageKnex)) continue + const vargs = Validation.validateListOutputsArgs({ basket: 'default', include: 'entire transactions' }) + const r = await storage.listOutputs(vargs) + expect(r.BEEF).toBeInstanceOf(Uint8Array) + expect(Beef.fromBinary(r.BEEF!).txs.length).toBeGreaterThan(0) + } + }) + test('9_labels for babbage_protocol_perm', async () => { for (const { wallet } of ctxs) { {