@bsv/overlay 2.2.1 → 2.3.0

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 +379 -0
  19. package/dist/cjs/src/Engine.d.ts.map +1 -0
  20. package/dist/cjs/src/Engine.js +425 -418
  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 +404 -396
  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 +18 -1
  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
package/docs/API.md DELETED
@@ -1,944 +0,0 @@
1
- # API
2
-
3
- [🏠 Home](./README.md) | [📚 API](./API.md) | [💡 Concepts](./concepts/README.md) | [📖 Examples](./examples/README.md) | [⚙️ Internal](./internal/README.md)
4
-
5
- ---
6
-
7
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
8
-
9
- ## Interfaces
10
-
11
- | |
12
- | --- |
13
- | [Advertisement](#interface-advertisement) |
14
- | [AdvertisementData](#interface-advertisementdata) |
15
- | [Advertiser](#interface-advertiser) |
16
- | [AppliedTransaction](#interface-appliedtransaction) |
17
- | [GraphNode](#interface-graphnode) |
18
- | [LookupService](#interface-lookupservice) |
19
- | [LookupServiceMetaData](#interface-lookupservicemetadata) |
20
- | [Output](#interface-output) |
21
- | [Storage](#interface-storage) |
22
- | [TopicManager](#interface-topicmanager) |
23
-
24
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
25
-
26
- ---
27
-
28
- ### Interface: Advertisement
29
-
30
- ```ts
31
- export interface Advertisement {
32
- protocol: "SHIP" | "SLAP";
33
- identityKey: string;
34
- domain: string;
35
- topicOrService: string;
36
- beef?: number[];
37
- outputIndex?: number;
38
- }
39
- ```
40
-
41
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
42
-
43
- ---
44
- ### Interface: AdvertisementData
45
-
46
- ```ts
47
- export interface AdvertisementData {
48
- protocol: "SHIP" | "SLAP";
49
- topicOrServiceName: string;
50
- }
51
- ```
52
-
53
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
54
-
55
- ---
56
- ### Interface: Advertiser
57
-
58
- Interface for managing SHIP and SLAP advertisements.
59
- Provides methods for creating, finding, and revoking advertisements.
60
-
61
- ```ts
62
- export interface Advertiser {
63
- createAdvertisements: (adsData: AdvertisementData[]) => Promise<TaggedBEEF>;
64
- findAllAdvertisements: (protocol: "SHIP" | "SLAP") => Promise<Advertisement[]>;
65
- revokeAdvertisements: (advertisements: Advertisement[]) => Promise<TaggedBEEF>;
66
- parseAdvertisement: (outputScript: Script) => Advertisement;
67
- }
68
- ```
69
-
70
- See also: [Advertisement](#interface-advertisement), [AdvertisementData](#interface-advertisementdata)
71
-
72
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
73
-
74
- ---
75
- ### Interface: AppliedTransaction
76
-
77
- Represents a transaction that has been applied to a topic.
78
-
79
- ```ts
80
- export interface AppliedTransaction {
81
- txid: string;
82
- topic: string;
83
- }
84
- ```
85
-
86
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
87
-
88
- ---
89
- ### Interface: GraphNode
90
-
91
- Represents a node in the temporary graph.
92
-
93
- ```ts
94
- export interface GraphNode {
95
- txid: string;
96
- graphID: string;
97
- rawTx: string;
98
- outputIndex: number;
99
- spentBy?: string;
100
- proof?: string;
101
- txMetadata?: string;
102
- outputMetadata?: string;
103
- inputs?: Record<string, {
104
- hash: string;
105
- }> | undefined;
106
- children: GraphNode[];
107
- parent?: GraphNode;
108
- }
109
- ```
110
-
111
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
112
-
113
- ---
114
- ### Interface: LookupService
115
-
116
- ```ts
117
- export interface LookupService {
118
- readonly admissionMode: AdmissionMode;
119
- readonly spendNotificationMode: SpendNotificationMode;
120
- outputAdmittedByTopic: (payload: OutputAdmittedByTopic) => Promise<void> | void;
121
- outputSpent?: (payload: OutputSpent) => Promise<void> | void;
122
- outputNoLongerRetainedInHistory?: (txid: string, outputIndex: number, topic: string) => Promise<void> | void;
123
- outputEvicted: (txid: string, outputIndex: number) => Promise<void> | void;
124
- lookup: (question: LookupQuestion) => Promise<LookupFormula>;
125
- getDocumentation: () => Promise<string>;
126
- getMetaData: () => Promise<LookupServiceMetaData>;
127
- }
128
- ```
129
-
130
- See also: [AdmissionMode](#type-admissionmode), [LookupFormula](#type-lookupformula), [LookupServiceMetaData](#interface-lookupservicemetadata), [OutputAdmittedByTopic](#type-outputadmittedbytopic), [OutputSpent](#type-outputspent), [SpendNotificationMode](#type-spendnotificationmode)
131
-
132
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
133
-
134
- ---
135
- ### Interface: LookupServiceMetaData
136
-
137
- ```ts
138
- export interface LookupServiceMetaData {
139
- name: string;
140
- shortDescription: string;
141
- iconURL?: string;
142
- version?: string;
143
- informationURL?: string;
144
- }
145
- ```
146
-
147
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
148
-
149
- ---
150
- ### Interface: Output
151
-
152
- Represents an output to be tracked by the Overlay Services Engine
153
-
154
- ```ts
155
- export interface Output {
156
- txid: string;
157
- outputIndex: number;
158
- outputScript: number[];
159
- satoshis: number;
160
- topic: string;
161
- spent: boolean;
162
- outputsConsumed: Array<{
163
- txid: string;
164
- outputIndex: number;
165
- }>;
166
- consumedBy: Array<{
167
- txid: string;
168
- outputIndex: number;
169
- }>;
170
- beef?: number[];
171
- blockHeight?: number;
172
- score?: number;
173
- }
174
- ```
175
-
176
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
177
-
178
- ---
179
- ### Interface: Storage
180
-
181
- Defines the Storage Engine interface used internally by the Overlay Services Engine.
182
-
183
- ```ts
184
- export interface Storage {
185
- insertOutput: (utxo: Output) => Promise<void>;
186
- findOutput: (txid: string, outputIndex: number, topic?: string, spent?: boolean, includeBEEF?: boolean) => Promise<Output | null>;
187
- findOutputsForTransaction: (txid: string, includeBEEF?: boolean) => Promise<Output[]>;
188
- findUTXOsForTopic: (topic: string, since?: number, limit?: number, includeBEEF?: boolean) => Promise<Output[]>;
189
- deleteOutput: (txid: string, outputIndex: number, topic: string) => Promise<void>;
190
- markUTXOAsSpent: (txid: string, outputIndex: number, topic: string) => Promise<void>;
191
- updateConsumedBy: (txid: string, outputIndex: number, topic: string, consumedBy: Array<{
192
- txid: string;
193
- outputIndex: number;
194
- }>) => Promise<void>;
195
- updateTransactionBEEF: (txid: string, beef: number[]) => Promise<void>;
196
- updateOutputBlockHeight?: (txid: string, outputIndex: number, topic: string, blockHeight: number) => Promise<void>;
197
- insertAppliedTransaction: (tx: AppliedTransaction) => Promise<void>;
198
- doesAppliedTransactionExist: (tx: AppliedTransaction) => Promise<boolean>;
199
- updateLastInteraction: (host: string, topic: string, since: number) => Promise<void>;
200
- getLastInteraction: (host: string, topic: string) => Promise<number>;
201
- }
202
- ```
203
-
204
- See also: [AppliedTransaction](#interface-appliedtransaction), [Output](#interface-output)
205
-
206
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
207
-
208
- ---
209
- ### Interface: TopicManager
210
-
211
- Defines a Topic Manager interface that can be implemented for specific use-cases
212
-
213
- ```ts
214
- export interface TopicManager {
215
- identifyAdmissibleOutputs: (beef: number[], previousCoins: number[], offChainValues?: number[], mode?: "historical-tx" | "current-tx" | "historical-tx-no-spv") => Promise<AdmittanceInstructions>;
216
- identifyNeededInputs?: (beef: number[], offChainValues?: number[]) => Promise<Array<{
217
- txid: string;
218
- outputIndex: number;
219
- }>>;
220
- getDocumentation: () => Promise<string>;
221
- getMetaData: () => Promise<{
222
- name: string;
223
- shortDescription: string;
224
- iconURL?: string;
225
- version?: string;
226
- informationURL?: string;
227
- }>;
228
- }
229
- ```
230
-
231
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
232
-
233
- ---
234
- ## Classes
235
-
236
- | |
237
- | --- |
238
- | [Engine](#class-engine) |
239
- | [KnexStorage](#class-knexstorage) |
240
- | [OverlayGASPRemote](#class-overlaygaspremote) |
241
- | [OverlayGASPStorage](#class-overlaygaspstorage) |
242
-
243
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
244
-
245
- ---
246
-
247
- ### Class: Engine
248
-
249
- An engine for running BSV Overlay Services (topic managers and lookup services).
250
-
251
- ```ts
252
- export class Engine {
253
- constructor(public managers: {
254
- [key: string]: TopicManager;
255
- }, public lookupServices: {
256
- [key: string]: LookupService;
257
- }, public storage: Storage, public chainTracker: ChainTracker | "scripts only", public hostingURL?: string, public shipTrackers?: string[], public slapTrackers?: string[], public broadcaster?: Broadcaster, public advertiser?: Advertiser, public syncConfiguration?: SyncConfiguration, public logTime = false, public logPrefix = "[OVERLAY_ENGINE] ", public throwOnBroadcastFailure = false, public overlayBroadcastFacilitator: OverlayBroadcastFacilitator = new HTTPSOverlayBroadcastFacilitator(), public logger: typeof console = console, public suppressDefaultSyncAdvertisements = true)
258
- async submit(taggedBEEF: TaggedBEEF, onSteakReady?: (steak: STEAK) => void, mode: "historical-tx" | "current-tx" | "historical-tx-no-spv" = "current-tx", offChainValues?: number[]): Promise<STEAK>
259
- async lookup(lookupQuestion: LookupQuestion): Promise<LookupAnswer>
260
- async syncAdvertisements(): Promise<void>
261
- async startGASPSync(): Promise<void>
262
- async provideForeignSyncResponse(initialRequest: GASPInitialRequest, topic: string): Promise<GASPInitialResponse>
263
- async provideForeignGASPNode(graphID: string, txid: string, outputIndex: number): Promise<GASPNode>
264
- async getUTXOHistory(output: Output, historySelector?: ((beef: number[], outputIndex: number, currentDepth: number) => Promise<boolean>) | number, currentDepth = 0, context: UTXOHistoryHydrationContext = this.createUTXOHistoryHydrationContext()): Promise<Output | undefined>
265
- async handleNewMerkleProof(txid: string, proof: MerklePath, blockHeight?: number): Promise<void>
266
- async listTopicManagers(): Promise<Record<string, {
267
- name: string;
268
- shortDescription: string;
269
- iconURL?: string;
270
- version?: string;
271
- informationURL?: string;
272
- }>>
273
- async listLookupServiceProviders(): Promise<Record<string, {
274
- name: string;
275
- shortDescription: string;
276
- iconURL?: string;
277
- version?: string;
278
- informationURL?: string;
279
- }>>
280
- async getDocumentationForTopicManager(manager: any): Promise<string>
281
- async getDocumentationForLookupServiceProvider(provider: any): Promise<string>
282
- }
283
- ```
284
-
285
- See also: [Advertiser](#interface-advertiser), [LookupService](#interface-lookupservice), [Output](#interface-output), [Storage](#interface-storage), [SyncConfiguration](#type-syncconfiguration), [TopicManager](#interface-topicmanager)
286
-
287
- <details>
288
-
289
- <summary>Class Engine Details</summary>
290
-
291
- #### Constructor
292
-
293
- Creates a new Overlay Services Engine
294
-
295
- ```ts
296
- constructor(public managers: {
297
- [key: string]: TopicManager;
298
- }, public lookupServices: {
299
- [key: string]: LookupService;
300
- }, public storage: Storage, public chainTracker: ChainTracker | "scripts only", public hostingURL?: string, public shipTrackers?: string[], public slapTrackers?: string[], public broadcaster?: Broadcaster, public advertiser?: Advertiser, public syncConfiguration?: SyncConfiguration, public logTime = false, public logPrefix = "[OVERLAY_ENGINE] ", public throwOnBroadcastFailure = false, public overlayBroadcastFacilitator: OverlayBroadcastFacilitator = new HTTPSOverlayBroadcastFacilitator(), public logger: typeof console = console, public suppressDefaultSyncAdvertisements = true)
301
- ```
302
- See also: [Advertiser](#interface-advertiser), [LookupService](#interface-lookupservice), [Storage](#interface-storage), [SyncConfiguration](#type-syncconfiguration), [TopicManager](#interface-topicmanager)
303
-
304
- Argument Details
305
-
306
- + ****
307
- + : TopicManager} managers - manages topic admittance
308
- + ****
309
- + : LookupService} lookupServices - manages UTXO lookups
310
- + **storage**
311
- + for interacting with internally-managed persistent data
312
- + **chainTracker**
313
- + Verifies SPV data associated with transactions
314
- + **hostingURL**
315
- + The URL this engine is hosted at. Required if going to support peer-discovery with an advertiser.
316
- + **Broadcaster**
317
- + broadcaster used for broadcasting the incoming transaction
318
- + **Advertiser**
319
- + handles SHIP and SLAP advertisements for peer-discovery
320
- + **shipTrackers**
321
- + SHIP domains we know to bootstrap the system
322
- + **slapTrackers**
323
- + SLAP domains we know to bootstrap the system
324
- + **syncConfiguration**
325
- + — Configuration object describing historical synchronization of topics.
326
- + **logTime**
327
- + Enables / disables the timing logs for various operations in the Overlay submit route.
328
- + **logPrefix**
329
- + Supports overriding the log prefix with a custom string.
330
- + **throwOnBroadcastFailure**
331
- + Enables / disables throwing an error when a transaction broadcast failure is detected.
332
- + **overlayBroadcastFacilitator**
333
- + Facilitator for propagation to other Overlay Services.
334
- + **logger**
335
- + The place where log entries are written.
336
- + **suppressDefaultSyncAdvertisements**
337
- + Whether to suppress the default (SHIP/SLAP) sync advertisements.
338
-
339
- #### Method getDocumentationForLookupServiceProvider
340
-
341
- Run a query to get the documentation for a particular lookup service
342
-
343
- ```ts
344
- async getDocumentationForLookupServiceProvider(provider: any): Promise<string>
345
- ```
346
-
347
- Returns
348
-
349
- - the documentation for the lookup service
350
-
351
- #### Method getDocumentationForTopicManager
352
-
353
- Run a query to get the documentation for a particular topic manager
354
-
355
- ```ts
356
- async getDocumentationForTopicManager(manager: any): Promise<string>
357
- ```
358
-
359
- Returns
360
-
361
- - the documentation for the topic manager
362
-
363
- #### Method getUTXOHistory
364
-
365
- Traverse and return the history of a UTXO.
366
-
367
- This method traverses the history of a given Unspent Transaction Output (UTXO) and returns
368
- its historical data based on the provided history selector and current depth.
369
-
370
- ```ts
371
- async getUTXOHistory(output: Output, historySelector?: ((beef: number[], outputIndex: number, currentDepth: number) => Promise<boolean>) | number, currentDepth = 0, context: UTXOHistoryHydrationContext = this.createUTXOHistoryHydrationContext()): Promise<Output | undefined>
372
- ```
373
- See also: [Output](#interface-output)
374
-
375
- Returns
376
-
377
- - A promise that resolves to the output history if found, or undefined if not.
378
-
379
- Argument Details
380
-
381
- + **output**
382
- + The UTXO to traverse the history for.
383
- + **historySelector**
384
- + Optionally directs the history traversal:
385
- - If a number, denotes how many previous spends (in terms of chain depth) to include.
386
- - If a function, accepts a BEEF-formatted transaction, an output index, and the current depth as parameters,
387
- returning a promise that resolves to a boolean indicating whether to include the output in the history.
388
- + **currentDepth**
389
- + The current depth of the traversal relative to the top-level UTXO.
390
-
391
- #### Method handleNewMerkleProof
392
-
393
- Recursively prune UTXOs when an incoming Merkle Proof is received.
394
-
395
- ```ts
396
- async handleNewMerkleProof(txid: string, proof: MerklePath, blockHeight?: number): Promise<void>
397
- ```
398
-
399
- Argument Details
400
-
401
- + **txid**
402
- + Transaction ID of the associated outputs to prune.
403
- + **proof**
404
- + Merkle proof containing the Merkle path and other relevant data to verify the transaction.
405
- + **blockHeight**
406
- + The block height associated with the incoming merkle proof.
407
-
408
- #### Method listLookupServiceProviders
409
-
410
- Find a list of supported lookup services
411
-
412
- ```ts
413
- async listLookupServiceProviders(): Promise<Record<string, {
414
- name: string;
415
- shortDescription: string;
416
- iconURL?: string;
417
- version?: string;
418
- informationURL?: string;
419
- }>>
420
- ```
421
-
422
- Returns
423
-
424
- - Supported lookup services and their metadata
425
-
426
- #### Method listTopicManagers
427
-
428
- Find a list of supported topic managers
429
-
430
- ```ts
431
- async listTopicManagers(): Promise<Record<string, {
432
- name: string;
433
- shortDescription: string;
434
- iconURL?: string;
435
- version?: string;
436
- informationURL?: string;
437
- }>>
438
- ```
439
-
440
- Returns
441
-
442
- - Supported topic managers and their metadata
443
-
444
- #### Method lookup
445
-
446
- Submit a lookup question to the Overlay Services Engine, and receive back a Lookup Answer
447
-
448
- ```ts
449
- async lookup(lookupQuestion: LookupQuestion): Promise<LookupAnswer>
450
- ```
451
-
452
- Returns
453
-
454
- The answer to the question
455
-
456
- Argument Details
457
-
458
- + **LookupQuestion**
459
- + — The question to ask the Overlay Services Engine
460
-
461
- #### Method provideForeignGASPNode
462
-
463
- Provides a GASPNode for the given graphID, transaction ID, and output index.
464
-
465
- ```ts
466
- async provideForeignGASPNode(graphID: string, txid: string, outputIndex: number): Promise<GASPNode>
467
- ```
468
-
469
- Returns
470
-
471
- A promise that resolves to a GASPNode containing the raw transaction and other optional data.
472
-
473
- Argument Details
474
-
475
- + **graphID**
476
- + The identifier for the graph to which this node belongs (in the format txid.outputIndex).
477
- + **txid**
478
- + The transaction ID for the requested output from somewhere within the graph's history.
479
- + **outputIndex**
480
- + The index of the output in the transaction.
481
-
482
- Throws
483
-
484
- An error if no output is found for the given transaction ID and output index.
485
-
486
- #### Method provideForeignSyncResponse
487
-
488
- Given a GASP request, create an initial response.
489
-
490
- This method processes an initial synchronization request by finding the relevant UTXOs for the given topic
491
- since the provided block height in the request. It constructs a response that includes a list of these UTXOs
492
- and the min block height from the initial request.
493
-
494
- ```ts
495
- async provideForeignSyncResponse(initialRequest: GASPInitialRequest, topic: string): Promise<GASPInitialResponse>
496
- ```
497
-
498
- Returns
499
-
500
- A promise that resolves to a GASPInitialResponse containing the list of UTXOs and the provided min block height.
501
-
502
- Argument Details
503
-
504
- + **initialRequest**
505
- + The GASP initial request containing the version and the block height since the last sync.
506
- + **topic**
507
- + The topic for which UTXOs are being requested.
508
-
509
- #### Method startGASPSync
510
-
511
- This method goes through each topic that we support syncing and attempts to sync with each endpoint
512
- associated with that topic. If the sync configuration is 'SHIP', it will sync to all peers that support
513
- the topic.
514
-
515
- ```ts
516
- async startGASPSync(): Promise<void>
517
- ```
518
-
519
- Throws
520
-
521
- Error if the overlay service engine is not configured for topical synchronization.
522
-
523
- #### Method submit
524
-
525
- Submits a transaction for processing by Overlay Services.
526
-
527
- ```ts
528
- async submit(taggedBEEF: TaggedBEEF, onSteakReady?: (steak: STEAK) => void, mode: "historical-tx" | "current-tx" | "historical-tx-no-spv" = "current-tx", offChainValues?: number[]): Promise<STEAK>
529
- ```
530
-
531
- Returns
532
-
533
- The submitted transaction execution acknowledgement
534
-
535
- Argument Details
536
-
537
- + **taggedBEEF**
538
- + The transaction to process
539
- + **onSTEAKReady**
540
- + Optional callback function invoked when the STEAK is ready.
541
- + **mode**
542
- + — Indicates the submission behavior, whether historical or current. Historical transactions are not broadcast or propagated.
543
- + **offChainValues**
544
- + — Values necessary to evaluate topical admittance that are not stored on-chain.
545
-
546
- The optional callback function should be used to get STEAK when ready, and avoid waiting for broadcast and transaction propagation to complete.
547
-
548
- #### Method syncAdvertisements
549
-
550
- Ensures alignment between the current SHIP/SLAP advertisements and the
551
- configured Topic Managers and Lookup Services in the engine.
552
-
553
- This method performs the following actions:
554
- 1. Retrieves the current configuration of topics and services.
555
- 2. Fetches the existing SHIP advertisements for each configured topic.
556
- 3. Fetches the existing SLAP advertisements for each configured service.
557
- 4. Compares the current configuration with the fetched advertisements to determine which advertisements
558
- need to be created or revoked.
559
- 5. Creates new SHIP/SLAP advertisements if they do not exist for the configured topics/services.
560
- 6. Revokes existing SHIP/SLAP advertisements if they are no longer required based on the current configuration.
561
-
562
- The function uses the `Advertiser` methods to create or revoke advertisements and ensures the updates are
563
- submitted to the SHIP/SLAP overlay networks using the engine's `submit()` method.
564
-
565
- ```ts
566
- async syncAdvertisements(): Promise<void>
567
- ```
568
-
569
- Returns
570
-
571
- A promise that resolves when the synchronization process is complete.
572
-
573
- Throws
574
-
575
- Will throw an error if there are issues during the advertisement synchronization process.
576
-
577
- </details>
578
-
579
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
580
-
581
- ---
582
- ### Class: KnexStorage
583
-
584
- ```ts
585
- export class KnexStorage implements Storage {
586
- knex: Knex;
587
- constructor(knex: Knex)
588
- async findOutput(txid: string, outputIndex: number, topic?: string, spent?: boolean, includeBEEF: boolean = false): Promise<Output | null>
589
- async findOutputsForTransaction(txid: string, includeBEEF: boolean = false): Promise<Output[]>
590
- async findUTXOsForTopic(topic: string, since?: number, limit?: number, includeBEEF: boolean = false): Promise<Output[]>
591
- async deleteOutput(txid: string, outputIndex: number, _: string): Promise<void>
592
- async insertOutput(output: Output): Promise<void>
593
- async markUTXOAsSpent(txid: string, outputIndex: number, topic?: string): Promise<void>
594
- async updateConsumedBy(txid: string, outputIndex: number, topic: string, consumedBy: Array<{
595
- txid: string;
596
- outputIndex: number;
597
- }>): Promise<void>
598
- async updateTransactionBEEF(txid: string, beef: number[]): Promise<void>
599
- async updateOutputBlockHeight(txid: string, outputIndex: number, topic: string, blockHeight: number): Promise<void>
600
- async insertAppliedTransaction(tx: {
601
- txid: string;
602
- topic: string;
603
- }): Promise<void>
604
- async doesAppliedTransactionExist(tx: {
605
- txid: string;
606
- topic: string;
607
- }): Promise<boolean>
608
- async updateLastInteraction(host: string, topic: string, since: number): Promise<void>
609
- async getLastInteraction(host: string, topic: string): Promise<number>
610
- }
611
- ```
612
-
613
- See also: [Output](#interface-output), [Storage](#interface-storage)
614
-
615
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
616
-
617
- ---
618
- ### Class: OverlayGASPRemote
619
-
620
- ```ts
621
- export class OverlayGASPRemote implements GASPRemote {
622
- constructor(public endpointURL: string, public topic: string)
623
- async getInitialResponse(request: GASPInitialRequest): Promise<GASPInitialResponse>
624
- async requestNode(graphID: string, txid: string, outputIndex: number, metadata: boolean): Promise<GASPNode>
625
- async getInitialReply(response: GASPInitialResponse): Promise<GASPInitialReply>
626
- async submitNode(node: GASPNode): Promise<GASPNodeResponse | undefined>
627
- }
628
- ```
629
-
630
- <details>
631
-
632
- <summary>Class OverlayGASPRemote Details</summary>
633
-
634
- #### Method getInitialResponse
635
-
636
- Given an outgoing initial request, sends the request to the foreign instance and obtains their initial response.
637
-
638
- ```ts
639
- async getInitialResponse(request: GASPInitialRequest): Promise<GASPInitialResponse>
640
- ```
641
-
642
- #### Method requestNode
643
-
644
- Given an outgoing txid, outputIndex and optional metadata, request the associated GASP node from the foreign instance.
645
-
646
- ```ts
647
- async requestNode(graphID: string, txid: string, outputIndex: number, metadata: boolean): Promise<GASPNode>
648
- ```
649
-
650
- </details>
651
-
652
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
653
-
654
- ---
655
- ### Class: OverlayGASPStorage
656
-
657
- ```ts
658
- export class OverlayGASPStorage implements GASPStorage {
659
- readonly temporaryGraphNodeRefs: Record<string, GraphNode> = {};
660
- constructor(public topic: string, public engine: Engine, public maxNodesInGraph?: number)
661
- async findKnownUTXOs(since: number): Promise<GASPOutput[]>
662
- async hydrateGASPNode(graphID: string, txid: string, outputIndex: number, metadata: boolean): Promise<GASPNode>
663
- async findNeededInputs(tx: GASPNode): Promise<GASPNodeResponse | undefined>
664
- async appendToGraph(tx: GASPNode, spentBy?: string | undefined): Promise<void>
665
- async validateGraphAnchor(graphID: string): Promise<void>
666
- async discardGraph(graphID: string): Promise<void>
667
- async finalizeGraph(graphID: string): Promise<void>
668
- }
669
- ```
670
-
671
- See also: [Engine](#class-engine), [GraphNode](#interface-graphnode)
672
-
673
- <details>
674
-
675
- <summary>Class OverlayGASPStorage Details</summary>
676
-
677
- #### Method appendToGraph
678
-
679
- Appends a new node to a temporary graph.
680
-
681
- ```ts
682
- async appendToGraph(tx: GASPNode, spentBy?: string | undefined): Promise<void>
683
- ```
684
-
685
- Argument Details
686
-
687
- + **tx**
688
- + The node to append to this graph.
689
- + **spentBy**
690
- + Unless this is the same node identified by the graph ID, denotes the TXID and input index for the node which spent this one, in 36-byte format.
691
-
692
- Throws
693
-
694
- If the node cannot be appended to the graph, either because the graph ID is for a graph the recipient does not want or because the graph has grown to be too large before being finalized.
695
-
696
- #### Method discardGraph
697
-
698
- Deletes all data associated with a temporary graph that has failed to sync, if the graph exists.
699
-
700
- ```ts
701
- async discardGraph(graphID: string): Promise<void>
702
- ```
703
-
704
- Argument Details
705
-
706
- + **graphID**
707
- + The TXID and output index (in 36-byte format) for the UTXO at the tip of this graph.
708
-
709
- #### Method finalizeGraph
710
-
711
- Finalizes a graph, solidifying the new UTXO and its ancestors so that it will appear in the list of known UTXOs.
712
-
713
- ```ts
714
- async finalizeGraph(graphID: string): Promise<void>
715
- ```
716
-
717
- Argument Details
718
-
719
- + **graphID**
720
- + The TXID and output index (in 36-byte format) for the UTXO at the root of this graph.
721
-
722
- #### Method findNeededInputs
723
-
724
- For a given node, returns the inputs needed to complete the graph, including whether updated metadata is requested for those inputs.
725
-
726
- ```ts
727
- async findNeededInputs(tx: GASPNode): Promise<GASPNodeResponse | undefined>
728
- ```
729
-
730
- Returns
731
-
732
- A promise for a mapping of requested input transactions and whether metadata should be provided for each.
733
-
734
- Argument Details
735
-
736
- + **tx**
737
- + The node for which needed inputs should be found.
738
-
739
- #### Method hydrateGASPNode
740
-
741
- For a given txid and output index, returns the associated transaction, a merkle proof if the transaction is in a block, and metadata if if requested. If no metadata is requested, metadata hashes on inputs are not returned.
742
-
743
- ```ts
744
- async hydrateGASPNode(graphID: string, txid: string, outputIndex: number, metadata: boolean): Promise<GASPNode>
745
- ```
746
-
747
- #### Method validateGraphAnchor
748
-
749
- Checks whether the given graph, in its current state, makes reference only to transactions that are proven in the blockchain, or already known by the recipient to be valid.
750
- Additionally, in a breadth-first manner (ensuring that all inputs for any given node are processed before nodes that spend them), it ensures that the root node remains valid according to the rules of the overlay's topic manager,
751
- while considering any coins which the Manager had previously indicated were either valid or invalid.
752
-
753
- ```ts
754
- async validateGraphAnchor(graphID: string): Promise<void>
755
- ```
756
-
757
- Argument Details
758
-
759
- + **graphID**
760
- + The TXID and output index (in 36-byte format) for the UTXO at the tip of this graph.
761
-
762
- Throws
763
-
764
- If the graph is not well-anchored, according to the rules of Bitcoin or the rules of the Overlay Topic Manager.
765
-
766
- </details>
767
-
768
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
769
-
770
- ---
771
- ## Functions
772
-
773
- | |
774
- | --- |
775
- | [down](#function-down) |
776
- | [up](#function-up) |
777
-
778
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
779
-
780
- ---
781
-
782
- ### Function: down
783
-
784
- ```ts
785
- export async function down(knex: Knex): Promise<void>
786
- ```
787
-
788
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
789
-
790
- ---
791
- ### Function: up
792
-
793
- Adds optimized index for findUTXOsForTopic queries.
794
- This query pattern is: WHERE topic = ? AND spent = false ORDER BY score
795
- The composite index (topic, spent, score) enables efficient range scans.
796
-
797
- ```ts
798
- export async function up(knex: Knex): Promise<void>
799
- ```
800
-
801
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
802
-
803
- ---
804
- ## Types
805
-
806
- | |
807
- | --- |
808
- | [AdmissionMode](#type-admissionmode) |
809
- | [LookupFormula](#type-lookupformula) |
810
- | [OutputAdmittedByTopic](#type-outputadmittedbytopic) |
811
- | [OutputSpent](#type-outputspent) |
812
- | [SpendNotificationMode](#type-spendnotificationmode) |
813
- | [SyncConfiguration](#type-syncconfiguration) |
814
-
815
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
816
-
817
- ---
818
-
819
- ### Type: AdmissionMode
820
-
821
- ```ts
822
- export type AdmissionMode = "locking-script" | "whole-tx"
823
- ```
824
-
825
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
826
-
827
- ---
828
- ### Type: LookupFormula
829
-
830
- The formula that will be used by the Overlay Services Engine to compute the Lookup Answer. Can be returned by Lookup Services in response to a Lookup Question.
831
-
832
- ```ts
833
- export type LookupFormula = Array<{
834
- txid: string;
835
- outputIndex: number;
836
- history?: ((beef: number[], outputIndex: number, currentDepth: number) => Promise<boolean>) | number;
837
- context?: number[];
838
- }>
839
- ```
840
-
841
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
842
-
843
- ---
844
- ### Type: OutputAdmittedByTopic
845
-
846
- ```ts
847
- export type OutputAdmittedByTopic = {
848
- mode: "locking-script";
849
- txid: string;
850
- outputIndex: number;
851
- topic: string;
852
- satoshis: number;
853
- lockingScript: Script;
854
- offChainValues?: number[];
855
- } | {
856
- mode: "whole-tx";
857
- atomicBEEF: number[];
858
- outputIndex: number;
859
- topic: string;
860
- offChainValues?: number[];
861
- }
862
- ```
863
-
864
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
865
-
866
- ---
867
- ### Type: OutputSpent
868
-
869
- ```ts
870
- export type OutputSpent = {
871
- mode: "none";
872
- txid: string;
873
- outputIndex: number;
874
- topic: string;
875
- } | {
876
- mode: "txid";
877
- txid: string;
878
- outputIndex: number;
879
- topic: string;
880
- spendingTxid: string;
881
- } | {
882
- mode: "script";
883
- txid: string;
884
- outputIndex: number;
885
- topic: string;
886
- spendingTxid: string;
887
- inputIndex: number;
888
- unlockingScript: Script;
889
- sequenceNumber: number;
890
- offChainValues?: number[];
891
- } | {
892
- mode: "whole-tx";
893
- txid: string;
894
- outputIndex: number;
895
- topic: string;
896
- spendingAtomicBEEF: number[];
897
- offChainValues?: number[];
898
- }
899
- ```
900
-
901
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
902
-
903
- ---
904
- ### Type: SpendNotificationMode
905
-
906
- ```ts
907
- export type SpendNotificationMode = "none" | "txid" | "script" | "whole-tx"
908
- ```
909
-
910
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
911
-
912
- ---
913
- ### Type: SyncConfiguration
914
-
915
- Configuration for synchronizing supported topic managers.
916
-
917
- This configuration determines which topics should support synchronization and specifies the mode of synchronization.
918
-
919
- There are two synchronization modes:
920
- 1. Sync to predefined hardcoded peers for the specified topic, including associated hosting URLs.
921
- 2. Use SHIP (Service Host Interconnect Protocol) to sync with all known peers that support the specified topic.
922
-
923
- Each entry in the configuration object maps a topic to either an array of overlay service peers (hardcoded URLs) or the string 'SHIP' (for dynamic syncing using SHIP).
924
-
925
- Example
926
-
927
- ```ts
928
- // Example usage of SyncConfiguration
929
- const config: SyncConfiguration = {
930
- "topicManager1": ["http://peer1.com", "http://peer2.com"],
931
- "topicManager2": "SHIP"
932
- }
933
- ```
934
-
935
- ```ts
936
- export type SyncConfiguration = Record<string, string[] | "SHIP" | false>
937
- ```
938
-
939
- Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types)
940
-
941
- ---
942
-
943
- [🏠 Home](./README.md) | [📚 API](./API.md) | [💡 Concepts](./concepts/README.md) | [📖 Examples](./examples/README.md) | [⚙️ Internal](./internal/README.md)
944
-