@bsv/overlay 2.2.1 → 2.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/LICENSE.txt +57 -27
  2. package/README.md +102 -269
  3. package/dist/cjs/mod.d.ts +15 -0
  4. package/dist/cjs/mod.d.ts.map +1 -0
  5. package/dist/cjs/mod.js +4 -1
  6. package/dist/cjs/mod.js.map +1 -1
  7. package/dist/cjs/package.json +41 -13
  8. package/dist/cjs/src/Advertisement.d.ts +9 -0
  9. package/dist/cjs/src/Advertisement.d.ts.map +1 -0
  10. package/dist/cjs/src/Advertiser.d.ts +36 -0
  11. package/dist/cjs/src/Advertiser.d.ts.map +1 -0
  12. package/dist/cjs/src/BASM.d.ts +110 -0
  13. package/dist/cjs/src/BASM.d.ts.map +1 -0
  14. package/dist/cjs/src/BASM.js.map +1 -1
  15. package/dist/cjs/src/BASMRemote.d.ts +14 -0
  16. package/dist/cjs/src/BASMRemote.d.ts.map +1 -0
  17. package/dist/cjs/src/BASMRemote.js.map +1 -1
  18. package/dist/cjs/src/Engine.d.ts +377 -0
  19. package/dist/cjs/src/Engine.d.ts.map +1 -0
  20. package/dist/cjs/src/Engine.js +416 -417
  21. package/dist/cjs/src/Engine.js.map +1 -1
  22. package/dist/cjs/src/GASP/OverlayGASPRemote.d.ts +24 -0
  23. package/dist/cjs/src/GASP/OverlayGASPRemote.d.ts.map +1 -0
  24. package/dist/cjs/src/GASP/OverlayGASPRemote.js +7 -10
  25. package/dist/cjs/src/GASP/OverlayGASPRemote.js.map +1 -1
  26. package/dist/cjs/src/GASP/OverlayGASPStorage.d.ts +103 -0
  27. package/dist/cjs/src/GASP/OverlayGASPStorage.d.ts.map +1 -0
  28. package/dist/cjs/src/GASP/OverlayGASPStorage.js +32 -30
  29. package/dist/cjs/src/GASP/OverlayGASPStorage.js.map +1 -1
  30. package/dist/cjs/src/LookupFormula.d.ts +29 -0
  31. package/dist/cjs/src/LookupFormula.d.ts.map +1 -0
  32. package/dist/cjs/src/LookupService.d.ts +85 -0
  33. package/dist/cjs/src/LookupService.d.ts.map +1 -0
  34. package/dist/cjs/src/Output.d.ts +32 -0
  35. package/dist/cjs/src/Output.d.ts.map +1 -0
  36. package/dist/cjs/src/SafeLog.d.ts +14 -0
  37. package/dist/cjs/src/SafeLog.d.ts.map +1 -0
  38. package/dist/cjs/src/SafeLog.js +44 -0
  39. package/dist/cjs/src/SafeLog.js.map +1 -0
  40. package/{src/SyncConfiguration.ts → dist/cjs/src/SyncConfiguration.d.ts} +2 -1
  41. package/dist/cjs/src/SyncConfiguration.d.ts.map +1 -0
  42. package/dist/cjs/src/TopicManager.d.ts +35 -0
  43. package/dist/cjs/src/TopicManager.d.ts.map +1 -0
  44. package/dist/cjs/src/storage/Storage.d.ts +237 -0
  45. package/dist/cjs/src/storage/Storage.d.ts.map +1 -0
  46. package/dist/cjs/src/storage/knex/KnexStorage.d.ts +69 -0
  47. package/dist/cjs/src/storage/knex/KnexStorage.d.ts.map +1 -0
  48. package/dist/cjs/src/storage/knex/KnexStorage.js +7 -10
  49. package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -1
  50. package/dist/cjs/src/storage/knex/all-migrations.d.ts +11 -0
  51. package/dist/cjs/src/storage/knex/all-migrations.d.ts.map +1 -0
  52. package/dist/cjs/src/storage/knex/all-migrations.js.map +1 -1
  53. package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.d.ts +4 -0
  54. package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.d.ts.map +1 -0
  55. package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.js.map +1 -1
  56. package/dist/cjs/src/storage/knex/migrations/2024-07-10-001-block-height.d.ts +4 -0
  57. package/dist/cjs/src/storage/knex/migrations/2024-07-10-001-block-height.d.ts.map +1 -0
  58. package/dist/cjs/src/storage/knex/migrations/2024-07-10-001-block-height.js.map +1 -1
  59. package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.d.ts +4 -0
  60. package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.d.ts.map +1 -0
  61. package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.js.map +1 -1
  62. package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.d.ts +4 -0
  63. package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.d.ts.map +1 -0
  64. package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.js.map +1 -1
  65. package/dist/cjs/src/storage/knex/migrations/2025-05-28-001-enlarge.d.ts +4 -0
  66. package/dist/cjs/src/storage/knex/migrations/2025-05-28-001-enlarge.d.ts.map +1 -0
  67. package/dist/cjs/src/storage/knex/migrations/2025-05-28-001-enlarge.js.map +1 -1
  68. package/dist/cjs/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.d.ts +4 -0
  69. package/dist/cjs/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.d.ts.map +1 -0
  70. package/dist/cjs/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.js.map +1 -1
  71. package/dist/cjs/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.d.ts +4 -0
  72. package/dist/cjs/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.d.ts.map +1 -0
  73. package/dist/cjs/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.js.map +1 -1
  74. package/dist/cjs/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.d.ts +9 -0
  75. package/dist/cjs/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.d.ts.map +1 -0
  76. package/dist/cjs/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.js.map +1 -1
  77. package/dist/cjs/src/storage/knex/migrations/2026-05-29-001-brc136-basm.d.ts +4 -0
  78. package/dist/cjs/src/storage/knex/migrations/2026-05-29-001-brc136-basm.d.ts.map +1 -0
  79. package/dist/cjs/src/storage/knex/migrations/2026-05-29-001-brc136-basm.js.map +1 -1
  80. package/dist/esm/mod.js +2 -1
  81. package/dist/esm/mod.js.map +1 -1
  82. package/dist/esm/src/BASMRemote.js.map +1 -1
  83. package/dist/esm/src/Engine.js +394 -395
  84. package/dist/esm/src/Engine.js.map +1 -1
  85. package/dist/esm/src/GASP/OverlayGASPRemote.js +2 -2
  86. package/dist/esm/src/GASP/OverlayGASPRemote.js.map +1 -1
  87. package/dist/esm/src/GASP/OverlayGASPStorage.js +21 -18
  88. package/dist/esm/src/GASP/OverlayGASPStorage.js.map +1 -1
  89. package/dist/esm/src/SafeLog.js +40 -0
  90. package/dist/esm/src/SafeLog.js.map +1 -0
  91. package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -1
  92. package/dist/types/mod.d.ts +5 -4
  93. package/dist/types/mod.d.ts.map +1 -1
  94. package/dist/types/src/BASMRemote.d.ts.map +1 -1
  95. package/dist/types/src/Engine.d.ts +15 -0
  96. package/dist/types/src/Engine.d.ts.map +1 -1
  97. package/dist/types/src/GASP/OverlayGASPRemote.d.ts +2 -2
  98. package/dist/types/src/GASP/OverlayGASPRemote.d.ts.map +1 -1
  99. package/dist/types/src/GASP/OverlayGASPStorage.d.ts +3 -1
  100. package/dist/types/src/GASP/OverlayGASPStorage.d.ts.map +1 -1
  101. package/dist/types/src/SafeLog.d.ts +14 -0
  102. package/dist/types/src/SafeLog.d.ts.map +1 -0
  103. package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -1
  104. package/dist/types/src/storage/knex/all-migrations.d.ts.map +1 -1
  105. package/package.json +85 -28
  106. package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
  107. package/dist/esm/tsconfig.esm.tsbuildinfo +0 -1
  108. package/dist/types/tsconfig.types.tsbuildinfo +0 -1
  109. package/docs/API.md +0 -944
  110. package/docs/BRC-136-BASM.md +0 -327
  111. package/docs/README.md +0 -16
  112. package/docs/Synchronization.md +0 -212
  113. package/docs/concepts/00-overview.md +0 -85
  114. package/docs/concepts/01-best-practices.md +0 -202
  115. package/docs/concepts/02-query-performance.md +0 -345
  116. package/docs/concepts/03-database-monitoring.md +0 -211
  117. package/docs/concepts/04-pagination-example.md +0 -186
  118. package/docs/concepts/05-recommendations-summary.md +0 -158
  119. package/docs/concepts/README.md +0 -20
  120. package/docs/examples/README.md +0 -15
  121. package/docs/examples/gs-wip.md +0 -111
  122. package/docs/internal/README.md +0 -11
  123. package/mod.ts +0 -40
  124. package/src/Advertisement.ts +0 -8
  125. package/src/Advertiser.ts +0 -41
  126. package/src/BASM.ts +0 -208
  127. package/src/BASMRemote.ts +0 -54
  128. package/src/Engine.ts +0 -2194
  129. package/src/GASP/OverlayGASPRemote.ts +0 -108
  130. package/src/GASP/OverlayGASPStorage.ts +0 -384
  131. package/src/LookupFormula.ts +0 -31
  132. package/src/LookupService.ts +0 -136
  133. package/src/Output.ts +0 -31
  134. package/src/TopicManager.ts +0 -40
  135. package/src/__tests/BASM.test.ts +0 -44
  136. package/src/__tests/BASMChain.test.ts +0 -295
  137. package/src/__tests/Engine.test.ts +0 -1381
  138. package/src/__tests/OverlayGASPRemote.test.ts +0 -135
  139. package/src/__tests/OverlayGASPStorage.test.ts +0 -205
  140. package/src/storage/Storage.ts +0 -260
  141. package/src/storage/knex/KnexStorage.ts +0 -651
  142. package/src/storage/knex/all-migrations.ts +0 -32
  143. package/src/storage/knex/migrations/2024-05-18-001-initial.ts +0 -30
  144. package/src/storage/knex/migrations/2024-07-10-001-block-height.ts +0 -15
  145. package/src/storage/knex/migrations/2024-07-17-001-transactions.ts +0 -64
  146. package/src/storage/knex/migrations/2024-07-18-001-indexes.ts +0 -30
  147. package/src/storage/knex/migrations/2025-05-28-001-enlarge.ts +0 -42
  148. package/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.ts +0 -46
  149. package/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.ts +0 -24
  150. package/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.ts +0 -18
  151. package/src/storage/knex/migrations/2026-05-29-001-brc136-basm.ts +0 -123
