diff --git a/docs/packages/wallet/wallet-toolbox-client.md b/docs/packages/wallet/wallet-toolbox-client.md index 135b7b7fc..853dee0de 100644 --- a/docs/packages/wallet/wallet-toolbox-client.md +++ b/docs/packages/wallet/wallet-toolbox-client.md @@ -3,7 +3,7 @@ id: pkg-wallet-toolbox-client title: '@bsv/wallet-toolbox-client' kind: package domain: wallet -version: '2.6.0' +version: '2.6.1' last_updated: '2026-08-05' last_verified: '2026-08-05' review_cadence_days: 30 diff --git a/docs/packages/wallet/wallet-toolbox-mobile.md b/docs/packages/wallet/wallet-toolbox-mobile.md index 94b6e2c76..42675d84d 100644 --- a/docs/packages/wallet/wallet-toolbox-mobile.md +++ b/docs/packages/wallet/wallet-toolbox-mobile.md @@ -3,7 +3,7 @@ id: pkg-wallet-toolbox-mobile title: '@bsv/wallet-toolbox-mobile' kind: package domain: wallet -version: '2.6.0' +version: '2.6.1' last_updated: '2026-08-05' last_verified: '2026-08-05' review_cadence_days: 30 diff --git a/docs/packages/wallet/wallet-toolbox.md b/docs/packages/wallet/wallet-toolbox.md index e5ee0f2cf..f11b087e3 100644 --- a/docs/packages/wallet/wallet-toolbox.md +++ b/docs/packages/wallet/wallet-toolbox.md @@ -4,7 +4,7 @@ title: '@bsv/wallet-toolbox' kind: package domain: wallet npm: '@bsv/wallet-toolbox' -version: '2.6.0' +version: '2.6.1' last_updated: '2026-08-05' last_verified: '2026-08-05' review_cadence_days: 30 diff --git a/docs/reference/package-api-migrations.md b/docs/reference/package-api-migrations.md index fcaccc736..033ce1fab 100644 --- a/docs/reference/package-api-migrations.md +++ b/docs/reference/package-api-migrations.md @@ -23,39 +23,39 @@ and clean-consumer tests remain the executable type authority. ## Current release boundary -| Package | npm baseline | Source | Candidate | API | Migration | -| --------------------------------- | ------------ | ------- | --------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `@bsv/402-pay` | `0.2.1` | `0.2.4` | patch | [API and usage](../packages/middleware/402-pay.md) | No consumer migration is required; client and server exports, payment protocol behavior, and runtime defaults are unchanged. | -| `@bsv/air-gap` | `0.0.0` | `0.1.1` | minor | [API and usage](../packages/helpers/air-gap.md) | No consumer migration is required; this is the first published release of a new package with no prior public API. The experimental pre-release framing that circulated on the unmerged feature branch is not accepted by the v1 decoder. | -| `@bsv/amountinator` | `2.1.1` | `2.1.4` | patch | [API and usage](../packages/helpers/amountinator.md) | No consumer migration is required; this is a backward-compatible patch candidate. | -| `@bsv/auth` | `0.1.1` | `0.1.3` | patch | [API and usage](../packages/middleware/auth.md) | No consumer migration is required; authentication APIs, wire behavior, and runtime defaults are unchanged. | -| `@bsv/auth-express-middleware` | `2.1.2` | `2.2.0` | minor | [API and usage](../packages/middleware/auth-express-middleware.md) | Existing middleware construction remains compatible. Operators may set transportLimits.maxResponseBytes to a positive byte count or -1 when the embedding service enforces an equivalent response budget. | -| `@bsv/authsocket` | `2.1.1` | `2.1.5` | patch | [API and usage](../packages/messaging/authsocket.md) | Valid traffic and the wire contract are unchanged. A socket is now disconnected when its authentication processing exceeds the concurrency limit or a callback fails; use onError for diagnostics and maxPendingAuthMessages to tune the default limit of 32. | -| `@bsv/authsocket-client` | `2.1.1` | `2.1.4` | patch | [API and usage](../packages/messaging/authsocket-client.md) | Valid traffic and supported imports are unchanged. The client now disconnects from a server that causes authentication failure or exceeds the concurrency limit; use onError for diagnostics and maxPendingAuthMessages to tune the default limit of 32. | -| `@bsv/btms` | `1.1.1` | `1.1.4` | patch | [API and usage](../packages/wallet/btms.md) | No consumer migration is required; token and lookup wire contracts are unchanged. | -| `@bsv/btms-permission-module` | `1.1.1` | `1.1.3` | patch | [API and usage](../packages/wallet/btms-permission-module.md) | No consumer migration is required; permission-module APIs and token semantics are unchanged. | -| `@bsv/did` | `0.2.1` | `0.2.4` | patch | [API and usage](../packages/helpers/did.md) | No consumer migration is required; DID APIs, encodings, credential behavior, and supported import forms are unchanged. | -| `@bsv/did-client` | `1.2.1` | `1.2.3` | patch | [API and usage](../packages/helpers/did-client.md) | No consumer migration is required; DID client APIs, encodings, and supported imports are unchanged. | -| `@bsv/fund-wallet` | `1.4.1` | `1.4.3` | patch | [API and usage](../packages/helpers/fund-wallet.md) | No consumer migration is required; wallet funding APIs and transaction behavior are unchanged. | -| `@bsv/gasp` | `1.3.1` | `1.3.5` | patch | [API and usage](../packages/overlays/gasp.md) | No consumer migration is required; existing constructor calls, imports, synchronization behavior, and wire semantics are unchanged. | -| `@bsv/message-box-client` | `2.2.2` | `2.3.0` | minor | [API and usage](../packages/messaging/message-box-client.md) | Existing listMessages and listMessagesLite calls continue to fetch all available messages. Applications that need an aggregate memory ceiling should set limit and/or maxPages; no additional BRC-105 approval callback is required because AuthFetch uses wallet permissions. | -| `@bsv/overlay` | `2.2.1` | `2.3.0` | minor | [API and usage](../packages/overlays/overlay.md) | Existing Engine constructor calls remain valid and default to 1,000 lookup formulas. Pass -1 as the final maxLookupResults argument only when a custom lookup service and deployment enforce an equivalent bound. | -| `@bsv/overlay-discovery-services` | `2.1.1` | `2.1.6` | patch | [API and usage](../packages/overlays/overlay-discovery-services.md) | No consumer migration is required; discovery records and public network behavior are unchanged. | -| `@bsv/overlay-express` | `2.4.2` | `2.5.0` | minor | [API and usage](../packages/overlays/overlay-express.md) | The standard profile is selected by default. Existing configuration methods remain compatible; use OVERLAY_RESOURCE_PROFILE or granular OVERLAY_* limits, and ensure custom lookup services bound their own database queries before returning formulas. | -| `@bsv/overlay-topics` | `1.6.1` | `1.6.8` | patch | [API and usage](../packages/overlays/overlay-topics.md) | No consumer migration is required; topic IDs, lookup contracts, and persisted formats are unchanged. | -| `@bsv/paymail` | `2.4.2` | `2.4.6` | patch | [API and usage](../packages/messaging/paymail.md) | Existing Paymail client APIs and protocol semantics are retained. Consumers provide one Express 4.18 or 5 runtime and matching type graph; browser bundles continue to exclude the server router implementation. | -| `@bsv/payment-express-middleware` | `2.1.1` | `2.1.5` | patch | [API and usage](../packages/middleware/payment-express-middleware.md) | No consumer migration is required; legacy x-bsv-payment JSON behavior remains supported, and Express 4 and 5 applications use their own peer-provided Express installation. | -| `@bsv/sdk` | `2.2.18` | `2.3.0` | minor | [API and usage](../packages/sdk/bsv-sdk.md) | No consumer migration is required. The new APIs are additive; BEEF ordering and bytes, proof validity, signatures, synchronous signing, SDK 2.x wire encodings, BRC-103/104 behavior, and supported imports are unchanged. | -| `@bsv/simple` | `0.4.1` | `0.4.8` | patch | [API and usage](../packages/helpers/simple.md) | No consumer migration is required; the browser and server entry points remain compatible. | -| `@bsv/templates` | `1.9.1` | `1.9.6` | patch | [API and usage](../packages/helpers/templates.md) | No consumer migration is required; template APIs, supported imports, and generated script semantics are unchanged. | -| `@bsv/teranode-listener` | `1.1.1` | `1.1.4` | patch | [API and usage](../packages/network/teranode-listener.md) | No consumer migration is required; listener APIs, topics, and network configuration are unchanged. | -| `@bsv/verifast` | `0.3.0` | `0.3.4` | patch | [API and usage](../packages/sdk/verifast.md) | No consumer migration is required; exports, verification behavior, worker protocols, package paths, and runtime defaults are unchanged. | -| `@bsv/wallet-helper` | `0.1.1` | `0.1.6` | patch | [API and usage](../packages/helpers/wallet-helper.md) | No consumer migration is required; fluent builder APIs and transaction semantics are unchanged. | -| `@bsv/wallet-relay` | `0.2.2` | `0.3.4` | minor | [API and usage](../packages/wallet/wallet-relay.md) | QRPairingCode now renders a native button and accepts button wrapper attributes. Existing className, style, data, and ARIA props continue to work; update div-specific wrapper selectors or explicitly typed div event handlers. Express integrations now use the host application's matching Express runtime and type graph. | -| `@bsv/wallet-toolbox` | `2.5.0` | `2.6.0` | minor | [API and usage](../packages/wallet/wallet-toolbox.md) | List/find RPC calls that omit a limit now receive the profile default (1,000 in standard), and larger caller limits are rejected above the operator maximum. Existing calls and storage data remain compatible; migrations add auth_sessions, payment_replays, and createAction indexes automatically, and storage-provider additions retain backward-compatible fallbacks. Applications may now enter new-user flow when at least one overlay host returns a clean empty result despite malformed or unavailable peers; one verified token still establishes an existing account, multiple unresolved verified tokens remain an error, and WAB existing-account continuity still blocks replacement-wallet onboarding. The default ChainTracks client for mainnet, testnet, and TerraTestNet now uses each public Arcade v2 endpoint without a credential; explicit ChaintracksClientApi injection and legacy v1 URLs remain supported. STN and Terra Scaling TestNet require an explicit STN_CHAINTRACKS_URL/TSTN_CHAINTRACKS_URL or corresponding Arcade URL. A WhatsOnChain key is optional, anonymous fallback stays below the documented public rate, and ChainTracks header/info requests retry anonymously when a configured key is rejected. Browser/mobile CORS expectations, wallet results, BRC-103/104, AuthFetch, JSON-RPC, and wallet wire behavior are otherwise unchanged. | -| `@bsv/wallet-toolbox-client` | `2.5.0` | `2.6.0` | minor | [API and usage](../packages/wallet/wallet-toolbox-client.md) | No browser consumer migration is required. Remote storage callers may provide explicit list limits when they need a value other than the operator profile default, and browser wallets receive the resilient partial-host UMP lookup behavior described for @bsv/wallet-toolbox. Mainnet, testnet, and TerraTestNet ChainTracks defaults now use public credential-free Arcade v2 endpoints; explicit clients and legacy v1 URLs remain compatible, while STN and Terra Scaling TestNet require an explicit endpoint. Older compatible SDK peers retain the validated sequential proof fallback, IndexedDB upgrades automatically, and CORS, BRC-103/104, AuthFetch, browser entry points, JSON-RPC, and remote storage wire behavior remain compatible. | -| `@bsv/wallet-toolbox-mobile` | `2.5.0` | `2.6.0` | minor | [API and usage](../packages/wallet/wallet-toolbox-mobile.md) | No mobile consumer migration is required. Remote storage callers may provide explicit list limits when they need a value other than the operator profile default, and mobile wallets receive the resilient partial-host UMP lookup behavior described for @bsv/wallet-toolbox. Mainnet, testnet, and TerraTestNet ChainTracks defaults now use public credential-free Arcade v2 endpoints; explicit clients and legacy v1 URLs remain compatible, while STN and Terra Scaling TestNet require an explicit endpoint. Older compatible SDK peers retain the validated sequential proof fallback, and BRC-103/104, AuthFetch, React Native, the mobile bridge, JSON-RPC, and remote storage wire behavior remain compatible. | -| `create-bsv-app` | `1.0.2` | `1.0.4` | patch | [API and usage](../packages/helpers/create-bsv-app.md) | No consumer migration is required; generated application structure and CLI behavior are unchanged. | +| Package | npm baseline | Source | Candidate | API | Migration | +| --------------------------------- | ------------ | ------- | --------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `@bsv/402-pay` | `0.2.1` | `0.2.4` | patch | [API and usage](../packages/middleware/402-pay.md) | No consumer migration is required; client and server exports, payment protocol behavior, and runtime defaults are unchanged. | +| `@bsv/air-gap` | `0.0.0` | `0.1.1` | minor | [API and usage](../packages/helpers/air-gap.md) | No consumer migration is required; this is the first published release of a new package with no prior public API. The experimental pre-release framing that circulated on the unmerged feature branch is not accepted by the v1 decoder. | +| `@bsv/amountinator` | `2.1.1` | `2.1.4` | patch | [API and usage](../packages/helpers/amountinator.md) | No consumer migration is required; this is a backward-compatible patch candidate. | +| `@bsv/auth` | `0.1.1` | `0.1.3` | patch | [API and usage](../packages/middleware/auth.md) | No consumer migration is required; authentication APIs, wire behavior, and runtime defaults are unchanged. | +| `@bsv/auth-express-middleware` | `2.1.2` | `2.2.0` | minor | [API and usage](../packages/middleware/auth-express-middleware.md) | Existing middleware construction remains compatible. Operators may set transportLimits.maxResponseBytes to a positive byte count or -1 when the embedding service enforces an equivalent response budget. | +| `@bsv/authsocket` | `2.1.1` | `2.1.5` | patch | [API and usage](../packages/messaging/authsocket.md) | Valid traffic and the wire contract are unchanged. A socket is now disconnected when its authentication processing exceeds the concurrency limit or a callback fails; use onError for diagnostics and maxPendingAuthMessages to tune the default limit of 32. | +| `@bsv/authsocket-client` | `2.1.1` | `2.1.4` | patch | [API and usage](../packages/messaging/authsocket-client.md) | Valid traffic and supported imports are unchanged. The client now disconnects from a server that causes authentication failure or exceeds the concurrency limit; use onError for diagnostics and maxPendingAuthMessages to tune the default limit of 32. | +| `@bsv/btms` | `1.1.1` | `1.1.4` | patch | [API and usage](../packages/wallet/btms.md) | No consumer migration is required; token and lookup wire contracts are unchanged. | +| `@bsv/btms-permission-module` | `1.1.1` | `1.1.3` | patch | [API and usage](../packages/wallet/btms-permission-module.md) | No consumer migration is required; permission-module APIs and token semantics are unchanged. | +| `@bsv/did` | `0.2.1` | `0.2.4` | patch | [API and usage](../packages/helpers/did.md) | No consumer migration is required; DID APIs, encodings, credential behavior, and supported import forms are unchanged. | +| `@bsv/did-client` | `1.2.1` | `1.2.3` | patch | [API and usage](../packages/helpers/did-client.md) | No consumer migration is required; DID client APIs, encodings, and supported imports are unchanged. | +| `@bsv/fund-wallet` | `1.4.1` | `1.4.3` | patch | [API and usage](../packages/helpers/fund-wallet.md) | No consumer migration is required; wallet funding APIs and transaction behavior are unchanged. | +| `@bsv/gasp` | `1.3.1` | `1.3.5` | patch | [API and usage](../packages/overlays/gasp.md) | No consumer migration is required; existing constructor calls, imports, synchronization behavior, and wire semantics are unchanged. | +| `@bsv/message-box-client` | `2.2.2` | `2.3.0` | minor | [API and usage](../packages/messaging/message-box-client.md) | Existing listMessages and listMessagesLite calls continue to fetch all available messages. Applications that need an aggregate memory ceiling should set limit and/or maxPages; no additional BRC-105 approval callback is required because AuthFetch uses wallet permissions. | +| `@bsv/overlay` | `2.2.1` | `2.3.0` | minor | [API and usage](../packages/overlays/overlay.md) | Existing Engine constructor calls remain valid and default to 1,000 lookup formulas. Pass -1 as the final maxLookupResults argument only when a custom lookup service and deployment enforce an equivalent bound. | +| `@bsv/overlay-discovery-services` | `2.1.1` | `2.1.6` | patch | [API and usage](../packages/overlays/overlay-discovery-services.md) | No consumer migration is required; discovery records and public network behavior are unchanged. | +| `@bsv/overlay-express` | `2.4.2` | `2.5.0` | minor | [API and usage](../packages/overlays/overlay-express.md) | The standard profile is selected by default. Existing configuration methods remain compatible; use OVERLAY_RESOURCE_PROFILE or granular OVERLAY_* limits, and ensure custom lookup services bound their own database queries before returning formulas. | +| `@bsv/overlay-topics` | `1.6.1` | `1.6.8` | patch | [API and usage](../packages/overlays/overlay-topics.md) | No consumer migration is required; topic IDs, lookup contracts, and persisted formats are unchanged. | +| `@bsv/paymail` | `2.4.2` | `2.4.6` | patch | [API and usage](../packages/messaging/paymail.md) | Existing Paymail client APIs and protocol semantics are retained. Consumers provide one Express 4.18 or 5 runtime and matching type graph; browser bundles continue to exclude the server router implementation. | +| `@bsv/payment-express-middleware` | `2.1.1` | `2.1.5` | patch | [API and usage](../packages/middleware/payment-express-middleware.md) | No consumer migration is required; legacy x-bsv-payment JSON behavior remains supported, and Express 4 and 5 applications use their own peer-provided Express installation. | +| `@bsv/sdk` | `2.2.18` | `2.3.0` | minor | [API and usage](../packages/sdk/bsv-sdk.md) | No consumer migration is required. The new APIs are additive; BEEF ordering and bytes, proof validity, signatures, synchronous signing, SDK 2.x wire encodings, BRC-103/104 behavior, and supported imports are unchanged. | +| `@bsv/simple` | `0.4.1` | `0.4.8` | patch | [API and usage](../packages/helpers/simple.md) | No consumer migration is required; the browser and server entry points remain compatible. | +| `@bsv/templates` | `1.9.1` | `1.9.6` | patch | [API and usage](../packages/helpers/templates.md) | No consumer migration is required; template APIs, supported imports, and generated script semantics are unchanged. | +| `@bsv/teranode-listener` | `1.1.1` | `1.1.4` | patch | [API and usage](../packages/network/teranode-listener.md) | No consumer migration is required; listener APIs, topics, and network configuration are unchanged. | +| `@bsv/verifast` | `0.3.0` | `0.3.4` | patch | [API and usage](../packages/sdk/verifast.md) | No consumer migration is required; exports, verification behavior, worker protocols, package paths, and runtime defaults are unchanged. | +| `@bsv/wallet-helper` | `0.1.1` | `0.1.6` | patch | [API and usage](../packages/helpers/wallet-helper.md) | No consumer migration is required; fluent builder APIs and transaction semantics are unchanged. | +| `@bsv/wallet-relay` | `0.2.2` | `0.3.4` | minor | [API and usage](../packages/wallet/wallet-relay.md) | QRPairingCode now renders a native button and accepts button wrapper attributes. Existing className, style, data, and ARIA props continue to work; update div-specific wrapper selectors or explicitly typed div event handlers. Express integrations now use the host application's matching Express runtime and type graph. | +| `@bsv/wallet-toolbox` | `2.6.0` | `2.6.1` | patch | [API and usage](../packages/wallet/wallet-toolbox.md) | No consumer migration is required. Fresh keyless ChainTracks deployments can now bootstrap from a valid height-zero Arcade batch; existing CDN-backed, persisted, browser, mobile, explicit-client, and legacy v1 configurations remain compatible and keep the same trust checks. | +| `@bsv/wallet-toolbox-client` | `2.6.0` | `2.6.1` | patch | [API and usage](../packages/wallet/wallet-toolbox-client.md) | No browser consumer migration is required. Browser entry points, CORS behavior, explicit clients, legacy v1 URLs, persisted storage, and wire contracts remain compatible. | +| `@bsv/wallet-toolbox-mobile` | `2.6.0` | `2.6.1` | patch | [API and usage](../packages/wallet/wallet-toolbox-mobile.md) | No mobile consumer migration is required. React Native entry points, the mobile bridge, explicit clients, legacy v1 URLs, persisted storage, and wire contracts remain compatible. | +| `create-bsv-app` | `1.0.2` | `1.0.4` | patch | [API and usage](../packages/helpers/create-bsv-app.md) | No consumer migration is required; generated application structure and CLI behavior are unchanged. | `none` means the source manifest matches the recorded npm baseline. Any other value is an unpublished candidate. Publication, tags, releases, registry @@ -477,8 +477,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: Adds resource-profile-aware Wallet Storage RPC pagination, array and response budgets, bounded authenticated response capture, durable payment replay and session schemas, and double-slash compatibility; makes fragmented createAction atomic and set-based with batched proof reads, validation, output writes, shared derivation work, coalesced session touches, and complete privacy-safe phase timings; makes UMP account lookup resilient to partial overlay failure; and refreshes ChainTracks with credential-free Arcade/go-chaintracks bulk and SSE sources, five-network genesis correctness, prioritized failover, local last-good operation, source health, browser-safe reconnects, and a rate-limited keyless WhatsOnChain fallback. -- Migration: List/find RPC calls that omit a limit now receive the profile default (1,000 in standard), and larger caller limits are rejected above the operator maximum. Existing calls and storage data remain compatible; migrations add auth_sessions, payment_replays, and createAction indexes automatically, and storage-provider additions retain backward-compatible fallbacks. Applications may now enter new-user flow when at least one overlay host returns a clean empty result despite malformed or unavailable peers; one verified token still establishes an existing account, multiple unresolved verified tokens remain an error, and WAB existing-account continuity still blocks replacement-wallet onboarding. The default ChainTracks client for mainnet, testnet, and TerraTestNet now uses each public Arcade v2 endpoint without a credential; explicit ChaintracksClientApi injection and legacy v1 URLs remain supported. STN and Terra Scaling TestNet require an explicit STN_CHAINTRACKS_URL/TSTN_CHAINTRACKS_URL or corresponding Arcade URL. A WhatsOnChain key is optional, anonymous fallback stays below the documented public rate, and ChainTracks header/info requests retry anonymously when a configured key is rejected. Browser/mobile CORS expectations, wallet results, BRC-103/104, AuthFetch, JSON-RPC, and wallet wire behavior are otherwise unchanged. +- Release note: Fixes credential-free Arcade/go-chaintracks initialization when ChainTracks bulk storage is empty while retaining continuity, proof-of-work, file-integrity, chainwork, and exact-network genesis validation. +- Migration: No consumer migration is required. Fresh keyless ChainTracks deployments can now bootstrap from a valid height-zero Arcade batch; existing CDN-backed, persisted, browser, mobile, explicit-client, and legacy v1 configurations remain compatible and keep the same trust checks. | Public subpath | Runtime target(s) | Declaration target(s) | | ---------------- | ---------------------------------------------------- | -------------------------- | @@ -491,8 +491,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: Carries the lockstep browser build with the bounded remote-storage contract, batched proof assembly, linear funding and signing work, canonical P2PKH verification, expired-reservation filtering, complete privacy-safe createAction timings, resilient UMP account lookup, and the browser-safe credential-free ChainTracks v2 client with reconnecting SSE and five-network header support. -- Migration: No browser consumer migration is required. Remote storage callers may provide explicit list limits when they need a value other than the operator profile default, and browser wallets receive the resilient partial-host UMP lookup behavior described for @bsv/wallet-toolbox. Mainnet, testnet, and TerraTestNet ChainTracks defaults now use public credential-free Arcade v2 endpoints; explicit clients and legacy v1 URLs remain compatible, while STN and Terra Scaling TestNet require an explicit endpoint. Older compatible SDK peers retain the validated sequential proof fallback, IndexedDB upgrades automatically, and CORS, BRC-103/104, AuthFetch, browser entry points, JSON-RPC, and remote storage wire behavior remain compatible. +- Release note: Carries the lockstep browser build with the corrected credential-free Arcade/go-chaintracks empty-store bootstrap and unchanged validation guarantees. +- Migration: No browser consumer migration is required. Browser entry points, CORS behavior, explicit clients, legacy v1 URLs, persisted storage, and wire contracts remain compatible. | Public subpath | Runtime target(s) | Declaration target(s) | | ---------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | @@ -503,8 +503,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: Carries the lockstep mobile build with the bounded remote-storage contract, batched proof assembly, linear funding and signing work, canonical P2PKH verification, expired-reservation filtering, complete privacy-safe createAction timings, resilient UMP account lookup, and the mobile-safe credential-free ChainTracks v2 client with reconnecting SSE and five-network header support. -- Migration: No mobile consumer migration is required. Remote storage callers may provide explicit list limits when they need a value other than the operator profile default, and mobile wallets receive the resilient partial-host UMP lookup behavior described for @bsv/wallet-toolbox. Mainnet, testnet, and TerraTestNet ChainTracks defaults now use public credential-free Arcade v2 endpoints; explicit clients and legacy v1 URLs remain compatible, while STN and Terra Scaling TestNet require an explicit endpoint. Older compatible SDK peers retain the validated sequential proof fallback, and BRC-103/104, AuthFetch, React Native, the mobile bridge, JSON-RPC, and remote storage wire behavior remain compatible. +- Release note: Carries the lockstep mobile build with the corrected credential-free Arcade/go-chaintracks empty-store bootstrap and unchanged validation guarantees. +- Migration: No mobile consumer migration is required. React Native entry points, the mobile bridge, explicit clients, legacy v1 URLs, persisted storage, and wire contracts remain compatible. | Public subpath | Runtime target(s) | Declaration target(s) | | ---------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | diff --git a/docs/reference/stack-facts.md b/docs/reference/stack-facts.md index acbe6b6ce..5ec5695b1 100644 --- a/docs/reference/stack-facts.md +++ b/docs/reference/stack-facts.md @@ -65,9 +65,9 @@ authorized release action. | wallet | `@bsv/btms` | `1.1.4` | node-library | node-cjs, node-esm | node | `>=22` | [packages/wallet/btms](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/btms) | | wallet | `@bsv/btms-permission-module` | `1.1.3` | node-library | node-esm | node | `>=22` | [packages/wallet/btms-permission-module](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/btms-permission-module) | | wallet | `@bsv/wallet-relay` | `0.3.4` | cli-library | browser-bundler, browser-esm, cli, node-cjs, node-esm | browser, node | `>=22` | [packages/wallet/ts-wallet-relay](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/ts-wallet-relay) | -| wallet | `@bsv/wallet-toolbox` | `2.6.0` | node-library | node-cjs | node | `>=22` | [packages/wallet/wallet-toolbox](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox) | -| wallet | `@bsv/wallet-toolbox-client` | `2.6.0` | browser-library | browser-bundler, browser-esm, node-cjs, node-esm | browser, node | `>=22` | [packages/wallet/wallet-toolbox/client](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/client) | -| wallet | `@bsv/wallet-toolbox-mobile` | `2.6.0` | react-native-library | react-native-metro | react-native | `>=22` | [packages/wallet/wallet-toolbox/mobile](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/mobile) | +| wallet | `@bsv/wallet-toolbox` | `2.6.1` | node-library | node-cjs | node | `>=22` | [packages/wallet/wallet-toolbox](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox) | +| wallet | `@bsv/wallet-toolbox-client` | `2.6.1` | browser-library | browser-bundler, browser-esm, node-cjs, node-esm | browser, node | `>=22` | [packages/wallet/wallet-toolbox/client](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/client) | +| wallet | `@bsv/wallet-toolbox-mobile` | `2.6.1` | react-native-library | react-native-metro | react-native | `>=22` | [packages/wallet/wallet-toolbox/mobile](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/wallet/wallet-toolbox/mobile) | ## Standalone infrastructure manifests diff --git a/governance/package-release-notes.json b/governance/package-release-notes.json index 9b89d1c00..4a7fca48a 100644 --- a/governance/package-release-notes.json +++ b/governance/package-release-notes.json @@ -194,24 +194,24 @@ }, { "name": "@bsv/wallet-toolbox", - "publishedVersion": "2.5.0", - "releaseType": "minor", - "summary": "Adds resource-profile-aware Wallet Storage RPC pagination, array and response budgets, bounded authenticated response capture, durable payment replay and session schemas, and double-slash compatibility; makes fragmented createAction atomic and set-based with batched proof reads, validation, output writes, shared derivation work, coalesced session touches, and complete privacy-safe phase timings; makes UMP account lookup resilient to partial overlay failure; and refreshes ChainTracks with credential-free Arcade/go-chaintracks bulk and SSE sources, five-network genesis correctness, prioritized failover, local last-good operation, source health, browser-safe reconnects, and a rate-limited keyless WhatsOnChain fallback.", - "migration": "List/find RPC calls that omit a limit now receive the profile default (1,000 in standard), and larger caller limits are rejected above the operator maximum. Existing calls and storage data remain compatible; migrations add auth_sessions, payment_replays, and createAction indexes automatically, and storage-provider additions retain backward-compatible fallbacks. Applications may now enter new-user flow when at least one overlay host returns a clean empty result despite malformed or unavailable peers; one verified token still establishes an existing account, multiple unresolved verified tokens remain an error, and WAB existing-account continuity still blocks replacement-wallet onboarding. The default ChainTracks client for mainnet, testnet, and TerraTestNet now uses each public Arcade v2 endpoint without a credential; explicit ChaintracksClientApi injection and legacy v1 URLs remain supported. STN and Terra Scaling TestNet require an explicit STN_CHAINTRACKS_URL/TSTN_CHAINTRACKS_URL or corresponding Arcade URL. A WhatsOnChain key is optional, anonymous fallback stays below the documented public rate, and ChainTracks header/info requests retry anonymously when a configured key is rejected. Browser/mobile CORS expectations, wallet results, BRC-103/104, AuthFetch, JSON-RPC, and wallet wire behavior are otherwise unchanged." + "publishedVersion": "2.6.0", + "releaseType": "patch", + "summary": "Fixes credential-free Arcade/go-chaintracks initialization when ChainTracks bulk storage is empty while retaining continuity, proof-of-work, file-integrity, chainwork, and exact-network genesis validation.", + "migration": "No consumer migration is required. Fresh keyless ChainTracks deployments can now bootstrap from a valid height-zero Arcade batch; existing CDN-backed, persisted, browser, mobile, explicit-client, and legacy v1 configurations remain compatible and keep the same trust checks." }, { "name": "@bsv/wallet-toolbox-client", - "publishedVersion": "2.5.0", - "releaseType": "minor", - "summary": "Carries the lockstep browser build with the bounded remote-storage contract, batched proof assembly, linear funding and signing work, canonical P2PKH verification, expired-reservation filtering, complete privacy-safe createAction timings, resilient UMP account lookup, and the browser-safe credential-free ChainTracks v2 client with reconnecting SSE and five-network header support.", - "migration": "No browser consumer migration is required. Remote storage callers may provide explicit list limits when they need a value other than the operator profile default, and browser wallets receive the resilient partial-host UMP lookup behavior described for @bsv/wallet-toolbox. Mainnet, testnet, and TerraTestNet ChainTracks defaults now use public credential-free Arcade v2 endpoints; explicit clients and legacy v1 URLs remain compatible, while STN and Terra Scaling TestNet require an explicit endpoint. Older compatible SDK peers retain the validated sequential proof fallback, IndexedDB upgrades automatically, and CORS, BRC-103/104, AuthFetch, browser entry points, JSON-RPC, and remote storage wire behavior remain compatible." + "publishedVersion": "2.6.0", + "releaseType": "patch", + "summary": "Carries the lockstep browser build with the corrected credential-free Arcade/go-chaintracks empty-store bootstrap and unchanged validation guarantees.", + "migration": "No browser consumer migration is required. Browser entry points, CORS behavior, explicit clients, legacy v1 URLs, persisted storage, and wire contracts remain compatible." }, { "name": "@bsv/wallet-toolbox-mobile", - "publishedVersion": "2.5.0", - "releaseType": "minor", - "summary": "Carries the lockstep mobile build with the bounded remote-storage contract, batched proof assembly, linear funding and signing work, canonical P2PKH verification, expired-reservation filtering, complete privacy-safe createAction timings, resilient UMP account lookup, and the mobile-safe credential-free ChainTracks v2 client with reconnecting SSE and five-network header support.", - "migration": "No mobile consumer migration is required. Remote storage callers may provide explicit list limits when they need a value other than the operator profile default, and mobile wallets receive the resilient partial-host UMP lookup behavior described for @bsv/wallet-toolbox. Mainnet, testnet, and TerraTestNet ChainTracks defaults now use public credential-free Arcade v2 endpoints; explicit clients and legacy v1 URLs remain compatible, while STN and Terra Scaling TestNet require an explicit endpoint. Older compatible SDK peers retain the validated sequential proof fallback, and BRC-103/104, AuthFetch, React Native, the mobile bridge, JSON-RPC, and remote storage wire behavior remain compatible." + "publishedVersion": "2.6.0", + "releaseType": "patch", + "summary": "Carries the lockstep mobile build with the corrected credential-free Arcade/go-chaintracks empty-store bootstrap and unchanged validation guarantees.", + "migration": "No mobile consumer migration is required. React Native entry points, the mobile bridge, explicit clients, legacy v1 URLs, persisted storage, and wire contracts remain compatible." }, { "name": "create-bsv-app", diff --git a/governance/repository-health/baselines.json b/governance/repository-health/baselines.json index 5e439ffd4..9fe3dd99f 100644 --- a/governance/repository-health/baselines.json +++ b/governance/repository-health/baselines.json @@ -325,8 +325,8 @@ "@bsv/btms": "1.1.4", "@bsv/btms-permission-module": "1.1.3", "@bsv/wallet-relay": "0.3.4", - "@bsv/wallet-toolbox-client": "2.6.0", - "@bsv/wallet-toolbox-mobile": "2.6.0", - "@bsv/wallet-toolbox": "2.6.0" + "@bsv/wallet-toolbox-client": "2.6.1", + "@bsv/wallet-toolbox-mobile": "2.6.1", + "@bsv/wallet-toolbox": "2.6.1" } } diff --git a/packages/wallet/wallet-toolbox/CHANGELOG.md b/packages/wallet/wallet-toolbox/CHANGELOG.md index a611326c4..c5b2442c8 100644 --- a/packages/wallet/wallet-toolbox/CHANGELOG.md +++ b/packages/wallet/wallet-toolbox/CHANGELOG.md @@ -6,6 +6,10 @@ attention to changes that materially alter behavior or extend functionality. ## wallet-toolbox (unreleased) +- Fix credential-free Arcade/go-chaintracks bootstrap when ChainTracks bulk + storage is empty. A first batch is now accepted only from height zero and is + still checked for continuity, proof of work, file integrity, and the exact + configured network genesis before it becomes available. - Make ChainTracks credential-free by default on mainnet, testnet, and TerraTestNet through the public Arcade/go-chaintracks v2 HTTP and SSE APIs. Add explicit STN and Terra Scaling TestNet support, exact per-network genesis diff --git a/packages/wallet/wallet-toolbox/client/package.json b/packages/wallet/wallet-toolbox/client/package.json index 13f9fc427..7a54307ba 100644 --- a/packages/wallet/wallet-toolbox/client/package.json +++ b/packages/wallet/wallet-toolbox/client/package.json @@ -1,6 +1,6 @@ { "name": "@bsv/wallet-toolbox-client", - "version": "2.6.0", + "version": "2.6.1", "type": "module", "sideEffects": false, "engines": { diff --git a/packages/wallet/wallet-toolbox/client/platform-budget.json b/packages/wallet/wallet-toolbox/client/platform-budget.json index 5a71e5404..bdc1e2209 100644 --- a/packages/wallet/wallet-toolbox/client/platform-budget.json +++ b/packages/wallet/wallet-toolbox/client/platform-budget.json @@ -8,7 +8,7 @@ }, "esbuild": { "raw": 1205000, - "gzip": 330000, + "gzip": 330100, "brotli": 268000 } } diff --git a/packages/wallet/wallet-toolbox/mobile/package.json b/packages/wallet/wallet-toolbox/mobile/package.json index 08d414c84..10d5fd475 100644 --- a/packages/wallet/wallet-toolbox/mobile/package.json +++ b/packages/wallet/wallet-toolbox/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@bsv/wallet-toolbox-mobile", - "version": "2.6.0", + "version": "2.6.1", "type": "module", "sideEffects": false, "engines": { diff --git a/packages/wallet/wallet-toolbox/package.json b/packages/wallet/wallet-toolbox/package.json index c12d0f787..54bd65aa2 100644 --- a/packages/wallet/wallet-toolbox/package.json +++ b/packages/wallet/wallet-toolbox/package.json @@ -1,6 +1,6 @@ { "name": "@bsv/wallet-toolbox", - "version": "2.6.0", + "version": "2.6.1", "sideEffects": false, "type": "commonjs", "engines": { diff --git a/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorChaintracks.test.ts b/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorChaintracks.test.ts index 389d3f3a6..421f9d8a8 100644 --- a/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorChaintracks.test.ts +++ b/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/Ingest/__tests/BulkIngestorChaintracks.test.ts @@ -1,5 +1,8 @@ import { ChaintracksClientApi } from '../../Api/ChaintracksClientApi' import { ChaintracksStorageBase } from '../../Storage/ChaintracksStorageBase' +import { ChaintracksStorageNoDb } from '../../Storage/ChaintracksStorageNoDb' +import { BulkFileDataManager } from '../../util/BulkFileDataManager' +import { ChaintracksFs } from '../../util/ChaintracksFs' import { HeightRange } from '../../util/HeightRange' import { serializeBaseBlockHeader } from '../../util/blockHeaderUtilities' import { BulkIngestorChaintracks } from '../BulkIngestorChaintracks' @@ -79,6 +82,48 @@ describe('BulkIngestorChaintracks', () => { expect(result.map(header => header.height)).toEqual([0, 1, 2]) }) + test('bootstraps real empty storage from a validated Arcade genesis batch', async () => { + const data = await ChaintracksFs.readFile( + './src/services/chaintracker/chaintracks/__tests/data/cdnTest499/mainNet_0.headers' + ) + const getHeaders = jest.fn(async () => toHex([...data])) + const remote = { + getChain: jest.fn(async () => 'main'), + getHeaders + } as unknown as ChaintracksClientApi + const storageOptions = ChaintracksStorageBase.createStorageBaseOptions('main') + storageOptions.bulkFileDataManager = new BulkFileDataManager({ + chain: 'main', + maxPerFile: 100, + maxRetained: 2 + }) + const storage = new ChaintracksStorageNoDb(storageOptions) + const ingestor = new BulkIngestorChaintracks({ + chain: 'main', + jsonResource: 'mainNetBlockHeaders.json', + chaintracks: remote, + maxHeadersPerRequest: 100 + }) + await ingestor.setStorage(storage, () => {}) + + await expect( + ingestor.fetchHeaders( + { bulk: HeightRange.empty, live: HeightRange.empty }, + new HeightRange(0, 99), + new HeightRange(0, 99), + [] + ) + ).resolves.toEqual([]) + + expect(getHeaders).toHaveBeenCalledWith(0, 100) + await expect(storage.getAvailableHeightRanges()).resolves.toMatchObject({ + bulk: { minHeight: 0, maxHeight: 99 } + }) + await expect(storage.bulkManager.findHeaderForHeightOrUndefined(0)).resolves.toMatchObject({ + hash: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f' + }) + }) + test('rejects an upstream configured for another network', async () => { const remote = { getChain: jest.fn(async () => 'test') diff --git a/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts b/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts index ef96b0097..a241e7b2d 100644 --- a/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts +++ b/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts @@ -290,13 +290,18 @@ export class BulkFileDataManager { )) if (newBulkHeaders.length === 0) return - if (lbf == null || nextHeight !== newBulkHeaders[0].height) { + if (nextHeight !== newBulkHeaders[0].height) { throw new WERR_INVALID_PARAMETER('newBulkHeaders', 'an extension of existing bulk headers') } - if (!lbf.lastHash) throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`) + if (lbf != null && !lbf.lastHash) { + throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`) + } + + const prevChainWork = lbf?.lastChainWork ?? '00'.repeat(32) + const prevHash = lbf?.lastHash ?? '00'.repeat(32) const lastChainWork = incrementalChainWork - ? addWork(incrementalChainWork, lbf.lastChainWork) + ? addWork(incrementalChainWork, prevChainWork) : computeChainWorkFromHeaders(newBulkHeaders, lbf) const data = serializeBaseBlockHeaders(newBulkHeaders) @@ -308,9 +313,9 @@ export class BulkFileDataManager { fileName: 'incremental', firstHeight: newBulkHeaders[0].height, count: newBulkHeaders.length, - prevChainWork: lbf.lastChainWork, + prevChainWork, lastChainWork, - prevHash: lbf.lastHash, + prevHash, lastHash: newBulkHeaders.at(-1)!.hash, fileHash, data @@ -952,12 +957,13 @@ function trimAlreadyStoredHeaders( /** * Computes `lastChainWork` for a sequence of new bulk headers extending `lbf`, - * validating that the sequence is contiguous. + * or beginning at genesis when bulk storage is empty, validating that the + * sequence is contiguous. */ -function computeChainWorkFromHeaders(headers: BlockHeader[], lbf: BulkHeaderFileInfo): string { - let lastHeight = lbf.firstHeight + lbf.count - 1 - let lastHash = lbf.lastHash! - let lastChainWork = lbf.lastChainWork +function computeChainWorkFromHeaders(headers: BlockHeader[], lbf?: BulkHeaderFileInfo): string { + let lastHeight = lbf != null ? lbf.firstHeight + lbf.count - 1 : -1 + let lastHash = lbf?.lastHash ?? '00'.repeat(32) + let lastChainWork = lbf?.lastChainWork ?? '00'.repeat(32) for (const h of headers) { if (h.height !== lastHeight + 1 || h.previousHash !== lastHash) { throw new WERR_INVALID_PARAMETER( diff --git a/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts b/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts index 1e51c0582..8c8f06651 100644 --- a/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts +++ b/packages/wallet/wallet-toolbox/src/services/chaintracker/chaintracks/util/__tests/BulkFileDataManager.test.ts @@ -16,6 +16,7 @@ describe('BulkFileDataManager tests', () => { const chain: Chain = 'main' const fs = ChaintracksFs const rootFolder = './src/services/chaintracker/chaintracks/__tests/data' + let headers0_99: BlockHeader[] = [] let headers300_399: BlockHeader[] = [] let headers400_499: BlockHeader[] = [] let server349: LocalCdnServer | undefined @@ -25,8 +26,10 @@ describe('BulkFileDataManager tests', () => { let server499: LocalCdnServer | undefined beforeAll(async () => { + const data0_99 = await ChaintracksFs.readFile(fs.pathJoin(rootFolder, 'cdnTest499/mainNet_0.headers')) const data300_399 = await ChaintracksFs.readFile(fs.pathJoin(rootFolder, 'cdnTest499/mainNet_3.headers')) const data400_499 = await ChaintracksFs.readFile(fs.pathJoin(rootFolder, 'cdnTest499/mainNet_4.headers')) + headers0_99 = deserializeBlockHeaders(0, data0_99) headers300_399 = deserializeBlockHeaders(300, data300_399) headers400_499 = deserializeBlockHeaders(400, data400_499) @@ -264,7 +267,49 @@ describe('BulkFileDataManager tests', () => { await storage.destroy() }) - test('6 validates last-file update transitions', async () => { + test('6 bootstraps empty bulk storage from a validated genesis batch', async () => { + const computedWorkManager = createEmptyManager() + + await computedWorkManager.mergeIncrementalBlockHeaders(headers0_99) + await computedWorkManager.ReValidate() + + const range = await computedWorkManager.getHeightRange() + expect(range.minHeight).toBe(0) + expect(range.maxHeight).toBe(99) + const [file] = await computedWorkManager.getBulkFiles(true) + expect(file).toMatchObject({ + firstHeight: 0, + count: 100, + fileName: 'incremental', + prevChainWork: '00'.repeat(32), + prevHash: '00'.repeat(32), + lastHash: headers0_99.at(-1)!.hash, + validated: true + }) + expect(await computedWorkManager.findHeaderForHeightOrUndefined(0)).toEqual(headers0_99[0]) + + const suppliedWorkManager = createEmptyManager() + await expect( + suppliedWorkManager.mergeIncrementalBlockHeaders(headers0_99, file.lastChainWork) + ).resolves.toBeUndefined() + await suppliedWorkManager.ReValidate() + + const nonGenesisManager = createEmptyManager() + await expect(nonGenesisManager.mergeIncrementalBlockHeaders(headers300_399)).rejects.toThrow( + 'an extension of existing bulk headers' + ) + expect((await nonGenesisManager.getHeightRange()).isEmpty).toBe(true) + + const missingLastHashManager = createEmptyManager() + const incompleteFile = makeBulkFile(0, 99, 'incremental') + incompleteFile.lastHash = undefined + missingLastHashManager['bfds'] = [incompleteFile] as any + await expect( + missingLastHashManager.mergeIncrementalBlockHeaders(headers0_99.slice(99)) + ).rejects.toThrow('lastHash is not defined for the last bulk file incremental') + }) + + test('7 validates last-file update transitions', async () => { const manager = createEmptyManager() const cdn = makeBulkFile(0, 10, 'mainNet_0.headers', 'https://cdn.example') manager['bfds'] = [cdn] as any @@ -302,7 +347,7 @@ describe('BulkFileDataManager tests', () => { ).resolves.toEqual({ index: 0, truncate: undefined }) }) - test('7 validates penultimate-file update transitions', async () => { + test('8 validates penultimate-file update transitions', async () => { const manager = createEmptyManager() const cdn = makeBulkFile(0, 10, 'mainNet_0.headers', 'https://cdn.example') cdn.fileId = 7 @@ -345,7 +390,7 @@ describe('BulkFileDataManager tests', () => { ).rejects.toThrow('CDN file update followed by an incremental file') }) - test('8 preserves or inherits file identity for valid penultimate updates', async () => { + test('9 preserves or inherits file identity for valid penultimate updates', async () => { const manager = createEmptyManager() const cdn = makeBulkFile(0, 10, 'mainNet_0.headers', 'https://cdn.example') cdn.fileId = 7