@bsv/overlay 0.1.15 → 0.1.16
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.
- package/dist/cjs/mod.js.map +1 -1
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/Engine.js +81 -118
- package/dist/cjs/src/Engine.js.map +1 -1
- package/dist/cjs/src/SHIPAdvertisement.js +3 -0
- package/dist/cjs/src/SHIPAdvertisement.js.map +1 -0
- package/dist/cjs/src/SLAPAdvertisement.js +3 -0
- package/dist/cjs/src/SLAPAdvertisement.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/src/Engine.js +84 -115
- package/dist/esm/src/Engine.js.map +1 -1
- package/dist/esm/src/SHIPAdvertisement.js +2 -0
- package/dist/esm/src/SHIPAdvertisement.js.map +1 -0
- package/dist/esm/src/SLAPAdvertisement.js +2 -0
- package/dist/esm/src/SLAPAdvertisement.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/mod.d.ts +2 -6
- package/dist/types/mod.d.ts.map +1 -1
- package/dist/types/src/Advertiser.d.ts +1 -2
- package/dist/types/src/Advertiser.d.ts.map +1 -1
- package/dist/types/src/Engine.d.ts +27 -15
- package/dist/types/src/Engine.d.ts.map +1 -1
- package/dist/types/src/LookupService.d.ts +1 -3
- package/dist/types/src/LookupService.d.ts.map +1 -1
- package/dist/types/src/SHIPAdvertisement.d.ts +9 -0
- package/dist/types/src/SHIPAdvertisement.d.ts.map +1 -0
- package/dist/types/src/SLAPAdvertisement.d.ts +9 -0
- package/dist/types/src/SLAPAdvertisement.d.ts.map +1 -0
- package/dist/types/src/TopicManager.d.ts +1 -1
- package/dist/types/src/TopicManager.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/API.md +736 -212
- package/mod.ts +2 -6
- package/package.json +2 -2
- package/src/Advertiser.ts +1 -2
- package/src/Engine.ts +123 -127
- package/src/LookupService.ts +1 -3
- package/src/TopicManager.ts +1 -1
- package/src/__tests/Engine.test.ts +1 -5
- package/src/AdmittanceInstructions.ts +0 -14
- package/src/LookupAnswer.ts +0 -14
- package/src/LookupQuestion.ts +0 -15
- package/src/STEAK.ts +0 -10
- package/src/TaggedBEEF.ts +0 -10
package/mod.ts
CHANGED
|
@@ -6,14 +6,10 @@ export type { TopicManager } from "./src/TopicManager.js"
|
|
|
6
6
|
// Interfaces and structures
|
|
7
7
|
export type { Storage, AppliedTransaction } from "./src/storage/Storage.js"
|
|
8
8
|
export type { Output } from './src/Output.js'
|
|
9
|
-
export type { AdmittanceInstructions } from '
|
|
10
|
-
export type { TaggedBEEF } from './src/TaggedBEEF.js'
|
|
11
|
-
export type { STEAK } from './src/STEAK.js'
|
|
12
|
-
export type { LookupQuestion } from './src/LookupQuestion.js'
|
|
9
|
+
export type { TaggedBEEF, STEAK, LookupQuestion, LookupAnswer, AdmittanceInstructions } from '@bsv/sdk'
|
|
13
10
|
export type { LookupFormula } from './src/LookupFormula.js'
|
|
14
|
-
export type { LookupAnswer } from './src/LookupAnswer.js'
|
|
15
11
|
export type { Advertisement } from './src/Advertisement.js'
|
|
16
|
-
export type { AdvertisementData } from './src/Advertiser.js'
|
|
12
|
+
export type { AdvertisementData, Advertiser } from './src/Advertiser.js'
|
|
17
13
|
|
|
18
14
|
// The Knex storage system
|
|
19
15
|
export { KnexStorage } from './src/storage/knex/KnexStorage.js'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsv/overlay",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "BSV Blockchain Overlay Services Engine",
|
|
6
6
|
"main": "dist/cjs/mod.js",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@bsv/gasp": "^0.1.2",
|
|
76
|
-
"@bsv/sdk": "^1.
|
|
76
|
+
"@bsv/sdk": "^1.2.3",
|
|
77
77
|
"knex": "^3.1.0"
|
|
78
78
|
}
|
|
79
79
|
}
|
package/src/Advertiser.ts
CHANGED
package/src/Engine.ts
CHANGED
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
import { TopicManager } from './TopicManager.js'
|
|
2
2
|
import { LookupService } from './LookupService.js'
|
|
3
3
|
import { Storage } from './storage/Storage.js'
|
|
4
|
-
import type { AdmittanceInstructions } from './AdmittanceInstructions.js'
|
|
5
4
|
import type { Output } from './Output.js'
|
|
6
|
-
import { TaggedBEEF } from './TaggedBEEF.js'
|
|
7
|
-
import { STEAK } from './STEAK.js'
|
|
8
|
-
import { LookupQuestion } from './LookupQuestion.js'
|
|
9
|
-
import { LookupAnswer } from './LookupAnswer.js'
|
|
10
5
|
import { LookupFormula } from './LookupFormula.js'
|
|
11
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
Transaction,
|
|
8
|
+
ChainTracker,
|
|
9
|
+
MerklePath,
|
|
10
|
+
Broadcaster,
|
|
11
|
+
isBroadcastFailure,
|
|
12
|
+
TaggedBEEF, STEAK,
|
|
13
|
+
LookupQuestion,
|
|
14
|
+
LookupAnswer,
|
|
15
|
+
AdmittanceInstructions,
|
|
16
|
+
SHIPBroadcaster,
|
|
17
|
+
HTTPSOverlayBroadcastFacilitator,
|
|
18
|
+
LookupResolver,
|
|
19
|
+
LookupResolverConfig,
|
|
20
|
+
OverlayBroadcastFacilitator
|
|
21
|
+
} from '@bsv/sdk'
|
|
12
22
|
import { AdvertisementData, Advertiser } from './Advertiser.js'
|
|
13
23
|
import { GASP, GASPInitialRequest, GASPInitialResponse, GASPNode } from '@bsv/gasp'
|
|
14
24
|
import { SyncConfiguration } from './SyncConfiguration.js'
|
|
15
|
-
import { Advertisement } from './Advertisement.js'
|
|
16
25
|
import { OverlayGASPRemote } from './GASP/OverlayGASPRemote.js'
|
|
17
26
|
import { OverlayGASPStorage } from './GASP/OverlayGASPStorage.js'
|
|
18
27
|
import { URL } from "url"
|
|
19
28
|
|
|
20
29
|
/**
|
|
21
|
-
*
|
|
30
|
+
* An engine for running BSV Overlay Services (topic managers and lookup services).
|
|
22
31
|
*/
|
|
23
32
|
export class Engine {
|
|
24
33
|
/**
|
|
@@ -30,12 +39,14 @@ export class Engine {
|
|
|
30
39
|
* @param {string} [hostingURL] - The URL this engine is hosted at. Required if going to support peer-discovery with an advertiser.
|
|
31
40
|
* @param {Broadcaster} [Broadcaster] - broadcaster used for broadcasting the incoming transaction
|
|
32
41
|
* @param {Advertiser} [Advertiser] - handles SHIP and SLAP advertisements for peer-discovery
|
|
33
|
-
* @param {string} shipTrackers - SHIP domains we know to bootstrap the system
|
|
34
|
-
* @param {string} slapTrackers - SLAP domains we know to bootstrap the system
|
|
42
|
+
* @param {string[]} shipTrackers - SHIP domains we know to bootstrap the system
|
|
43
|
+
* @param {string[]} slapTrackers - SLAP domains we know to bootstrap the system
|
|
35
44
|
* @param {SyncConfiguration} syncConfiguration — Configuration object describing historical synchronization of topics.
|
|
36
45
|
* @param {boolean} logTime - Enables / disables the timing logs for various operations in the Overlay submit route.
|
|
37
46
|
* @param {string} logPrefix - Supports overriding the log prefix with a custom string.
|
|
38
47
|
* @param {boolean} throwOnBroadcastFailure - Enables / disables throwing an error when a transaction broadcast failure is detected.
|
|
48
|
+
* @param {OverlayBroadcastFacilitator} overlayBroadcastFacilitator - Facilitator for propagation to other Overlay Services.
|
|
49
|
+
* @param {typeof console} logger - The place where log entries are written.
|
|
39
50
|
*/
|
|
40
51
|
constructor(
|
|
41
52
|
public managers: { [key: string]: TopicManager },
|
|
@@ -50,7 +61,9 @@ export class Engine {
|
|
|
50
61
|
public syncConfiguration?: SyncConfiguration,
|
|
51
62
|
public logTime = false,
|
|
52
63
|
public logPrefix = '[OVERLAY_ENGINE] ',
|
|
53
|
-
public throwOnBroadcastFailure = false
|
|
64
|
+
public throwOnBroadcastFailure = false,
|
|
65
|
+
public overlayBroadcastFacilitator: OverlayBroadcastFacilitator = new HTTPSOverlayBroadcastFacilitator(),
|
|
66
|
+
public logger: typeof console = console
|
|
54
67
|
) {
|
|
55
68
|
// To encourage synchronization of overlay services, the SHIP sync strategy is used by default for all overlay topics, except for 'tm_ship' and 'tm_slap'.
|
|
56
69
|
// For these two topics, any existing trackers are combined with the provided shipTrackers and slapTrackers omitting any duplicates.
|
|
@@ -87,13 +100,13 @@ export class Engine {
|
|
|
87
100
|
// Helper functions for logging timings
|
|
88
101
|
private startTime(label: string): void {
|
|
89
102
|
if (this.logTime) {
|
|
90
|
-
|
|
103
|
+
this.logger.time(`${this.logPrefix} ${label}`)
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
106
|
|
|
94
107
|
private endTime(label: string): void {
|
|
95
108
|
if (this.logTime) {
|
|
96
|
-
|
|
109
|
+
this.logger.timeEnd(`${this.logPrefix} ${label}`)
|
|
97
110
|
}
|
|
98
111
|
}
|
|
99
112
|
|
|
@@ -125,7 +138,6 @@ export class Engine {
|
|
|
125
138
|
this.endTime(`chainTracker_${txid.substring(0, 10)}`)
|
|
126
139
|
|
|
127
140
|
const steak: STEAK = {}
|
|
128
|
-
let admissibleOutputs: AdmittanceInstructions = { outputsToAdmit: [], coinsToRetain: [] }
|
|
129
141
|
const previousCoins: number[] = []
|
|
130
142
|
|
|
131
143
|
// Parallelize the topic processing
|
|
@@ -169,15 +181,16 @@ export class Engine {
|
|
|
169
181
|
try {
|
|
170
182
|
await l.outputSpent?.(output.txid, output.outputIndex, topic)
|
|
171
183
|
} catch (error) {
|
|
172
|
-
|
|
184
|
+
this.logger.error('Error in lookup service for outputSpent:', error)
|
|
173
185
|
}
|
|
174
186
|
}))
|
|
175
187
|
} catch (error) {
|
|
176
|
-
|
|
188
|
+
this.logger.error('Error marking UTXO as spent:', error)
|
|
177
189
|
}
|
|
178
190
|
}
|
|
179
191
|
})
|
|
180
192
|
|
|
193
|
+
let admissibleOutputs: AdmittanceInstructions = { outputsToAdmit: [], coinsToRetain: [] }
|
|
181
194
|
// Determine which outputs are admissible
|
|
182
195
|
const admissibleOutputsPromise = (async () => {
|
|
183
196
|
try {
|
|
@@ -215,25 +228,27 @@ export class Engine {
|
|
|
215
228
|
onSteakReady(steak)
|
|
216
229
|
}
|
|
217
230
|
|
|
231
|
+
// Update storage and notify lookup services
|
|
218
232
|
for (const topic of taggedBEEF.topics) {
|
|
219
233
|
// Keep track of which outputs to admit, mark as stale, or retain
|
|
234
|
+
const admissibleOutputs = steak[topic]
|
|
220
235
|
const outputsToAdmit: number[] = admissibleOutputs.outputsToAdmit
|
|
221
|
-
const
|
|
236
|
+
const outputsConsumed: Array<{
|
|
222
237
|
txid: string
|
|
223
238
|
outputIndex: number
|
|
224
239
|
}> = []
|
|
225
|
-
|
|
240
|
+
|
|
241
|
+
const outputsToMarkStale: Array<{
|
|
226
242
|
txid: string
|
|
227
243
|
outputIndex: number
|
|
228
244
|
}> = []
|
|
229
245
|
|
|
230
|
-
//
|
|
231
|
-
// For each of the previous UTXOs, if the the UTXO was not included in the list of UTXOs identified for retention, then it will be marked as stale.
|
|
246
|
+
// For each of the previous UTXOs, if the UTXO was not included in the list of UTXOs identified for retention, then it will be marked as stale.
|
|
232
247
|
for (const inputIndex of previousCoins) {
|
|
233
248
|
const previousTXID = tx.inputs[inputIndex].sourceTXID || tx.inputs[inputIndex].sourceTransaction?.id('hex') as string
|
|
234
249
|
const previousOutputIndex = tx.inputs[inputIndex].sourceOutputIndex
|
|
235
250
|
if (!admissibleOutputs.coinsToRetain.includes(inputIndex)) {
|
|
236
|
-
|
|
251
|
+
outputsToMarkStale.push({
|
|
237
252
|
txid: previousTXID,
|
|
238
253
|
outputIndex: previousOutputIndex
|
|
239
254
|
})
|
|
@@ -247,7 +262,7 @@ export class Engine {
|
|
|
247
262
|
|
|
248
263
|
// Remove stale outputs recursively
|
|
249
264
|
this.startTime(`lookForStaleOutputs_${txid.substring(0, 10)}`)
|
|
250
|
-
await Promise.all(
|
|
265
|
+
await Promise.all(outputsToMarkStale.map(async coin => {
|
|
251
266
|
const output = await this.storage.findOutput(coin.txid, coin.outputIndex, topic)
|
|
252
267
|
if (output !== undefined && output !== null) {
|
|
253
268
|
await this.deleteUTXODeep(output)
|
|
@@ -302,110 +317,74 @@ export class Engine {
|
|
|
302
317
|
}
|
|
303
318
|
|
|
304
319
|
this.startTime(`transactionPropagation_${txid.substring(0, 10)}`)
|
|
305
|
-
// Propagate transaction to other nodes according to synchronization agreements
|
|
306
|
-
// 1. Find nodes that host the topics associated with admissable outputs
|
|
307
|
-
// We want to figure out which topics we actually care about (because their associated outputs were admitted)
|
|
308
|
-
// AND if the topic was not admitted we want to remove it from the list of topics we care about.
|
|
309
320
|
const relevantTopics = taggedBEEF.topics.filter(topic =>
|
|
310
321
|
steak[topic] !== undefined && steak[topic].outputsToAdmit.length !== 0
|
|
311
322
|
)
|
|
312
323
|
|
|
313
|
-
// TODO: Cache ship/slap lookup with expiry (every 5min)
|
|
314
324
|
if (relevantTopics.length > 0) {
|
|
315
|
-
//
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
// Lookup will currently always return type output-list
|
|
328
|
-
if (lookupAnswer.type === 'output-list') {
|
|
329
|
-
const shipAdvertisements: Advertisement[] = []
|
|
330
|
-
lookupAnswer.outputs.forEach(output => {
|
|
331
|
-
try {
|
|
332
|
-
// Parse out the advertisements using the provided parser
|
|
333
|
-
const tx = Transaction.fromBEEF(output.beef)
|
|
334
|
-
const advertisement = this.advertiser?.parseAdvertisement(tx.outputs[output.outputIndex].lockingScript)
|
|
335
|
-
if (advertisement !== undefined && advertisement !== null && advertisement.protocol === 'SHIP') {
|
|
336
|
-
shipAdvertisements.push(advertisement)
|
|
337
|
-
}
|
|
338
|
-
} catch (error) {
|
|
339
|
-
console.error('Failed to parse advertisement output:', error)
|
|
340
|
-
}
|
|
341
|
-
})
|
|
342
|
-
if (shipAdvertisements.length > 0) {
|
|
343
|
-
shipAdvertisements.forEach((advertisement: Advertisement) => {
|
|
344
|
-
if (!domainToTopicsMap.has(advertisement.domain)) {
|
|
345
|
-
domainToTopicsMap.set(advertisement.domain, new Set<string>())
|
|
346
|
-
}
|
|
347
|
-
domainToTopicsMap.get(advertisement.domain)?.add(topic)
|
|
348
|
-
})
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
} catch (error) {
|
|
352
|
-
console.error(`Error looking up topic ${String(topic)}:`, error)
|
|
325
|
+
// Create a SHIPBroadcaster instance
|
|
326
|
+
let customBroadcasterConfig
|
|
327
|
+
if (this.slapTrackers) {
|
|
328
|
+
// Custom SLAP trackers warrant a custom broadcaster config
|
|
329
|
+
const resolverConfig: LookupResolverConfig = {
|
|
330
|
+
slapTrackers: this.slapTrackers
|
|
331
|
+
}
|
|
332
|
+
customBroadcasterConfig = {
|
|
333
|
+
resolver: new LookupResolver(resolverConfig)
|
|
353
334
|
}
|
|
354
335
|
}
|
|
336
|
+
const shipBroadcaster = new SHIPBroadcaster(relevantTopics, customBroadcasterConfig)
|
|
355
337
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
this.shipTrackers.forEach(tracker => {
|
|
361
|
-
if (domainToTopicsMap.get(tracker) !== undefined) {
|
|
362
|
-
domainToTopicsMap.get(tracker)?.add('tm_ship')
|
|
363
|
-
} else {
|
|
364
|
-
domainToTopicsMap.set(tracker, new Set(['tm_ship']))
|
|
365
|
-
}
|
|
366
|
-
})
|
|
338
|
+
try {
|
|
339
|
+
await shipBroadcaster.broadcast(tx)
|
|
340
|
+
} catch (error) {
|
|
341
|
+
this.logger.error('Error during broadcasting:', error)
|
|
367
342
|
}
|
|
368
343
|
|
|
369
|
-
//
|
|
370
|
-
if (this.
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
344
|
+
// Handle shipTrackers for 'tm_ship' topic
|
|
345
|
+
if (this.shipTrackers && this.shipTrackers.length > 0 && relevantTopics.includes('tm_ship')) {
|
|
346
|
+
const taggedBEEFForShip = {
|
|
347
|
+
beef: taggedBEEF.beef,
|
|
348
|
+
topics: ['tm_ship']
|
|
349
|
+
}
|
|
350
|
+
const facilitator = this.overlayBroadcastFacilitator
|
|
351
|
+
|
|
352
|
+
const sendPromises = this.shipTrackers.map(async tracker => {
|
|
353
|
+
try {
|
|
354
|
+
await facilitator.send(tracker, taggedBEEFForShip)
|
|
355
|
+
} catch (error) {
|
|
356
|
+
this.logger.error(`Error sending to shipTracker ${tracker}:`, error)
|
|
376
357
|
}
|
|
377
358
|
})
|
|
359
|
+
await Promise.all(sendPromises)
|
|
378
360
|
}
|
|
379
361
|
|
|
380
|
-
//
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
headers: {
|
|
386
|
-
'Content-Type': 'application/octet-stream',
|
|
387
|
-
'X-Topics': JSON.stringify(Array.from(topics))
|
|
388
|
-
},
|
|
389
|
-
body: new Uint8Array(taggedBEEF.beef)
|
|
390
|
-
})
|
|
391
|
-
broadcastPromises.push(promise)
|
|
362
|
+
// Handle slapTrackers for 'tm_slap' topic
|
|
363
|
+
if (this.slapTrackers && this.slapTrackers.length > 0 && relevantTopics.includes('tm_slap')) {
|
|
364
|
+
const taggedBEEFForSlap = {
|
|
365
|
+
beef: taggedBEEF.beef,
|
|
366
|
+
topics: ['tm_slap']
|
|
392
367
|
}
|
|
393
|
-
|
|
368
|
+
const facilitator = new HTTPSOverlayBroadcastFacilitator()
|
|
394
369
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
370
|
+
const sendPromises = this.slapTrackers.map(async tracker => {
|
|
371
|
+
try {
|
|
372
|
+
await facilitator.send(tracker, taggedBEEFForSlap)
|
|
373
|
+
} catch (error) {
|
|
374
|
+
this.logger.error(`Error sending to slapTracker ${tracker}:`, error)
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
await Promise.all(sendPromises)
|
|
399
378
|
}
|
|
400
379
|
}
|
|
401
|
-
this.endTime(`
|
|
380
|
+
this.endTime(`transactionPropagation_${txid.substring(0, 10)}`)
|
|
402
381
|
|
|
403
382
|
// Immediately return from the function without waiting for the promises to resolve.
|
|
404
383
|
return steak
|
|
405
384
|
}
|
|
406
385
|
|
|
407
386
|
/**
|
|
408
|
-
* Submit a lookup question to the Overlay Services Engine, and receive
|
|
387
|
+
* Submit a lookup question to the Overlay Services Engine, and receive back a Lookup Answer
|
|
409
388
|
* @param LookupQuestion — The question to ask the Overlay Services Engine
|
|
410
389
|
* @returns The answer to the question
|
|
411
390
|
*/
|
|
@@ -508,7 +487,7 @@ export class Engine {
|
|
|
508
487
|
await this.submit(taggedBEEF)
|
|
509
488
|
}
|
|
510
489
|
} catch (error) {
|
|
511
|
-
|
|
490
|
+
this.logger.error('Failed to create SHIP advertisement:', error)
|
|
512
491
|
}
|
|
513
492
|
|
|
514
493
|
// Revoke all advertisements to revoke
|
|
@@ -518,7 +497,7 @@ export class Engine {
|
|
|
518
497
|
await this.submit(taggedBEEF)
|
|
519
498
|
}
|
|
520
499
|
} catch (error) {
|
|
521
|
-
|
|
500
|
+
this.logger.error('Failed to revoke SHIP/SLAP advertisements:', error)
|
|
522
501
|
}
|
|
523
502
|
}
|
|
524
503
|
|
|
@@ -565,7 +544,7 @@ export class Engine {
|
|
|
565
544
|
endpointSet.add(advertisement.domain)
|
|
566
545
|
}
|
|
567
546
|
} catch (error) {
|
|
568
|
-
|
|
547
|
+
this.logger.error('Failed to parse advertisement output:', error)
|
|
569
548
|
}
|
|
570
549
|
})
|
|
571
550
|
|
|
@@ -767,7 +746,7 @@ export class Engine {
|
|
|
767
746
|
} catch (e) {
|
|
768
747
|
// Handle any errors that occurred
|
|
769
748
|
// Note: Test this!
|
|
770
|
-
|
|
749
|
+
this.logger.error(`Error retrieving UTXO history: ${e} `)
|
|
771
750
|
// return []
|
|
772
751
|
throw new Error(`Error retrieving UTXO history: ${e} `)
|
|
773
752
|
}
|
|
@@ -913,19 +892,51 @@ export class Engine {
|
|
|
913
892
|
/**
|
|
914
893
|
* Find a list of supported topic managers
|
|
915
894
|
* @public
|
|
916
|
-
* @returns {Promise<string
|
|
895
|
+
* @returns {Promise<Record<string, { name: string; shortDescription: string; iconURL?: string; version?: string; informationURL?: string; }>>} - Supported topic managers and their metadata
|
|
917
896
|
*/
|
|
918
|
-
async listTopicManagers(): Promise<string
|
|
919
|
-
|
|
897
|
+
async listTopicManagers(): Promise<Record<string, {
|
|
898
|
+
name: string;
|
|
899
|
+
shortDescription: string;
|
|
900
|
+
iconURL?: string;
|
|
901
|
+
version?: string;
|
|
902
|
+
informationURL?: string;
|
|
903
|
+
}>> {
|
|
904
|
+
let result: Record<string, {
|
|
905
|
+
name: string;
|
|
906
|
+
shortDescription: string;
|
|
907
|
+
iconURL?: string;
|
|
908
|
+
version?: string;
|
|
909
|
+
informationURL?: string;
|
|
910
|
+
}> = {}
|
|
911
|
+
for (let t in this.managers) {
|
|
912
|
+
result[t] = await this.managers[t].getMetaData()
|
|
913
|
+
}
|
|
914
|
+
return result
|
|
920
915
|
}
|
|
921
916
|
|
|
922
917
|
/**
|
|
923
918
|
* Find a list of supported lookup services
|
|
924
919
|
* @public
|
|
925
|
-
* @returns {Promise<string
|
|
920
|
+
* @returns {Promise<Record<string, { name: string; shortDescription: string; iconURL?: string; version?: string; informationURL?: string; }>>} - Supported lookup services and their metadata
|
|
926
921
|
*/
|
|
927
|
-
async
|
|
928
|
-
|
|
922
|
+
async listLookupServices(): Promise<Record<string, {
|
|
923
|
+
name: string;
|
|
924
|
+
shortDescription: string;
|
|
925
|
+
iconURL?: string;
|
|
926
|
+
version?: string;
|
|
927
|
+
informationURL?: string;
|
|
928
|
+
}>> {
|
|
929
|
+
let result: Record<string, {
|
|
930
|
+
name: string;
|
|
931
|
+
shortDescription: string;
|
|
932
|
+
iconURL?: string;
|
|
933
|
+
version?: string;
|
|
934
|
+
informationURL?: string;
|
|
935
|
+
}> = {}
|
|
936
|
+
for (let t in this.lookupServices) {
|
|
937
|
+
result[t] = await this.lookupServices[t].getMetaData()
|
|
938
|
+
}
|
|
939
|
+
return result
|
|
929
940
|
}
|
|
930
941
|
|
|
931
942
|
/**
|
|
@@ -1002,18 +1013,3 @@ export class Engine {
|
|
|
1002
1013
|
}
|
|
1003
1014
|
}
|
|
1004
1015
|
}
|
|
1005
|
-
|
|
1006
|
-
//////////
|
|
1007
|
-
// OTHER FILES
|
|
1008
|
-
//////////
|
|
1009
|
-
|
|
1010
|
-
/*
|
|
1011
|
-
There is currently a bug with the test runner that prevents importing and using files that export variables other than type definitions within implementation files that are not directly imported themselves.
|
|
1012
|
-
Thus, all non-type exports have been moved to Engine.
|
|
1013
|
-
*/
|
|
1014
|
-
|
|
1015
|
-
// TODO: fix bug with imports that break tests. -----[GASP/OverlayGASPRemote.ts]-----
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
// TODO: fix bug with imports that break tests. -----[GASP/OverlayGASPStorage.ts]-----
|
package/src/LookupService.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { LookupQuestion } from './LookupQuestion.js'
|
|
2
1
|
import { LookupFormula } from './LookupFormula.js'
|
|
3
|
-
import { LookupAnswer } from '
|
|
4
|
-
import { Script } from '@bsv/sdk'
|
|
2
|
+
import { LookupQuestion, LookupAnswer, Script } from '@bsv/sdk'
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Defines a Lookup Service interface to be implemented for specific use-cases
|
package/src/TopicManager.ts
CHANGED
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
import { Engine } from '../../dist/cjs/src/Engine'
|
|
3
3
|
import { LookupService } from '../LookupService'
|
|
4
4
|
import { TopicManager } from '../TopicManager'
|
|
5
|
-
import { AdmittanceInstructions } from '../AdmittanceInstructions'
|
|
6
5
|
import { Storage } from '../storage/Storage'
|
|
7
|
-
import { Transaction, Utils } from '@bsv/sdk'
|
|
6
|
+
import { Transaction, Utils, TaggedBEEF, AdmittanceInstructions } from '@bsv/sdk'
|
|
8
7
|
import { Output } from '../Output'
|
|
9
8
|
import { SyncConfiguration } from '../SyncConfiguration'
|
|
10
|
-
import { TaggedBEEF } from '../TaggedBEEF.js'
|
|
11
9
|
import { Advertiser } from '../Advertiser.js'
|
|
12
10
|
|
|
13
11
|
const mockChainTracker = {
|
|
@@ -118,8 +116,6 @@ describe('BSV Overlay Services Engine', () => {
|
|
|
118
116
|
// Verify that Advertiser methods are NOT called
|
|
119
117
|
expect(mockAdvertiser.createAdvertisements).not.toHaveBeenCalled()
|
|
120
118
|
expect(mockAdvertiser.findAllAdvertisements).not.toHaveBeenCalledWith('SHIP') // Assuming 'SHIP' is expected
|
|
121
|
-
|
|
122
|
-
console.log('Got past', url)
|
|
123
119
|
}
|
|
124
120
|
})
|
|
125
121
|
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Instructs the Overlay Services Engine about which outputs to admit and which previous outputs to retain. Returned by a Topic Manager.
|
|
3
|
-
*/
|
|
4
|
-
export type AdmittanceInstructions = {
|
|
5
|
-
/**
|
|
6
|
-
* The indices of all admissable outputs into the managed topic from the provided transaction.
|
|
7
|
-
*/
|
|
8
|
-
outputsToAdmit: number[]
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* The indices of all inputs from the provided transaction which spend previously-admitted outputs that should be retained for historical record-keeping.
|
|
12
|
-
*/
|
|
13
|
-
coinsToRetain: number[]
|
|
14
|
-
}
|
package/src/LookupAnswer.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* How the Overlay Services Engine responds to a Lookup Question.
|
|
3
|
-
* It may comprise either an output list or a freeform response from the Lookup Service.
|
|
4
|
-
*/
|
|
5
|
-
export type LookupAnswer = {
|
|
6
|
-
type: 'output-list'
|
|
7
|
-
outputs: Array<{
|
|
8
|
-
beef: number[]
|
|
9
|
-
outputIndex: number
|
|
10
|
-
}>
|
|
11
|
-
} | {
|
|
12
|
-
type: 'freeform'
|
|
13
|
-
result: unknown
|
|
14
|
-
}
|
package/src/LookupQuestion.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The question asked to the Overlay Services Engine when a consumer of state wishes to look up information.
|
|
3
|
-
*/
|
|
4
|
-
export type LookupQuestion = {
|
|
5
|
-
/**
|
|
6
|
-
* The identifier for a Lookup Service which the person asking the question wishes to use.
|
|
7
|
-
*/
|
|
8
|
-
service: string
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* The query which will be forwarded to the Lookup Service.
|
|
12
|
-
* Its type depends on that prescribed by the Lookup Service employed.
|
|
13
|
-
*/
|
|
14
|
-
query: unknown
|
|
15
|
-
}
|
package/src/STEAK.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { AdmittanceInstructions } from './AdmittanceInstructions.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Submitted Transaction Execution AcKnowledgment
|
|
5
|
-
*
|
|
6
|
-
* @description
|
|
7
|
-
* Comprises the topics where a transaction was submitted, and for each one, the output indices for the UTXOs newly admitted into the topics, and the coins retained.
|
|
8
|
-
* An object whose keys are topic names and whose values are topical admittance instructions denoting the state of the submitted transaction with respect to the associated topic.
|
|
9
|
-
*/
|
|
10
|
-
export type STEAK = Record<string, AdmittanceInstructions>
|
package/src/TaggedBEEF.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tagged BEEF
|
|
3
|
-
*
|
|
4
|
-
* @description
|
|
5
|
-
* Tagged BEEF ([Background Evaluation Extended Format](https://brc.dev/62)) structure. Comprises a transaction, its SPV information, and the overlay topics where its inclusion is requested.
|
|
6
|
-
*/
|
|
7
|
-
export type TaggedBEEF = {
|
|
8
|
-
beef: number[]
|
|
9
|
-
topics: string[]
|
|
10
|
-
}
|