@@ -1,111 +0,0 @@
1
- # Getting Started with BSV Overlay Services Engine
2
-
3
- [🏠 Home](../README.md) | [📚 API](../API.md) | [💡 Concepts](../concepts/README.md) | [📖 Examples](./README.md) | [⚙️ Internal](../internal/README.md)
4
-
5
- ---
6
-
7
- ## Introduction to BSV Overlay Services Engine
8
-
9
- The BSV Overlay Services Engine is designed to process transactions and manage data within a blockchain-based system, specifically targeting the Bitcoin SV (BSV) blockchain. It integrates various components such as Topic Managers, Lookup Services, Storage, and Chain Tracker to provide a robust environment for managing transaction data and overlay services.
10
-
11
- ### Components of the System
12
-
13
- 1. **Topic Managers**: Responsible for managing the admittance of transactions related to specific topics.
14
- 2. **Lookup Services**: Handle the lookup of UTXO (Unspent Transaction Output) data for transactions.
15
- 3. **Storage**: Manages persistent data storage, tracking UTXOs and their states within the system.
16
- 4. **Chain Tracker**: Verifies SPV (Simplified Payment Verification) data associated with transactions to ensure their validity.
17
-
18
- ### Setting Up the Engine
19
-
20
- Before you can use the engine, you must initialize it with the required components:
21
-
22
- ```ts
23
- import { Engine, KnexStorage } from "@bsv/overlay";
24
- import { HelloTopicManager, HelloLookupService } from 'hello-services';
25
- import { WoChain } from "@bsv/sdk";
26
-
27
- // Initialize components
28
- const managers = {
29
- "exampleTopic": new HelloTopicManager()
30
- };
31
-
32
- const lookupServices = {
33
- "exampleLookup": new HelloLookupService()
34
- };
35
-
36
- const storage = new KnexStorage();
37
- const chainTracker = new WoChain();
38
-
39
- // Create the engine instance
40
- const engine = new Engine(managers, lookupServices, storage, chainTracker);
41
- ```
42
-
43
- ### Submitting a Transaction
44
-
45
- To submit a transaction for processing by the Overlay Services:
46
-
47
- ```ts
48
- import { Transaction } from '@bsv/sdk'
49
-
50
- const tx = new Transaction(/* ... */);
51
-
52
- const transaction = {
53
- beef: tx.toBEEF(),
54
- topics: ['exampleTopic']
55
- }
56
-
57
- // Submit transaction
58
- engine.submit(transaction).then(steak => {
59
- console.log("Transaction processed:", steak);
60
- }).catch(error => {
61
- console.error("Error processing transaction:", error);
62
- });
63
- ```
64
-
65
- ### Lookup Queries
66
-
67
- To perform a lookup query using the engine:
68
-
69
- ```ts
70
- const question = {
71
- service: 'exampleLookup',
72
- query: {
73
- name: 'Bob'
74
- }
75
- }
76
-
77
- // Perform a lookup
78
- engine.lookup(question).then(answer => {
79
- console.log("Lookup result:", answer);
80
- }).catch(error => {
81
- console.error("Error performing lookup:", error);
82
- });
83
- ```
84
-
85
- ### Managing UTXOs
86
-
87
- The system's core functionality involves managing UTXOs:
88
-
89
- 1. **Inserting a New UTXO**: Store new UTXO data when transactions are processed.
90
- 2. **Deleting a UTXO**: Remove UTXOs that are no longer needed or have been consumed by newer transactions.
91
- 3. **Tracking UTXO Consumption**: Monitor which transactions consume which UTXOs.
92
-
93
- ### Retrieving Documentation
94
-
95
- To retrieve documentation for specific managers or services:
96
-
97
- ```ts
98
- // For a topic manager
99
- engine.getDocumentationForTopicManger("exampleTopic").then(doc => {
100
- console.log("Documentation for Topic Manager:", doc);
101
- });
102
-
103
- // For a lookup service
104
- engine.getDocumentationForLookupServiceProvider("exampleLookup").then(doc => {
105
- console.log("Documentation for Lookup Service:", doc);
106
- });
107
- ```
108
-
109
- ### Conclusion
110
-
111
- The BSV Overlay Services Engine provides a powerful toolset for managing transactions and data on the Bitcoin SV blockchain. It's designed to handle complex data structures and ensure the integrity and security of transactions through rigorous validation and management processes. By following this tutorial, developers can effectively integrate and utilize these capabilities within their blockchain applications.
@@ -1,11 +0,0 @@
1
- # Internals
2
-
3
- [🏠 Home](../README.md) | [📚 API](../API.md) | [💡 Concepts](../concepts/README.md) | [📖 Examples](../examples/README.md) | [⚙️ Internal](./README.md)
4
-
5
- ---
6
-
7
- These documents cover the internal components of the Overlay Services engine. Generally, these are only useful for creating customized deployments.
8
-
9
- ---
10
-
11
- [🏠 Home](../README.md) | [📚 API](../API.md) | [💡 Concepts](../concepts/README.md) | [📖 Examples](../examples/README.md) | [⚙️ Internal](./README.md)
package/mod.ts DELETED
@@ -1,40 +0,0 @@
1
- // Fundamentals
2
- export { Engine } from "./src/Engine.js"
3
- export type * from "./src/LookupService.js"
4
- export type { TopicManager } from "./src/TopicManager.js"
5
-
6
- // Interfaces and structures
7
- export type { Storage, AppliedTransaction } from "./src/storage/Storage.js"
8
- export type { Output } from './src/Output.js'
9
- export type { TaggedBEEF, STEAK, LookupQuestion, LookupAnswer, AdmittanceInstructions } from '@bsv/sdk'
10
- export type { LookupFormula } from './src/LookupFormula.js'
11
- export type { Advertisement } from './src/Advertisement.js'
12
- export type { AdvertisementData, Advertiser } from './src/Advertiser.js'
13
- export {
14
- BASM_ZERO_HASH,
15
- computeBasmRoot,
16
- computeTac,
17
- extractMerkleProofMetadata
18
- } from './src/BASM.js'
19
- export type {
20
- AdmittedListRequest,
21
- AdmittedListResponse,
22
- AdmittedTxRef,
23
- BASMPeerSyncReport,
24
- CompoundMerklePathRequest,
25
- CompoundMerklePathResponse,
26
- MerkleProofMetadata,
27
- RawTransactionRecord,
28
- RawTransactionRequest,
29
- RawTransactionResponse,
30
- TopicAnchorHeader,
31
- TopicAnchorHeaderResolver,
32
- TopicAnchorRangeRequest,
33
- TopicAnchorRangeResponse,
34
- TopicAnchorTip,
35
- TopicBlockAnchor
36
- } from './src/BASM.js'
37
-
38
- // The Knex storage system
39
- export { KnexStorage } from './src/storage/knex/KnexStorage.js'
40
- export * as KnexStorageMigrations from './src/storage/knex/all-migrations.js'
@@ -1,8 +0,0 @@
1
- export interface Advertisement {
2
- protocol: 'SHIP' | 'SLAP'
3
- identityKey: string
4
- domain: string
5
- topicOrService: string
6
- beef?: number[]
7
- outputIndex?: number
8
- }
package/src/Advertiser.ts DELETED
@@ -1,41 +0,0 @@
1
- import { Script, TaggedBEEF } from '@bsv/sdk'
2
- import { Advertisement } from './Advertisement.js'
3
-
4
- export interface AdvertisementData {
5
- protocol: 'SHIP' | 'SLAP'
6
- topicOrServiceName: string
7
- }
8
-
9
- /**
10
- * Interface for managing SHIP and SLAP advertisements.
11
- * Provides methods for creating, finding, and revoking advertisements.
12
- */
13
- export interface Advertiser {
14
-
15
- /**
16
- * Creates a new SHIP/SLAP advertisement for a given topic.
17
- * @param adsData - The data indicating the type of advertisement.
18
- * @returns A promise that resolves to the created advertisement as TaggedBEEF.
19
- */
20
- createAdvertisements: (adsData: AdvertisementData[]) => Promise<TaggedBEEF>
21
-
22
- /**
23
- * Finds all SHIP/SLAP advertisements.
24
- * @returns A promise that resolves to an array of SHIP/SLAP advertisements.
25
- */
26
- findAllAdvertisements: (protocol: 'SHIP' | 'SLAP') => Promise<Advertisement[]>
27
-
28
- /**
29
- * Revokes an existing advertisement, either SHIP or SLAP.
30
- * @param advertisements - The advertisements to revoke, either SHIP or SLAP.
31
- * @returns A promise that resolves to the revocation transaction as TaggedBEEF.
32
- */
33
- revokeAdvertisements: (advertisements: Advertisement[]) => Promise<TaggedBEEF>
34
-
35
- /**
36
- * Parses an output script to extract an advertisement.
37
- * @param outputScript - The script of the output to be parsed.
38
- * @returns The parsed advertisement
39
- */
40
- parseAdvertisement: (outputScript: Script) => Advertisement
41
- }
package/src/BASM.ts DELETED
@@ -1,208 +0,0 @@
1
- import { createHash } from 'node:crypto'
2
- import { MerklePath } from '@bsv/sdk'
3
-
4
- export const BASM_ZERO_HASH = '0000000000000000000000000000000000000000000000000000000000000000'
5
-
6
- export interface TopicBlockAnchor {
7
- topic: string
8
- blockHeight: number
9
- blockHash: string
10
- basmRoot: string
11
- admittedCount: number
12
- tac: string
13
- }
14
-
15
- export interface TopicAnchorTip {
16
- topic: string
17
- blockHeight: number
18
- blockHash?: string
19
- basmRoot?: string
20
- admittedCount?: number
21
- tac: string
22
- }
23
-
24
- export interface AdmittedTxRef {
25
- txid: string
26
- blockIndex: number
27
- }
28
-
29
- export interface RawTransactionRecord {
30
- txid: string
31
- rawTx: string
32
- }
33
-
34
- export interface RawTransactionRequest {
35
- txids: string[]
36
- }
37
-
38
- export interface RawTransactionResponse {
39
- transactions: RawTransactionRecord[]
40
- missing: string[]
41
- }
42
-
43
- export interface TopicAnchorHeader {
44
- blockHeight: number
45
- blockHash: string
46
- merkleRoot?: string
47
- }
48
-
49
- export type TopicAnchorHeaderResolver = (blockHeight: number) => Promise<TopicAnchorHeader | undefined>
50
-
51
- export interface TopicAnchorRangeRequest {
52
- fromHeight: number
53
- toHeight: number
54
- }
55
-
56
- export interface TopicAnchorRangeResponse {
57
- topic: string
58
- anchors: TopicBlockAnchor[]
59
- }
60
-
61
- export interface AdmittedListRequest {
62
- blockHeight: number
63
- blockHash?: string
64
- }
65
-
66
- export interface AdmittedListResponse {
67
- topic: string
68
- blockHeight: number
69
- blockHash?: string
70
- admitted: AdmittedTxRef[]
71
- }
72
-
73
- export interface CompoundMerklePathRequest {
74
- blockHeight: number
75
- txids: string[]
76
- }
77
-
78
- export interface CompoundMerklePathResponse {
79
- topic: string
80
- blockHeight: number
81
- txids: string[]
82
- merklePath: string
83
- }
84
-
85
- export interface MerkleProofMetadata {
86
- blockHeight: number
87
- blockIndex: number
88
- merkleRoot: string
89
- }
90
-
91
- export interface ReorgReport {
92
- perTopic: Array<{
93
- topic: string
94
- demotedTxids: string[]
95
- rebuiltFrom: number
96
- rebuiltTo: number
97
- }>
98
- }
99
-
100
- export interface BASMPeerSyncReport {
101
- topic: string
102
- endpoint: string
103
- status: 'matched' | 'advanced' | 'diverged' | 'skipped' | 'error'
104
- localTip?: TopicAnchorTip
105
- remoteTip?: TopicAnchorTip
106
- checkedHeights: number[]
107
- missingTxids: string[]
108
- fetchedTxCount: number
109
- message?: string
110
- }
111
-
112
- type AdmittedTxLike = string | AdmittedTxRef
113
-
114
- function sha256d(buffer: Buffer): Buffer {
115
- const first = createHash('sha256').update(buffer).digest()
116
- return createHash('sha256').update(first).digest()
117
- }
118
-
119
- function assertHashHex(hash: string, label: string): void {
120
- if (!/^[0-9a-fA-F]{64}$/.test(hash)) {
121
- throw new Error(`${label} must be 32 bytes of hex`)
122
- }
123
- }
124
-
125
- function displayHexToInternal(hash: string): Buffer {
126
- assertHashHex(hash, 'hash')
127
- return Buffer.from(hash, 'hex').reverse()
128
- }
129
-
130
- function internalToDisplayHex(hash: Buffer): string {
131
- return Buffer.from(hash).reverse().toString('hex')
132
- }
133
-
134
- function normalizeAdmittedTxids(admitted: AdmittedTxLike[]): string[] {
135
- return admitted
136
- .map((item, originalIndex) => {
137
- if (typeof item === 'string') {
138
- return { txid: item, blockIndex: originalIndex }
139
- }
140
- return item
141
- })
142
- .sort((a, b) => a.blockIndex - b.blockIndex)
143
- .map(item => item.txid.toLowerCase())
144
- }
145
-
146
- /**
147
- * Computes a BRC-136 BASM root from admitted topic txids.
148
- *
149
- * The API accepts normal display-order txid hex because that is what the BSV
150
- * TypeScript stack exposes at its public boundaries. Hashing is performed on
151
- * internal byte order as required by the BRC, and the returned root is display
152
- * order for JSON/wire compatibility.
153
- */
154
- export function computeBasmRoot(admitted: AdmittedTxLike[]): string {
155
- const txids = normalizeAdmittedTxids(admitted)
156
-
157
- if (txids.length === 0) {
158
- return BASM_ZERO_HASH
159
- }
160
-
161
- let layer = txids.map(txid => displayHexToInternal(txid))
162
- if (layer.length === 1) {
163
- return internalToDisplayHex(layer[0])
164
- }
165
-
166
- while (layer.length > 1) {
167
- const next: Buffer[] = []
168
- for (let i = 0; i < layer.length; i += 2) {
169
- const left = layer[i]
170
- const right = i + 1 < layer.length ? layer[i + 1] : left
171
- next.push(sha256d(Buffer.concat([left, right])))
172
- }
173
- layer = next
174
- }
175
-
176
- return internalToDisplayHex(layer[0])
177
- }
178
-
179
- /**
180
- * Computes the BRC-136 cumulative Topic Anchor Chain hash:
181
- * SHA256d(prevTac || blockHash || basmRoot), with all inputs reversed to
182
- * internal byte order before hashing and the output returned as display hex.
183
- */
184
- export function computeTac(prevTac: string, blockHash: string, basmRoot: string): string {
185
- const input = Buffer.concat([
186
- displayHexToInternal(prevTac.toLowerCase()),
187
- displayHexToInternal(blockHash.toLowerCase()),
188
- displayHexToInternal(basmRoot.toLowerCase())
189
- ])
190
- return internalToDisplayHex(sha256d(input))
191
- }
192
-
193
- export function extractMerkleProofMetadata(txid: string, proof?: MerklePath): MerkleProofMetadata | undefined {
194
- if (proof === undefined) {
195
- return undefined
196
- }
197
-
198
- const leaf = proof.path[0]?.find(candidate => candidate.hash === txid)
199
- if (leaf === undefined) {
200
- return undefined
201
- }
202
-
203
- return {
204
- blockHeight: proof.blockHeight,
205
- blockIndex: leaf.offset,
206
- merkleRoot: proof.computeRoot(txid)
207
- }
208
- }
package/src/BASMRemote.ts DELETED
@@ -1,54 +0,0 @@
1
- import type {
2
- AdmittedListResponse,
3
- CompoundMerklePathResponse,
4
- RawTransactionResponse,
5
- TopicAnchorRangeResponse,
6
- TopicAnchorTip
7
- } from './BASM.js'
8
-
9
- export class BASMRemote {
10
- constructor(
11
- private readonly endpoint: string,
12
- private readonly topic: string,
13
- private readonly fetchImpl: typeof fetch = fetch.bind(globalThis)
14
- ) { }
15
-
16
- async requestTopicAnchorTip(): Promise<TopicAnchorTip> {
17
- return await this.post<TopicAnchorTip>('/requestTopicAnchorTip', {})
18
- }
19
-
20
- async requestTopicAnchorRange(fromHeight: number, toHeight: number): Promise<TopicAnchorRangeResponse> {
21
- return await this.post<TopicAnchorRangeResponse>('/requestTopicAnchorRange', { fromHeight, toHeight })
22
- }
23
-
24
- async requestAdmittedList(blockHeight: number, blockHash?: string): Promise<AdmittedListResponse> {
25
- return await this.post<AdmittedListResponse>('/requestAdmittedList', { blockHeight, blockHash })
26
- }
27
-
28
- async requestCompoundMerklePath(blockHeight: number, txids: string[]): Promise<CompoundMerklePathResponse> {
29
- return await this.post<CompoundMerklePathResponse>('/requestCompoundMerklePath', { blockHeight, txids })
30
- }
31
-
32
- async requestRawTransactions(txids: string[]): Promise<RawTransactionResponse> {
33
- return await this.post<RawTransactionResponse>('/requestRawTransactions', { txids })
34
- }
35
-
36
- private async post<T>(path: string, body: unknown): Promise<T> {
37
- const response = await this.fetchImpl(new URL(path, this.endpoint).toString(), {
38
- method: 'POST',
39
- headers: {
40
- Accept: 'application/json',
41
- 'Content-Type': 'application/json',
42
- 'x-bsv-topic': this.topic
43
- },
44
- body: JSON.stringify(body)
45
- })
46
-
47
- const text = await response.text()
48
- if (!response.ok) {
49
- throw new Error(`BASM peer ${this.endpoint} returned ${response.status}: ${text}`)
50
- }
51
-
52
- return (text.length === 0 ? {} : JSON.parse(text)) as T
53
- }
54
- }