@bsv/wallet-toolbox-client 2.5.0 → 2.6.1
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/out/index.client.cjs +535 -148
- package/out/index.client.cjs.map +1 -1
- package/out/index.client.d.cts +140 -12
- package/out/index.client.d.cts.map +1 -1
- package/out/index.client.d.mts +140 -12
- package/out/index.client.d.mts.map +1 -1
- package/out/index.client.mjs +527 -149
- package/out/index.client.mjs.map +1 -1
- package/package.json +1 -1
package/out/index.client.cjs
CHANGED
|
@@ -1005,6 +1005,7 @@ function toWalletNetwork(chain) {
|
|
|
1005
1005
|
switch (chain) {
|
|
1006
1006
|
case "main": return "mainnet";
|
|
1007
1007
|
case "test":
|
|
1008
|
+
case "stn":
|
|
1008
1009
|
case "ttn":
|
|
1009
1010
|
case "tstn":
|
|
1010
1011
|
case "mock": return "testnet";
|
|
@@ -1018,6 +1019,7 @@ function toLookupNetworkPreset(chain) {
|
|
|
1018
1019
|
switch (chain) {
|
|
1019
1020
|
case "main": return "mainnet";
|
|
1020
1021
|
case "test": return "testnet";
|
|
1022
|
+
case "stn":
|
|
1021
1023
|
case "ttn":
|
|
1022
1024
|
case "tstn":
|
|
1023
1025
|
case "mock": return "local";
|
|
@@ -11767,9 +11769,7 @@ function genesisHeader(chain) {
|
|
|
11767
11769
|
height: 0,
|
|
11768
11770
|
hash: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
|
11769
11771
|
};
|
|
11770
|
-
case "test":
|
|
11771
|
-
case "ttn":
|
|
11772
|
-
case "tstn": return {
|
|
11772
|
+
case "test": return {
|
|
11773
11773
|
version: 1,
|
|
11774
11774
|
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11775
11775
|
merkleRoot: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
@@ -11779,6 +11779,36 @@ function genesisHeader(chain) {
|
|
|
11779
11779
|
height: 0,
|
|
11780
11780
|
hash: "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
|
11781
11781
|
};
|
|
11782
|
+
case "stn": return {
|
|
11783
|
+
version: 1,
|
|
11784
|
+
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11785
|
+
merkleRoot: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
11786
|
+
time: 1296688602,
|
|
11787
|
+
bits: 486604799,
|
|
11788
|
+
nonce: 173779992,
|
|
11789
|
+
height: 0,
|
|
11790
|
+
hash: "6b38bdbcd73a19f7889d23e1fa6166a9de71affceca60ca3bb1b28af8135c594"
|
|
11791
|
+
};
|
|
11792
|
+
case "ttn": return {
|
|
11793
|
+
version: 1,
|
|
11794
|
+
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11795
|
+
merkleRoot: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
11796
|
+
time: 1755606836,
|
|
11797
|
+
bits: 486604799,
|
|
11798
|
+
nonce: 1092578460,
|
|
11799
|
+
height: 0,
|
|
11800
|
+
hash: "000000000499eabba0a88f5b3747231c74b9191c1a4a04b2c2ea817976b7776d"
|
|
11801
|
+
};
|
|
11802
|
+
case "tstn": return {
|
|
11803
|
+
version: 1,
|
|
11804
|
+
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11805
|
+
merkleRoot: "64452e5b25c65e492ad6a4f5ce9f427ca986626c28315d88de920d66e28cc98f",
|
|
11806
|
+
time: 1782864e3,
|
|
11807
|
+
bits: 486604799,
|
|
11808
|
+
nonce: 1780488216,
|
|
11809
|
+
height: 0,
|
|
11810
|
+
hash: "000000005d221c0e023cb56b5682cf094f32cd959958b40bc931e5797cae706c"
|
|
11811
|
+
};
|
|
11782
11812
|
case "mock": throw new Error("genesisHeader does not support 'mock' chain. Mock chain generates its own genesis block.");
|
|
11783
11813
|
}
|
|
11784
11814
|
}
|
|
@@ -19306,10 +19336,11 @@ var Chaintracks = class {
|
|
|
19306
19336
|
startupError = null;
|
|
19307
19337
|
subscriberCallbacksEnabled = false;
|
|
19308
19338
|
stopMainThread = true;
|
|
19309
|
-
lastPresentHeight =
|
|
19339
|
+
lastPresentHeight = -1;
|
|
19310
19340
|
lastPresentHeightMsecs = 0;
|
|
19311
19341
|
lastPresentHeightMaxAge = 60 * 1e3;
|
|
19312
19342
|
lock = new SingleWriterMultiReaderLock();
|
|
19343
|
+
sourceStatus = /* @__PURE__ */ new Map();
|
|
19313
19344
|
constructor(options) {
|
|
19314
19345
|
this.options = options;
|
|
19315
19346
|
if (options.storage == null) throw new Error("storage is required.");
|
|
@@ -19320,6 +19351,22 @@ var Chaintracks = class {
|
|
|
19320
19351
|
this.storage = options.storage;
|
|
19321
19352
|
this.bulkIngestors = options.bulkIngestors;
|
|
19322
19353
|
this.liveIngestors = options.liveIngestors;
|
|
19354
|
+
for (const [index, source] of this.bulkIngestors.entries()) {
|
|
19355
|
+
const name = this.sourceName("bulk", index, source);
|
|
19356
|
+
this.sourceStatus.set(name, {
|
|
19357
|
+
name,
|
|
19358
|
+
role: "bulk",
|
|
19359
|
+
state: "unknown"
|
|
19360
|
+
});
|
|
19361
|
+
}
|
|
19362
|
+
for (const [index, source] of this.liveIngestors.entries()) {
|
|
19363
|
+
const name = this.sourceName("live", index, source);
|
|
19364
|
+
this.sourceStatus.set(name, {
|
|
19365
|
+
name,
|
|
19366
|
+
role: "live",
|
|
19367
|
+
state: "unknown"
|
|
19368
|
+
});
|
|
19369
|
+
}
|
|
19323
19370
|
this.addLiveRecursionLimit = options.addLiveRecursionLimit;
|
|
19324
19371
|
if (options.logging != null) this.log = options.logging;
|
|
19325
19372
|
this.storage.log = this.log;
|
|
@@ -19334,19 +19381,36 @@ var Chaintracks = class {
|
|
|
19334
19381
|
*/
|
|
19335
19382
|
async getPresentHeight() {
|
|
19336
19383
|
const now = Date.now();
|
|
19337
|
-
if (this.lastPresentHeight && now - this.lastPresentHeightMsecs < this.lastPresentHeightMaxAge) return this.lastPresentHeight;
|
|
19338
|
-
const
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19384
|
+
if (this.lastPresentHeight >= 0 && now - this.lastPresentHeightMsecs < this.lastPresentHeightMaxAge) return this.lastPresentHeight;
|
|
19385
|
+
for (const [index, bulk] of this.bulkIngestors.entries()) {
|
|
19386
|
+
const source = this.sourceName("bulk", index, bulk);
|
|
19387
|
+
try {
|
|
19388
|
+
const presentHeight = await bulk.getPresentHeight();
|
|
19389
|
+
if (presentHeight != null && Number.isInteger(presentHeight) && presentHeight >= 0) {
|
|
19390
|
+
this.markSourceSuccess(source, "bulk");
|
|
19391
|
+
this.lastPresentHeight = presentHeight;
|
|
19392
|
+
this.lastPresentHeightMsecs = now;
|
|
19393
|
+
return presentHeight;
|
|
19394
|
+
}
|
|
19395
|
+
} catch (uerr) {
|
|
19396
|
+
const error = WalletError.fromUnknown(uerr);
|
|
19397
|
+
this.markSourceFailure(source, "bulk", error);
|
|
19398
|
+
this.log(`Present-height source ${source} failed: ${error.message}`);
|
|
19399
|
+
}
|
|
19400
|
+
}
|
|
19401
|
+
if (this.lastPresentHeight >= 0) return this.lastPresentHeight;
|
|
19402
|
+
try {
|
|
19403
|
+
const ranges = await this.storage.getAvailableHeightRanges();
|
|
19404
|
+
const localHeight = Math.max(ranges.bulk.maxHeight, ranges.live.maxHeight);
|
|
19405
|
+
if (localHeight >= 0) {
|
|
19406
|
+
this.lastPresentHeight = localHeight;
|
|
19407
|
+
this.lastPresentHeightMsecs = now;
|
|
19408
|
+
return localHeight;
|
|
19409
|
+
}
|
|
19410
|
+
} catch (error) {
|
|
19411
|
+
this.log(`Unable to read the locally validated ChainTracks height: ${WalletError.fromUnknown(error).message}`);
|
|
19412
|
+
}
|
|
19413
|
+
throw new Error("No present-height source or locally validated headers are available.");
|
|
19350
19414
|
}
|
|
19351
19415
|
async currentHeight() {
|
|
19352
19416
|
return await this.getPresentHeight();
|
|
@@ -19397,7 +19461,7 @@ var Chaintracks = class {
|
|
|
19397
19461
|
for (const bulkIn of this.bulkIngestors) await bulkIn.setStorage(this.storage, this.log);
|
|
19398
19462
|
for (const liveIn of this.liveIngestors) await liveIn.setStorage(this.storage, this.log);
|
|
19399
19463
|
this.stopMainThread = false;
|
|
19400
|
-
for (const liveIngestor of this.liveIngestors) this.promises.push(this.runLiveIngestor(liveIngestor));
|
|
19464
|
+
for (const [index, liveIngestor] of this.liveIngestors.entries()) this.promises.push(this.runLiveIngestor(liveIngestor, index));
|
|
19401
19465
|
this.promises.push(this.mainThreadShiftLiveHeaders());
|
|
19402
19466
|
while (!this.available && this.startupError == null) await wait(100);
|
|
19403
19467
|
if (this.startupError != null) throw this.startupError;
|
|
@@ -19424,10 +19488,12 @@ var Chaintracks = class {
|
|
|
19424
19488
|
async listening() {
|
|
19425
19489
|
return await this.makeAvailable();
|
|
19426
19490
|
}
|
|
19427
|
-
async runLiveIngestor(liveIngestor) {
|
|
19491
|
+
async runLiveIngestor(liveIngestor, index) {
|
|
19428
19492
|
let restartCount = 0;
|
|
19429
19493
|
const name = liveIngestor.constructor.name;
|
|
19494
|
+
const source = this.sourceName("live", index, liveIngestor);
|
|
19430
19495
|
while (!this.stopMainThread) try {
|
|
19496
|
+
this.markSourceSuccess(source, "live");
|
|
19431
19497
|
await liveIngestor.startListening(this.liveHeaders);
|
|
19432
19498
|
if (this.stopMainThread) return;
|
|
19433
19499
|
restartCount++;
|
|
@@ -19438,6 +19504,7 @@ var Chaintracks = class {
|
|
|
19438
19504
|
if (this.stopMainThread) return;
|
|
19439
19505
|
restartCount++;
|
|
19440
19506
|
const e = WalletError.fromUnknown(error_);
|
|
19507
|
+
this.markSourceFailure(source, "live", e);
|
|
19441
19508
|
const waitMsecs = this.liveIngestorRestartWaitMsecs(restartCount);
|
|
19442
19509
|
this.log(`Live ingestor ${name} failed restart=${restartCount} retryMsecs=${waitMsecs}: ${e.stack ?? e.message}`);
|
|
19443
19510
|
await wait(waitMsecs);
|
|
@@ -19485,7 +19552,8 @@ var Chaintracks = class {
|
|
|
19485
19552
|
storage: this.storage.constructor.name,
|
|
19486
19553
|
bulkIngestors: this.bulkIngestors.map((bulkIngestor) => bulkIngestor.constructor.name),
|
|
19487
19554
|
liveIngestors: this.liveIngestors.map((liveIngestor) => liveIngestor.constructor.name),
|
|
19488
|
-
packages: []
|
|
19555
|
+
packages: [],
|
|
19556
|
+
sources: Array.from(this.sourceStatus.values()).map((status) => ({ ...status }))
|
|
19489
19557
|
};
|
|
19490
19558
|
}
|
|
19491
19559
|
async getHeaders(height, count) {
|
|
@@ -19568,26 +19636,30 @@ var Chaintracks = class {
|
|
|
19568
19636
|
let madeProgress = false;
|
|
19569
19637
|
let hadSuccess = false;
|
|
19570
19638
|
let done = false;
|
|
19571
|
-
for (const bulk of this.bulkIngestors)
|
|
19572
|
-
const
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19639
|
+
for (const [index, bulk] of this.bulkIngestors.entries()) {
|
|
19640
|
+
const source = this.sourceName("bulk", index, bulk);
|
|
19641
|
+
try {
|
|
19642
|
+
const beforeBulkMax = before.bulk.maxHeight;
|
|
19643
|
+
const beforeLiveRange = HeightRange.from(newLiveHeaders);
|
|
19644
|
+
const r = await bulk.synchronize(presentHeight, before, newLiveHeaders);
|
|
19645
|
+
hadSuccess = true;
|
|
19646
|
+
this.markSourceSuccess(source, "bulk");
|
|
19647
|
+
newLiveHeaders = r.liveHeaders;
|
|
19648
|
+
after = await this.storage.getAvailableHeightRanges();
|
|
19649
|
+
const added = after.bulk.above(before.bulk);
|
|
19650
|
+
const afterLiveRange = HeightRange.from(newLiveHeaders);
|
|
19651
|
+
if (after.bulk.maxHeight > beforeBulkMax || afterLiveRange.maxHeight > beforeLiveRange.maxHeight) madeProgress = true;
|
|
19652
|
+
before = after;
|
|
19653
|
+
this.log(`Bulk Ingestor: ${added.length} added with ${newLiveHeaders.length} live headers from ${bulk.constructor.name}`);
|
|
19654
|
+
if (r.done) {
|
|
19655
|
+
done = true;
|
|
19656
|
+
break;
|
|
19657
|
+
}
|
|
19658
|
+
} catch (error_) {
|
|
19659
|
+
const e = bulkSyncError = WalletError.fromUnknown(error_);
|
|
19660
|
+
this.markSourceFailure(source, "bulk", e);
|
|
19661
|
+
this.log(`bulk sync error: ${e.message}`);
|
|
19586
19662
|
}
|
|
19587
|
-
} catch (error_) {
|
|
19588
|
-
const e = bulkSyncError = WalletError.fromUnknown(error_);
|
|
19589
|
-
this.log(`bulk sync error: ${e.message}`);
|
|
19590
|
-
if (!this.available) break;
|
|
19591
19663
|
}
|
|
19592
19664
|
if (!this.available && bulkSyncError != null && !hadSuccess) this.startupError = bulkSyncError;
|
|
19593
19665
|
return {
|
|
@@ -19597,10 +19669,41 @@ var Chaintracks = class {
|
|
|
19597
19669
|
madeProgress
|
|
19598
19670
|
};
|
|
19599
19671
|
}
|
|
19672
|
+
sourceName(role, index, source) {
|
|
19673
|
+
return `${role}[${index}]:${source.constructor.name}`;
|
|
19674
|
+
}
|
|
19675
|
+
markSourceSuccess(name, role) {
|
|
19676
|
+
this.sourceStatus.set(name, {
|
|
19677
|
+
...this.sourceStatus.get(name),
|
|
19678
|
+
name,
|
|
19679
|
+
role,
|
|
19680
|
+
state: "healthy",
|
|
19681
|
+
lastSuccess: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19682
|
+
error: void 0
|
|
19683
|
+
});
|
|
19684
|
+
}
|
|
19685
|
+
markSourceFailure(name, role, error) {
|
|
19686
|
+
this.sourceStatus.set(name, {
|
|
19687
|
+
...this.sourceStatus.get(name),
|
|
19688
|
+
name,
|
|
19689
|
+
role,
|
|
19690
|
+
state: "degraded",
|
|
19691
|
+
lastFailure: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19692
|
+
error: error.message
|
|
19693
|
+
});
|
|
19694
|
+
}
|
|
19600
19695
|
async getMissingBlockHeader(hash) {
|
|
19601
|
-
for (const live of this.liveIngestors) {
|
|
19602
|
-
const
|
|
19603
|
-
|
|
19696
|
+
for (const [index, live] of this.liveIngestors.entries()) {
|
|
19697
|
+
const source = this.sourceName("live", index, live);
|
|
19698
|
+
try {
|
|
19699
|
+
const header = await live.getHeaderByHash(hash);
|
|
19700
|
+
this.markSourceSuccess(source, "live");
|
|
19701
|
+
if (header != null) return header;
|
|
19702
|
+
} catch (error) {
|
|
19703
|
+
const resolved = WalletError.fromUnknown(error);
|
|
19704
|
+
this.markSourceFailure(source, "live", resolved);
|
|
19705
|
+
this.log(`Header lookup source ${source} failed: ${resolved.message}`);
|
|
19706
|
+
}
|
|
19604
19707
|
}
|
|
19605
19708
|
}
|
|
19606
19709
|
invalidInsertHeaderResult(ihr) {
|
|
@@ -19933,6 +20036,9 @@ var GoChaintracksServiceClient = class {
|
|
|
19933
20036
|
chain;
|
|
19934
20037
|
baseUrl;
|
|
19935
20038
|
fetcher;
|
|
20039
|
+
requestTimeoutMsecs;
|
|
20040
|
+
reconnectWaitMsecs;
|
|
20041
|
+
reconnectWaitMaxMsecs;
|
|
19936
20042
|
subscriptions = /* @__PURE__ */ new Map();
|
|
19937
20043
|
nextSubscriptionId = 1;
|
|
19938
20044
|
constructor(chain, serviceUrl, options = {}) {
|
|
@@ -19946,6 +20052,15 @@ var GoChaintracksServiceClient = class {
|
|
|
19946
20052
|
}
|
|
19947
20053
|
this.baseUrl = `${base}${prefix}`;
|
|
19948
20054
|
this.fetcher = options.fetch ?? fetch;
|
|
20055
|
+
this.requestTimeoutMsecs = options.requestTimeoutMsecs ?? 3e4;
|
|
20056
|
+
this.reconnectWaitMsecs = options.reconnectWaitMsecs ?? 1e3;
|
|
20057
|
+
this.reconnectWaitMaxMsecs = options.reconnectWaitMaxMsecs ?? 6e4;
|
|
20058
|
+
for (const [name, value] of [
|
|
20059
|
+
["requestTimeoutMsecs", this.requestTimeoutMsecs],
|
|
20060
|
+
["reconnectWaitMsecs", this.reconnectWaitMsecs],
|
|
20061
|
+
["reconnectWaitMaxMsecs", this.reconnectWaitMaxMsecs]
|
|
20062
|
+
]) if (!Number.isSafeInteger(value) || value < 1) throw new Error(`${name} must be a positive integer.`);
|
|
20063
|
+
if (this.reconnectWaitMaxMsecs < this.reconnectWaitMsecs) throw new Error("reconnectWaitMaxMsecs must be greater than or equal to reconnectWaitMsecs.");
|
|
19949
20064
|
}
|
|
19950
20065
|
async currentHeight() {
|
|
19951
20066
|
return await this.getPresentHeight();
|
|
@@ -19955,12 +20070,8 @@ var GoChaintracksServiceClient = class {
|
|
|
19955
20070
|
return h != null && root === asString(h.merkleRoot);
|
|
19956
20071
|
}
|
|
19957
20072
|
async getChain() {
|
|
19958
|
-
|
|
19959
|
-
|
|
19960
|
-
return this.normalizeChain(r.network);
|
|
19961
|
-
} catch {
|
|
19962
|
-
return this.chain;
|
|
19963
|
-
}
|
|
20073
|
+
const r = await this.getJson("/network");
|
|
20074
|
+
return this.normalizeChain(typeof r === "string" ? r : r.network);
|
|
19964
20075
|
}
|
|
19965
20076
|
async getInfo() {
|
|
19966
20077
|
const tip = await this.findChainTipHeader();
|
|
@@ -19975,11 +20086,11 @@ var GoChaintracksServiceClient = class {
|
|
|
19975
20086
|
};
|
|
19976
20087
|
}
|
|
19977
20088
|
async getPresentHeight() {
|
|
19978
|
-
|
|
20089
|
+
const result = await this.getJson("/height");
|
|
20090
|
+
return typeof result === "number" ? result : result.height;
|
|
19979
20091
|
}
|
|
19980
20092
|
async getHeaders(height, count) {
|
|
19981
|
-
|
|
19982
|
-
return Buffer.from(bytes).toString("hex");
|
|
20093
|
+
return asString(await this.getBinary(`/headers.bin?height=${height}&count=${count}`));
|
|
19983
20094
|
}
|
|
19984
20095
|
async findChainTipHeader() {
|
|
19985
20096
|
return await this.getJson("/tip");
|
|
@@ -20035,7 +20146,7 @@ var GoChaintracksServiceClient = class {
|
|
|
20035
20146
|
async subscribe(type, path, onPayload) {
|
|
20036
20147
|
const id = `${type}-${this.nextSubscriptionId++}`;
|
|
20037
20148
|
const abort = new AbortController();
|
|
20038
|
-
const done = this.
|
|
20149
|
+
const done = this.runSseWithReconnect(path, abort.signal, onPayload);
|
|
20039
20150
|
this.subscriptions.set(id, {
|
|
20040
20151
|
id,
|
|
20041
20152
|
type,
|
|
@@ -20047,30 +20158,75 @@ var GoChaintracksServiceClient = class {
|
|
|
20047
20158
|
});
|
|
20048
20159
|
return id;
|
|
20049
20160
|
}
|
|
20050
|
-
async
|
|
20051
|
-
|
|
20052
|
-
|
|
20053
|
-
|
|
20161
|
+
async runSseWithReconnect(path, signal, onPayload) {
|
|
20162
|
+
let failures = 0;
|
|
20163
|
+
while (!signal.aborted) {
|
|
20164
|
+
try {
|
|
20165
|
+
failures = await this.runSse(path, signal, onPayload) ? 0 : failures + 1;
|
|
20166
|
+
} catch {
|
|
20167
|
+
if (signal.aborted) return;
|
|
20168
|
+
failures++;
|
|
20169
|
+
}
|
|
20170
|
+
const multiplier = Math.min(2 ** Math.max(0, failures - 1), 64);
|
|
20171
|
+
const delay = Math.min(this.reconnectWaitMsecs * multiplier, this.reconnectWaitMaxMsecs);
|
|
20172
|
+
await this.waitForReconnect(delay, signal);
|
|
20173
|
+
}
|
|
20174
|
+
}
|
|
20175
|
+
async waitForReconnect(msecs, signal) {
|
|
20176
|
+
if (signal.aborted || msecs <= 0) return;
|
|
20177
|
+
await new Promise((resolve) => {
|
|
20178
|
+
let timeout;
|
|
20179
|
+
const onAbort = () => done();
|
|
20180
|
+
const done = () => {
|
|
20181
|
+
clearTimeout(timeout);
|
|
20182
|
+
signal.removeEventListener("abort", onAbort);
|
|
20183
|
+
resolve();
|
|
20184
|
+
};
|
|
20185
|
+
timeout = setTimeout(done, msecs);
|
|
20186
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
20054
20187
|
});
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
const
|
|
20058
|
-
const
|
|
20059
|
-
|
|
20188
|
+
}
|
|
20189
|
+
async runSse(path, signal, onPayload) {
|
|
20190
|
+
const controller = new AbortController();
|
|
20191
|
+
const onAbort = () => controller.abort();
|
|
20192
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
20193
|
+
const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMsecs);
|
|
20194
|
+
let receivedEvent = false;
|
|
20195
|
+
const observePayload = (payload) => {
|
|
20196
|
+
receivedEvent = true;
|
|
20197
|
+
onPayload(payload);
|
|
20198
|
+
};
|
|
20060
20199
|
try {
|
|
20061
|
-
|
|
20062
|
-
|
|
20063
|
-
|
|
20064
|
-
|
|
20065
|
-
|
|
20200
|
+
const response = await this.fetcher(this.url(path), {
|
|
20201
|
+
headers: { Accept: "text/event-stream" },
|
|
20202
|
+
signal: controller.signal
|
|
20203
|
+
});
|
|
20204
|
+
clearTimeout(timeout);
|
|
20205
|
+
if (!response.ok) throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`);
|
|
20206
|
+
if (response.body == null) throw new Error(`GET ${this.url(path)} returned no response body`);
|
|
20207
|
+
const reader = response.body.getReader();
|
|
20208
|
+
const decoder = new TextDecoder();
|
|
20209
|
+
let buffer = "";
|
|
20210
|
+
try {
|
|
20211
|
+
for (;;) {
|
|
20212
|
+
const { done, value } = await reader.read();
|
|
20213
|
+
if (done) break;
|
|
20214
|
+
buffer += decoder.decode(value, { stream: true });
|
|
20215
|
+
buffer = this.processSseBuffer(buffer, observePayload);
|
|
20216
|
+
}
|
|
20217
|
+
buffer += decoder.decode();
|
|
20218
|
+
this.processSseBuffer(`${buffer}\n\n`, observePayload);
|
|
20219
|
+
} finally {
|
|
20220
|
+
reader.releaseLock();
|
|
20066
20221
|
}
|
|
20067
|
-
buffer += decoder.decode();
|
|
20068
|
-
this.processSseBuffer(`${buffer}\n\n`, onPayload);
|
|
20069
20222
|
} finally {
|
|
20070
|
-
|
|
20223
|
+
clearTimeout(timeout);
|
|
20224
|
+
signal.removeEventListener("abort", onAbort);
|
|
20071
20225
|
}
|
|
20226
|
+
return receivedEvent;
|
|
20072
20227
|
}
|
|
20073
20228
|
processSseBuffer(buffer, onPayload) {
|
|
20229
|
+
buffer = buffer.replaceAll("\r\n", "\n");
|
|
20074
20230
|
for (;;) {
|
|
20075
20231
|
const boundary = buffer.indexOf("\n\n");
|
|
20076
20232
|
if (boundary < 0) return buffer;
|
|
@@ -20089,32 +20245,51 @@ var GoChaintracksServiceClient = class {
|
|
|
20089
20245
|
return r;
|
|
20090
20246
|
}
|
|
20091
20247
|
async getJsonOrUndefined(path) {
|
|
20092
|
-
const response = await this.
|
|
20248
|
+
const response = await this.fetchWithTimeout(this.url(path), { headers: { Accept: "application/json" } });
|
|
20093
20249
|
if (response.status === 404) return void 0;
|
|
20094
20250
|
if (!response.ok) throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`);
|
|
20095
|
-
|
|
20251
|
+
const value = await response.json();
|
|
20252
|
+
if (value != null && typeof value === "object" && "status" in value) {
|
|
20253
|
+
const envelope = value;
|
|
20254
|
+
if (envelope.status === "success") return envelope.value;
|
|
20255
|
+
if (envelope.status === "error") throw new Error(envelope.description ?? `GET ${this.url(path)} failed`);
|
|
20256
|
+
}
|
|
20257
|
+
return value;
|
|
20096
20258
|
}
|
|
20097
20259
|
async getBinary(path) {
|
|
20098
|
-
const response = await this.
|
|
20260
|
+
const response = await this.fetchWithTimeout(this.url(path), { headers: { Accept: "application/octet-stream" } });
|
|
20099
20261
|
if (!response.ok) throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`);
|
|
20100
20262
|
return new Uint8Array(await response.arrayBuffer());
|
|
20101
20263
|
}
|
|
20264
|
+
async fetchWithTimeout(url, init) {
|
|
20265
|
+
const controller = new AbortController();
|
|
20266
|
+
const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMsecs);
|
|
20267
|
+
try {
|
|
20268
|
+
return await this.fetcher(url, {
|
|
20269
|
+
...init,
|
|
20270
|
+
signal: controller.signal
|
|
20271
|
+
});
|
|
20272
|
+
} finally {
|
|
20273
|
+
clearTimeout(timeout);
|
|
20274
|
+
}
|
|
20275
|
+
}
|
|
20102
20276
|
url(path) {
|
|
20103
20277
|
return `${this.baseUrl}${path}`;
|
|
20104
20278
|
}
|
|
20105
20279
|
normalizeChain(network) {
|
|
20106
|
-
switch (network) {
|
|
20280
|
+
switch (network.trim().toLowerCase()) {
|
|
20107
20281
|
case "main":
|
|
20108
20282
|
case "mainnet": return "main";
|
|
20109
20283
|
case "test":
|
|
20110
20284
|
case "testnet": return "test";
|
|
20285
|
+
case "stn":
|
|
20286
|
+
case "scalingtestnet": return "stn";
|
|
20111
20287
|
case "ttn":
|
|
20112
20288
|
case "teratest":
|
|
20113
20289
|
case "teratestnet": return "ttn";
|
|
20114
20290
|
case "tstn":
|
|
20115
|
-
case "teranodescalingtestnet":
|
|
20116
|
-
|
|
20117
|
-
default: return this.chain;
|
|
20291
|
+
case "teranodescalingtestnet": return "tstn";
|
|
20292
|
+
default: throw new Error(`Unsupported ChainTracks upstream network '${network}'.`);
|
|
20118
20293
|
}
|
|
20119
20294
|
}
|
|
20120
20295
|
};
|
|
@@ -20609,9 +20784,11 @@ var BulkFileDataManager = class BulkFileDataManager {
|
|
|
20609
20784
|
const nextHeight = lbf != null ? lbf.firstHeight + lbf.count : 0;
|
|
20610
20785
|
({headers: newBulkHeaders, incrementalChainWork} = trimAlreadyStoredHeaders(newBulkHeaders, nextHeight, incrementalChainWork));
|
|
20611
20786
|
if (newBulkHeaders.length === 0) return;
|
|
20612
|
-
if (
|
|
20613
|
-
if (!lbf.lastHash) throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`);
|
|
20614
|
-
const
|
|
20787
|
+
if (nextHeight !== newBulkHeaders[0].height) throw new WERR_INVALID_PARAMETER("newBulkHeaders", "an extension of existing bulk headers");
|
|
20788
|
+
if (lbf != null && !lbf.lastHash) throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`);
|
|
20789
|
+
const prevChainWork = lbf?.lastChainWork ?? "00".repeat(32);
|
|
20790
|
+
const prevHash = lbf?.lastHash ?? "00".repeat(32);
|
|
20791
|
+
const lastChainWork = incrementalChainWork ? addWork(incrementalChainWork, prevChainWork) : computeChainWorkFromHeaders(newBulkHeaders, lbf);
|
|
20615
20792
|
const data = serializeBaseBlockHeaders(newBulkHeaders);
|
|
20616
20793
|
const fileHash = asString(_bsv_sdk.Hash.sha256(asArray(data)), "base64");
|
|
20617
20794
|
const bf = {
|
|
@@ -20621,9 +20798,9 @@ var BulkFileDataManager = class BulkFileDataManager {
|
|
|
20621
20798
|
fileName: "incremental",
|
|
20622
20799
|
firstHeight: newBulkHeaders[0].height,
|
|
20623
20800
|
count: newBulkHeaders.length,
|
|
20624
|
-
prevChainWork
|
|
20801
|
+
prevChainWork,
|
|
20625
20802
|
lastChainWork,
|
|
20626
|
-
prevHash
|
|
20803
|
+
prevHash,
|
|
20627
20804
|
lastHash: newBulkHeaders.at(-1).hash,
|
|
20628
20805
|
fileHash,
|
|
20629
20806
|
data
|
|
@@ -21053,12 +21230,13 @@ function trimAlreadyStoredHeaders(headers, nextHeight, incrementalChainWork) {
|
|
|
21053
21230
|
}
|
|
21054
21231
|
/**
|
|
21055
21232
|
* Computes `lastChainWork` for a sequence of new bulk headers extending `lbf`,
|
|
21056
|
-
*
|
|
21233
|
+
* or beginning at genesis when bulk storage is empty, validating that the
|
|
21234
|
+
* sequence is contiguous.
|
|
21057
21235
|
*/
|
|
21058
21236
|
function computeChainWorkFromHeaders(headers, lbf) {
|
|
21059
|
-
let lastHeight = lbf.firstHeight + lbf.count - 1;
|
|
21060
|
-
let lastHash = lbf.
|
|
21061
|
-
let lastChainWork = lbf.
|
|
21237
|
+
let lastHeight = lbf != null ? lbf.firstHeight + lbf.count - 1 : -1;
|
|
21238
|
+
let lastHash = lbf?.lastHash ?? "00".repeat(32);
|
|
21239
|
+
let lastChainWork = lbf?.lastChainWork ?? "00".repeat(32);
|
|
21062
21240
|
for (const h of headers) {
|
|
21063
21241
|
if (h.height !== lastHeight + 1 || h.previousHash !== lastHash) throw new WERR_INVALID_PARAMETER("headers", `an extension of existing bulk headers, header with height ${h.height} is non-sequential`);
|
|
21064
21242
|
lastChainWork = addWork(lastChainWork, convertBitsToWork(h.bits));
|
|
@@ -21447,31 +21625,45 @@ var ServiceCollection = class ServiceCollection {
|
|
|
21447
21625
|
//#endregion
|
|
21448
21626
|
//#region ../src/services/networkConfig.ts
|
|
21449
21627
|
/**
|
|
21450
|
-
* Runtime service-endpoint configuration for
|
|
21628
|
+
* Runtime service-endpoint configuration for Teranode networks that do not
|
|
21629
|
+
* have a public, operator-independent service endpoint.
|
|
21451
21630
|
*
|
|
21452
|
-
* Unlike `main`, `test`, and `ttn`, the tstn service endpoints are not public and must not be
|
|
21631
|
+
* Unlike `main`, `test`, and `ttn`, the stn/tstn service endpoints are not public and must not be
|
|
21453
21632
|
* hardcoded in this (public) source tree. They are supplied at runtime through environment
|
|
21454
21633
|
* variables:
|
|
21455
21634
|
*
|
|
21635
|
+
* STN_ARCADE_URL STN Arcade broadcaster / ARC endpoint base.
|
|
21636
|
+
* STN_CHAINTRACKS_URL STN ChainTracks service URL.
|
|
21456
21637
|
* TSTN_ARCADE_URL Arcade broadcaster / ARC endpoint base. Also the fallback host for
|
|
21457
21638
|
* ChainTracks when TSTN_CHAINTRACKS_URL is unset
|
|
21458
21639
|
* (`${TSTN_ARCADE_URL}/chaintracks/v1`, mirroring the ttn layout).
|
|
21459
21640
|
* TSTN_CHAINTRACKS_URL ChainTracks service URL.
|
|
21460
21641
|
*
|
|
21461
|
-
* tstn
|
|
21462
|
-
* WhatsOnChain
|
|
21642
|
+
* stn/tstn run only operator-configured Arcade and ChainTracks services; there is no
|
|
21643
|
+
* documented WhatsOnChain service for them, so no WhatsOnChain endpoint is configured and
|
|
21463
21644
|
* the WhatsOnChain-only lookups (raw tx, utxo status, txid status, script-hash history) are not
|
|
21464
|
-
* available on tstn.
|
|
21645
|
+
* available on stn/tstn.
|
|
21465
21646
|
*
|
|
21466
|
-
* `process` is accessed defensively so importing this module remains safe in
|
|
21467
|
-
*
|
|
21468
|
-
*
|
|
21647
|
+
* `process` is accessed defensively so importing this module remains safe in
|
|
21648
|
+
* browser bundles. Browser applications can still supply an explicit
|
|
21649
|
+
* ChaintracksClientApi without relying on environment variables.
|
|
21469
21650
|
*/
|
|
21470
21651
|
function readEnv(name) {
|
|
21471
21652
|
const value = (typeof process !== "undefined" ? process.env : void 0)?.[name];
|
|
21472
21653
|
return value != null && value.trim() !== "" ? value.trim() : void 0;
|
|
21473
21654
|
}
|
|
21474
|
-
|
|
21655
|
+
/** Credential-free public Arcade host for supported networks. */
|
|
21656
|
+
function publicArcadeUrl(chain) {
|
|
21657
|
+
switch (chain) {
|
|
21658
|
+
case "main": return "https://arcade-v2-us-1.bsvblockchain.tech";
|
|
21659
|
+
case "test": return "https://arcade-v2-testnet-us-1.bsvblockchain.tech";
|
|
21660
|
+
case "ttn": return "https://arcade-v2-ttn-us-1.bsvblockchain.tech";
|
|
21661
|
+
case "stn":
|
|
21662
|
+
case "tstn":
|
|
21663
|
+
case "mock": return;
|
|
21664
|
+
}
|
|
21665
|
+
}
|
|
21666
|
+
const stripTrailingSlash$1 = (url) => {
|
|
21475
21667
|
let end = url.length;
|
|
21476
21668
|
while (end > 0 && url[end - 1] === "/") end--;
|
|
21477
21669
|
return url.slice(0, end);
|
|
@@ -21480,6 +21672,10 @@ const stripTrailingSlash = (url) => {
|
|
|
21480
21672
|
function tstnArcadeUrl() {
|
|
21481
21673
|
return readEnv("TSTN_ARCADE_URL");
|
|
21482
21674
|
}
|
|
21675
|
+
/** Arcade broadcaster / ARC endpoint for stn, or `undefined` when unset. */
|
|
21676
|
+
function stnArcadeUrl() {
|
|
21677
|
+
return readEnv("STN_ARCADE_URL");
|
|
21678
|
+
}
|
|
21483
21679
|
/**
|
|
21484
21680
|
* ChainTracks service URL for tstn. Falls back to `${TSTN_ARCADE_URL}/chaintracks/v1` when
|
|
21485
21681
|
* `TSTN_CHAINTRACKS_URL` is unset (mirrors the ttn layout). Throws when neither is configured.
|
|
@@ -21488,20 +21684,53 @@ function tstnChaintracksUrl() {
|
|
|
21488
21684
|
const explicit = readEnv("TSTN_CHAINTRACKS_URL");
|
|
21489
21685
|
if (explicit != null) return explicit;
|
|
21490
21686
|
const arcade = tstnArcadeUrl();
|
|
21491
|
-
if (arcade != null) return `${stripTrailingSlash(arcade)}/chaintracks/v1`;
|
|
21687
|
+
if (arcade != null) return `${stripTrailingSlash$1(arcade)}/chaintracks/v1`;
|
|
21492
21688
|
throw new Error("tstn chain requires a ChainTracks URL: set TSTN_CHAINTRACKS_URL (or TSTN_ARCADE_URL) in the environment.");
|
|
21493
21689
|
}
|
|
21690
|
+
/**
|
|
21691
|
+
* ChainTracks service URL for stn. Falls back to the configured Arcade host's
|
|
21692
|
+
* legacy-compatible path when STN_CHAINTRACKS_URL is unset.
|
|
21693
|
+
*/
|
|
21694
|
+
function stnChaintracksUrl() {
|
|
21695
|
+
const explicit = readEnv("STN_CHAINTRACKS_URL");
|
|
21696
|
+
if (explicit != null) return explicit;
|
|
21697
|
+
const arcade = stnArcadeUrl();
|
|
21698
|
+
if (arcade != null) return `${stripTrailingSlash$1(arcade)}/chaintracks/v1`;
|
|
21699
|
+
throw new Error("stn chain requires a ChainTracks URL: set STN_CHAINTRACKS_URL (or STN_ARCADE_URL) in the environment.");
|
|
21700
|
+
}
|
|
21494
21701
|
//#endregion
|
|
21495
21702
|
//#region ../src/services/createDefaultWalletServicesOptions.ts
|
|
21703
|
+
function stripTrailingSlash(value) {
|
|
21704
|
+
let end = value.length;
|
|
21705
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
21706
|
+
return value.slice(0, end);
|
|
21707
|
+
}
|
|
21708
|
+
function configuredChaintracksClient(chain, serviceUrl) {
|
|
21709
|
+
let path = "";
|
|
21710
|
+
try {
|
|
21711
|
+
path = stripTrailingSlash(new URL(serviceUrl).pathname);
|
|
21712
|
+
} catch {}
|
|
21713
|
+
if (path.endsWith("/v2")) return new GoChaintracksServiceClient(chain, serviceUrl);
|
|
21714
|
+
return new ChaintracksServiceClient(chain, serviceUrl);
|
|
21715
|
+
}
|
|
21716
|
+
/**
|
|
21717
|
+
* Returns the credential-free default ChainTracks client for a supported
|
|
21718
|
+
* public network, or an operator-configured client for stn/tstn.
|
|
21719
|
+
*/
|
|
21720
|
+
function createDefaultChaintracksClient(chain) {
|
|
21721
|
+
switch (chain) {
|
|
21722
|
+
case "main":
|
|
21723
|
+
case "test":
|
|
21724
|
+
case "ttn": return new GoChaintracksServiceClient(chain, arcadeDefaultUrl(chain), { apiPrefix: "/chaintracks/v2" });
|
|
21725
|
+
case "stn": return configuredChaintracksClient(chain, stnChaintracksUrl());
|
|
21726
|
+
case "tstn": return configuredChaintracksClient(chain, tstnChaintracksUrl());
|
|
21727
|
+
}
|
|
21728
|
+
}
|
|
21496
21729
|
function createDefaultWalletServicesOptions(...[chain, arcCallbackUrl, arcCallbackToken, taalArcApiKey, gorillaPoolArcApiKey, bitailsApiKey, deploymentId, chaintracks, arcadeUrl, arcadeApiKey, arcadeCallbackToken]) {
|
|
21497
21730
|
if (chain === "mock") throw new Error("createDefaultWalletServicesOptions does not support 'mock' chain. Use MockServices directly.");
|
|
21498
21731
|
deploymentId ||= `wallet-toolbox-${randomBytesHex(16)}`;
|
|
21499
|
-
let chaintracksUrl;
|
|
21500
|
-
if (chain === "ttn") chaintracksUrl = "https://arcade-v2-ttn-us-1.bsvblockchain.tech/chaintracks/v1";
|
|
21501
|
-
else if (chain === "tstn") chaintracksUrl = tstnChaintracksUrl();
|
|
21502
|
-
else chaintracksUrl = `https://${chain}net-chaintracks.babbage.systems`;
|
|
21503
21732
|
const chaintracksFiatExchangeRatesUrl = "https://mainnet-chaintracks.babbage.systems/getFiatExchangeRates";
|
|
21504
|
-
chaintracks ||=
|
|
21733
|
+
chaintracks ||= createDefaultChaintracksClient(chain);
|
|
21505
21734
|
const o = {
|
|
21506
21735
|
chain,
|
|
21507
21736
|
taalApiKey: void 0,
|
|
@@ -21559,14 +21788,15 @@ function createDefaultWalletServicesOptions(...[chain, arcCallbackUrl, arcCallba
|
|
|
21559
21788
|
}
|
|
21560
21789
|
/**
|
|
21561
21790
|
* Default Arcade (bsv-blockchain/arcade) endpoint per chain.
|
|
21562
|
-
* Returns undefined when no public default is known for the chain
|
|
21791
|
+
* Returns undefined when no public default is known for the chain.
|
|
21563
21792
|
*/
|
|
21564
21793
|
function arcadeDefaultUrl(chain) {
|
|
21565
21794
|
switch (chain) {
|
|
21566
|
-
case "main":
|
|
21567
|
-
case "
|
|
21795
|
+
case "main":
|
|
21796
|
+
case "test":
|
|
21797
|
+
case "ttn": return publicArcadeUrl(chain);
|
|
21798
|
+
case "stn": return stnArcadeUrl();
|
|
21568
21799
|
case "tstn": return tstnArcadeUrl();
|
|
21569
|
-
case "test": return;
|
|
21570
21800
|
case "mock": return;
|
|
21571
21801
|
}
|
|
21572
21802
|
}
|
|
@@ -21574,6 +21804,7 @@ function arcDefaultUrl(chain) {
|
|
|
21574
21804
|
switch (chain) {
|
|
21575
21805
|
case "main": return "https://arc.taal.com";
|
|
21576
21806
|
case "test": return "https://arc-test.taal.com";
|
|
21807
|
+
case "stn": return stnArcadeUrl() ?? "";
|
|
21577
21808
|
case "ttn": return "https://arcade-v2-ttn-us-1.bsvblockchain.tech/";
|
|
21578
21809
|
case "tstn": return tstnArcadeUrl() ?? "";
|
|
21579
21810
|
case "mock": return "";
|
|
@@ -22955,7 +23186,7 @@ var Services = class Services {
|
|
|
22955
23186
|
telemetry;
|
|
22956
23187
|
constructor(optionsOrChain) {
|
|
22957
23188
|
this.chain = typeof optionsOrChain === "string" ? optionsOrChain : optionsOrChain.chain;
|
|
22958
|
-
if (this.chain === "mock") throw new WERR_INVALID_PARAMETER("chain", "'main', 'test', 'ttn', or 'tstn'. Use MockServices for 'mock' chain.");
|
|
23189
|
+
if (this.chain === "mock") throw new WERR_INVALID_PARAMETER("chain", "'main', 'test', 'stn', 'ttn', or 'tstn'. Use MockServices for 'mock' chain.");
|
|
22959
23190
|
this.options = typeof optionsOrChain === "string" ? Services.createDefaultOptions(this.chain) : optionsOrChain;
|
|
22960
23191
|
this.telemetry = new _bsv_sdk.Telemetry(this.options.telemetry);
|
|
22961
23192
|
this.whatsonchain = new WhatsOnChain(this.chain, { apiKey: this.options.whatsOnChainApiKey }, this);
|
|
@@ -22969,7 +23200,7 @@ var Services = class Services {
|
|
|
22969
23200
|
if (this.options.arcGorillaPoolUrl != null && this.options.arcGorillaPoolUrl !== "") this.arcGorillaPool = new ARC(this.options.arcGorillaPoolUrl, this.options.arcGorillaPoolConfig, "arcGorillaPool");
|
|
22970
23201
|
if (this.options.arcadeUrl != null && this.options.arcadeUrl !== "") this.arcade = new Arcade(this.options.arcadeUrl, this.options.arcadeConfig, "arcade");
|
|
22971
23202
|
const hasBitails = this.chain === "main" || this.chain === "test";
|
|
22972
|
-
const hasWhatsOnChain = this.chain
|
|
23203
|
+
const hasWhatsOnChain = this.chain === "main" || this.chain === "test";
|
|
22973
23204
|
if (hasBitails) this.bitails = new Bitails(this.chain, { apiKey: this.options.bitailsApiKey });
|
|
22974
23205
|
return {
|
|
22975
23206
|
hasBitails,
|
|
@@ -23683,9 +23914,22 @@ function classifyMerklePathResponse(status, statusText, retry) {
|
|
|
23683
23914
|
//#endregion
|
|
23684
23915
|
//#region ../src/services/providers/WhatsOnChain.ts
|
|
23685
23916
|
var WhatsOnChainNoServices = class extends SdkWhatsOnChain {
|
|
23917
|
+
requestGate;
|
|
23686
23918
|
constructor(chain = "main", config = {}) {
|
|
23687
23919
|
if (chain === "mock") throw new Error("WhatsOnChain does not support 'mock' chain. Use MockServices directly.");
|
|
23688
23920
|
super(chain, config);
|
|
23921
|
+
this.requestGate = config.requestGate;
|
|
23922
|
+
}
|
|
23923
|
+
async requestWithAnonymousAuthFallback(url, requestOptions) {
|
|
23924
|
+
await this.requestGate?.();
|
|
23925
|
+
const response = await this.httpClient.request(url, requestOptions);
|
|
23926
|
+
if (response.status !== 401 && response.status !== 403 || this.apiKey.trim() === "") return response;
|
|
23927
|
+
if (this.requestGate != null) await this.requestGate();
|
|
23928
|
+
else await wait(350);
|
|
23929
|
+
return await this.httpClient.request(url, {
|
|
23930
|
+
method: "GET",
|
|
23931
|
+
headers: { Accept: "application/json" }
|
|
23932
|
+
});
|
|
23689
23933
|
}
|
|
23690
23934
|
/**
|
|
23691
23935
|
* POST
|
|
@@ -24094,7 +24338,7 @@ var WhatsOnChainNoServices = class extends SdkWhatsOnChain {
|
|
|
24094
24338
|
};
|
|
24095
24339
|
const url = `${this.URL}/block/${hash}/header`;
|
|
24096
24340
|
for (let retry = 0; retry < 2; retry++) {
|
|
24097
|
-
const response = await this.
|
|
24341
|
+
const response = await this.requestWithAnonymousAuthFallback(url, requestOptions);
|
|
24098
24342
|
if (response.statusText === "Too Many Requests" && retry < 2) {
|
|
24099
24343
|
await wait(2e3);
|
|
24100
24344
|
continue;
|
|
@@ -24112,7 +24356,7 @@ var WhatsOnChainNoServices = class extends SdkWhatsOnChain {
|
|
|
24112
24356
|
};
|
|
24113
24357
|
const url = `${this.URL}/chain/info`;
|
|
24114
24358
|
for (let retry = 0; retry < 2; retry++) {
|
|
24115
|
-
const response = await this.
|
|
24359
|
+
const response = await this.requestWithAnonymousAuthFallback(url, requestOptions);
|
|
24116
24360
|
if (response.statusText === "Too Many Requests" && retry < 2) {
|
|
24117
24361
|
await wait(2e3);
|
|
24118
24362
|
continue;
|
|
@@ -24298,12 +24542,16 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24298
24542
|
timeout: 3e4,
|
|
24299
24543
|
userAgent: "BabbageWhatsOnChainServices",
|
|
24300
24544
|
enableCache: true,
|
|
24301
|
-
chainInfoMsecs: 5e3
|
|
24545
|
+
chainInfoMsecs: 5e3,
|
|
24546
|
+
minRequestIntervalMsecs: 350
|
|
24302
24547
|
};
|
|
24303
24548
|
}
|
|
24304
24549
|
static chainInfo = [];
|
|
24305
24550
|
static chainInfoTime = [];
|
|
24306
24551
|
static chainInfoMsecs = [];
|
|
24552
|
+
static chainInfoPromise = {};
|
|
24553
|
+
static requestTail = Promise.resolve();
|
|
24554
|
+
static nextRequestMsecs = 0;
|
|
24307
24555
|
chain;
|
|
24308
24556
|
woc;
|
|
24309
24557
|
constructor(options) {
|
|
@@ -24312,7 +24560,8 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24312
24560
|
apiKey: this.options.apiKey,
|
|
24313
24561
|
timeout: this.options.timeout,
|
|
24314
24562
|
userAgent: this.options.userAgent,
|
|
24315
|
-
enableCache: this.options.enableCache
|
|
24563
|
+
enableCache: this.options.enableCache,
|
|
24564
|
+
requestGate: async () => await this.waitForRateLimit()
|
|
24316
24565
|
};
|
|
24317
24566
|
this.chain = options.chain;
|
|
24318
24567
|
const chainInfoMsecs = WhatsOnChainServices.chainInfoMsecs;
|
|
@@ -24330,7 +24579,16 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24330
24579
|
let update = chainInfo[this.chain] === void 0;
|
|
24331
24580
|
if (!update && chainInfoTime[this.chain] !== void 0) update = now.getTime() - chainInfoTime[this.chain].getTime() > chainInfoMsecs[this.chain];
|
|
24332
24581
|
if (update) {
|
|
24333
|
-
|
|
24582
|
+
let pending = WhatsOnChainServices.chainInfoPromise[this.chain];
|
|
24583
|
+
if (pending == null) {
|
|
24584
|
+
pending = this.woc.getChainInfo();
|
|
24585
|
+
WhatsOnChainServices.chainInfoPromise[this.chain] = pending;
|
|
24586
|
+
}
|
|
24587
|
+
try {
|
|
24588
|
+
chainInfo[this.chain] = await pending;
|
|
24589
|
+
} finally {
|
|
24590
|
+
if (WhatsOnChainServices.chainInfoPromise[this.chain] === pending) delete WhatsOnChainServices.chainInfoPromise[this.chain];
|
|
24591
|
+
}
|
|
24334
24592
|
chainInfoTime[this.chain] = now;
|
|
24335
24593
|
}
|
|
24336
24594
|
if (!chainInfo[this.chain]) throw new Error("Unexpected failure to update chainInfo.");
|
|
@@ -24348,10 +24606,12 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24348
24606
|
*/
|
|
24349
24607
|
async getHeaders(fetch) {
|
|
24350
24608
|
fetch ||= new ChaintracksFetch();
|
|
24609
|
+
await this.waitForRateLimit();
|
|
24351
24610
|
return await fetch.fetchJson(`https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers`);
|
|
24352
24611
|
}
|
|
24353
24612
|
async getHeaderByteFileLinks(neededRange, fetch) {
|
|
24354
24613
|
fetch ||= new ChaintracksFetch();
|
|
24614
|
+
await this.waitForRateLimit();
|
|
24355
24615
|
const files = await fetch.fetchJson(`https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers/resources`);
|
|
24356
24616
|
const r = [];
|
|
24357
24617
|
let range;
|
|
@@ -24364,6 +24624,21 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24364
24624
|
}
|
|
24365
24625
|
return r;
|
|
24366
24626
|
}
|
|
24627
|
+
async waitForRateLimit() {
|
|
24628
|
+
let release;
|
|
24629
|
+
const previous = WhatsOnChainServices.requestTail;
|
|
24630
|
+
WhatsOnChainServices.requestTail = new Promise((resolve) => {
|
|
24631
|
+
release = resolve;
|
|
24632
|
+
});
|
|
24633
|
+
await previous;
|
|
24634
|
+
try {
|
|
24635
|
+
const delay = Math.max(0, WhatsOnChainServices.nextRequestMsecs - Date.now());
|
|
24636
|
+
if (delay > 0) await wait(delay);
|
|
24637
|
+
WhatsOnChainServices.nextRequestMsecs = Date.now() + (this.options.minRequestIntervalMsecs ?? 350);
|
|
24638
|
+
} finally {
|
|
24639
|
+
release();
|
|
24640
|
+
}
|
|
24641
|
+
}
|
|
24367
24642
|
};
|
|
24368
24643
|
function wocGetHeadersHeaderToBlockHeader(h) {
|
|
24369
24644
|
const bits = typeof h.bits === "string" ? Number.parseInt(h.bits, 16) : h.bits;
|
|
@@ -24424,6 +24699,51 @@ var BulkIngestorWhatsOnChainCdn = class extends BulkIngestorBase {
|
|
|
24424
24699
|
}
|
|
24425
24700
|
};
|
|
24426
24701
|
//#endregion
|
|
24702
|
+
//#region ../src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.ts
|
|
24703
|
+
/**
|
|
24704
|
+
* Uses a go-chaintracks/Arcade-compatible service as a validated bulk source.
|
|
24705
|
+
* Retrieved bytes still pass through ChainTracks' local serialization, hash,
|
|
24706
|
+
* continuity, and genesis checks before storage.
|
|
24707
|
+
*/
|
|
24708
|
+
var BulkIngestorChaintracks = class extends BulkIngestorBase {
|
|
24709
|
+
chaintracks;
|
|
24710
|
+
maxHeadersPerRequest;
|
|
24711
|
+
networkChecked = false;
|
|
24712
|
+
constructor(options) {
|
|
24713
|
+
super(options);
|
|
24714
|
+
this.chaintracks = options.chaintracks;
|
|
24715
|
+
this.maxHeadersPerRequest = options.maxHeadersPerRequest ?? 1e3;
|
|
24716
|
+
if (!Number.isInteger(this.maxHeadersPerRequest) || this.maxHeadersPerRequest < 1) throw new Error("maxHeadersPerRequest must be a positive integer.");
|
|
24717
|
+
}
|
|
24718
|
+
async getPresentHeight() {
|
|
24719
|
+
await this.ensureNetwork();
|
|
24720
|
+
return await this.chaintracks.getPresentHeight();
|
|
24721
|
+
}
|
|
24722
|
+
async fetchHeaders(_before, fetchRange, bulkRange, priorLiveHeaders) {
|
|
24723
|
+
if (fetchRange.isEmpty) return priorLiveHeaders;
|
|
24724
|
+
await this.ensureNetwork();
|
|
24725
|
+
let liveHeaders = priorLiveHeaders;
|
|
24726
|
+
let height = fetchRange.minHeight;
|
|
24727
|
+
while (height <= fetchRange.maxHeight) {
|
|
24728
|
+
const requested = Math.min(this.maxHeadersPerRequest, fetchRange.maxHeight - height + 1);
|
|
24729
|
+
const bytes = asUint8Array(await this.chaintracks.getHeaders(height, requested));
|
|
24730
|
+
if (bytes.length === 0) throw new Error(`ChainTracks upstream returned no headers at height ${height}.`);
|
|
24731
|
+
if (bytes.length % 80 !== 0 || bytes.length > requested * 80) throw new Error(`ChainTracks upstream returned ${bytes.length} bytes for ${requested} headers at height ${height}.`);
|
|
24732
|
+
const headers = deserializeBlockHeaders(height, bytes);
|
|
24733
|
+
liveHeaders = await this.storage().addBulkHeaders(headers, bulkRange, liveHeaders);
|
|
24734
|
+
height += headers.length;
|
|
24735
|
+
if (headers.length < requested && height <= fetchRange.maxHeight) throw new Error(`ChainTracks upstream returned ${headers.length} of ${requested} headers at height ${height - headers.length}.`);
|
|
24736
|
+
}
|
|
24737
|
+
return liveHeaders;
|
|
24738
|
+
}
|
|
24739
|
+
async ensureNetwork() {
|
|
24740
|
+
if (this.networkChecked) return;
|
|
24741
|
+
const actual = await this.chaintracks.getChain();
|
|
24742
|
+
if (actual !== this.chain) throw new Error(`ChainTracks upstream network '${actual}' does not match configured chain '${this.chain}'.`);
|
|
24743
|
+
this.networkChecked = true;
|
|
24744
|
+
}
|
|
24745
|
+
};
|
|
24746
|
+
//#endregion
|
|
24427
24747
|
//#region ../src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.ts
|
|
24428
24748
|
/**
|
|
24429
24749
|
* Reports new headers by polling periodically.
|
|
@@ -24530,9 +24850,17 @@ var LiveIngestorChaintracksSSE = class extends LiveIngestorBase {
|
|
|
24530
24850
|
}
|
|
24531
24851
|
async startListening(liveHeaders) {
|
|
24532
24852
|
this.stopped = false;
|
|
24533
|
-
|
|
24853
|
+
const actual = await this.options.chaintracks.getChain();
|
|
24854
|
+
if (actual !== this.chain) throw new Error(`ChainTracks upstream network '${actual}' does not match configured chain '${this.chain}'.`);
|
|
24855
|
+
if (this.stopped) return;
|
|
24856
|
+
const subscriptionId = await this.options.chaintracks.subscribeHeaders((header) => {
|
|
24534
24857
|
if (!this.stopped) liveHeaders.push(header);
|
|
24535
24858
|
});
|
|
24859
|
+
if (this.stopped) {
|
|
24860
|
+
await this.options.chaintracks.unsubscribe(subscriptionId);
|
|
24861
|
+
return;
|
|
24862
|
+
}
|
|
24863
|
+
this.subscriptionId = subscriptionId;
|
|
24536
24864
|
await new Promise((resolve) => {
|
|
24537
24865
|
this.resolveStopped = resolve;
|
|
24538
24866
|
if (this.stopped) resolve();
|
|
@@ -24545,7 +24873,9 @@ var LiveIngestorChaintracksSSE = class extends LiveIngestorBase {
|
|
|
24545
24873
|
if (subscriptionId != null) this.options.chaintracks.unsubscribe(subscriptionId).catch((e) => {
|
|
24546
24874
|
this.log(`LiveIngestorChaintracksSSE unsubscribe failed: ${e}`);
|
|
24547
24875
|
});
|
|
24548
|
-
this.resolveStopped
|
|
24876
|
+
const resolveStopped = this.resolveStopped;
|
|
24877
|
+
this.resolveStopped = void 0;
|
|
24878
|
+
resolveStopped?.();
|
|
24549
24879
|
}
|
|
24550
24880
|
async shutdown() {
|
|
24551
24881
|
this.stopListening();
|
|
@@ -25241,6 +25571,27 @@ var ChaintracksStorageNoDb = class ChaintracksStorageNoDb extends ChaintracksSto
|
|
|
25241
25571
|
tipHeaderId: 0,
|
|
25242
25572
|
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25243
25573
|
};
|
|
25574
|
+
static stnData = {
|
|
25575
|
+
chain: "stn",
|
|
25576
|
+
liveHeaders: /* @__PURE__ */ new Map(),
|
|
25577
|
+
maxHeaderId: 0,
|
|
25578
|
+
tipHeaderId: 0,
|
|
25579
|
+
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25580
|
+
};
|
|
25581
|
+
static ttnData = {
|
|
25582
|
+
chain: "ttn",
|
|
25583
|
+
liveHeaders: /* @__PURE__ */ new Map(),
|
|
25584
|
+
maxHeaderId: 0,
|
|
25585
|
+
tipHeaderId: 0,
|
|
25586
|
+
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25587
|
+
};
|
|
25588
|
+
static tstnData = {
|
|
25589
|
+
chain: "tstn",
|
|
25590
|
+
liveHeaders: /* @__PURE__ */ new Map(),
|
|
25591
|
+
maxHeaderId: 0,
|
|
25592
|
+
tipHeaderId: 0,
|
|
25593
|
+
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25594
|
+
};
|
|
25244
25595
|
constructor(options) {
|
|
25245
25596
|
super(options);
|
|
25246
25597
|
}
|
|
@@ -25248,10 +25599,11 @@ var ChaintracksStorageNoDb = class ChaintracksStorageNoDb extends ChaintracksSto
|
|
|
25248
25599
|
async getData() {
|
|
25249
25600
|
switch (this.chain) {
|
|
25250
25601
|
case "main": return ChaintracksStorageNoDb.mainData;
|
|
25251
|
-
case "test":
|
|
25252
|
-
case "
|
|
25253
|
-
case "
|
|
25254
|
-
|
|
25602
|
+
case "test": return ChaintracksStorageNoDb.testData;
|
|
25603
|
+
case "stn": return ChaintracksStorageNoDb.stnData;
|
|
25604
|
+
case "ttn": return ChaintracksStorageNoDb.ttnData;
|
|
25605
|
+
case "tstn": return ChaintracksStorageNoDb.tstnData;
|
|
25606
|
+
default: throw new WERR_INVALID_PARAMETER("chain", `'main', 'test', 'stn', 'ttn', or 'tstn'. '${this.chain}' is unsupported.`);
|
|
25255
25607
|
}
|
|
25256
25608
|
}
|
|
25257
25609
|
async deleteLiveBlockHeaders() {
|
|
@@ -25840,7 +26192,7 @@ var ChaintracksStorageIdb = class extends ChaintracksStorageBase {
|
|
|
25840
26192
|
//#endregion
|
|
25841
26193
|
//#region ../src/services/chaintracker/chaintracks/configureChaintracksIngestors.ts
|
|
25842
26194
|
function resolveDefaultChaintracksArguments(args) {
|
|
25843
|
-
const [chain, whatsonchainApiKey = "", maxPerFile = 1e5, maxRetained = 2, fetch = new ChaintracksFetch(), cdnUrl = "https://cdn.projectbabbage.com/blockheaders/", liveHeightThreshold = 2e3, reorgHeightThreshold = 400, bulkMigrationChunkSize = 500, batchInsertLimit = 400, addLiveRecursionLimit = 36] = args;
|
|
26195
|
+
const [chain, whatsonchainApiKey = "", maxPerFile = 1e5, maxRetained = 2, fetch = new ChaintracksFetch(), cdnUrl = chain === "main" || chain === "test" ? "https://cdn.projectbabbage.com/blockheaders/" : "", liveHeightThreshold = 2e3, reorgHeightThreshold = 400, bulkMigrationChunkSize = 500, batchInsertLimit = 400, addLiveRecursionLimit = 36, sources = {}] = args;
|
|
25844
26196
|
return {
|
|
25845
26197
|
chain,
|
|
25846
26198
|
whatsonchainApiKey,
|
|
@@ -25852,11 +26204,12 @@ function resolveDefaultChaintracksArguments(args) {
|
|
|
25852
26204
|
reorgHeightThreshold,
|
|
25853
26205
|
bulkMigrationChunkSize,
|
|
25854
26206
|
batchInsertLimit,
|
|
25855
|
-
addLiveRecursionLimit
|
|
26207
|
+
addLiveRecursionLimit,
|
|
26208
|
+
sources
|
|
25856
26209
|
};
|
|
25857
26210
|
}
|
|
25858
26211
|
function toDefaultChaintracksArguments(params) {
|
|
25859
|
-
|
|
26212
|
+
const args = [
|
|
25860
26213
|
params.chain,
|
|
25861
26214
|
params.whatsonchainApiKey,
|
|
25862
26215
|
params.maxPerFile,
|
|
@@ -25869,6 +26222,8 @@ function toDefaultChaintracksArguments(params) {
|
|
|
25869
26222
|
params.batchInsertLimit,
|
|
25870
26223
|
params.addLiveRecursionLimit
|
|
25871
26224
|
];
|
|
26225
|
+
if (Object.keys(params.sources).length > 0) args.push(params.sources);
|
|
26226
|
+
return args;
|
|
25872
26227
|
}
|
|
25873
26228
|
function createDefaultBulkFileDataManager(params) {
|
|
25874
26229
|
return new BulkFileDataManager({
|
|
@@ -25911,7 +26266,7 @@ function createAndStartDefaultChaintracks(args, createOptions) {
|
|
|
25911
26266
|
* The caller is responsible for providing the storage implementation.
|
|
25912
26267
|
*/
|
|
25913
26268
|
function buildChaintracksOptionsWithIngestors(params, storage) {
|
|
25914
|
-
const { chain, whatsonchainApiKey, maxPerFile, fetch, cdnUrl, addLiveRecursionLimit } = params;
|
|
26269
|
+
const { chain, whatsonchainApiKey, maxPerFile, fetch, cdnUrl, addLiveRecursionLimit, sources } = params;
|
|
25915
26270
|
const co = {
|
|
25916
26271
|
chain,
|
|
25917
26272
|
storage,
|
|
@@ -25922,35 +26277,58 @@ function buildChaintracksOptionsWithIngestors(params, storage) {
|
|
|
25922
26277
|
readonly: false
|
|
25923
26278
|
};
|
|
25924
26279
|
const jsonResource = `${chain}NetBlockHeaders.json`;
|
|
25925
|
-
|
|
25926
|
-
|
|
25927
|
-
|
|
25928
|
-
|
|
25929
|
-
|
|
25930
|
-
|
|
25931
|
-
|
|
25932
|
-
|
|
25933
|
-
|
|
25934
|
-
|
|
25935
|
-
|
|
25936
|
-
|
|
25937
|
-
|
|
25938
|
-
|
|
25939
|
-
|
|
25940
|
-
|
|
25941
|
-
|
|
25942
|
-
|
|
25943
|
-
|
|
25944
|
-
|
|
25945
|
-
|
|
25946
|
-
|
|
25947
|
-
|
|
25948
|
-
|
|
25949
|
-
|
|
25950
|
-
|
|
25951
|
-
|
|
26280
|
+
if (!sources.disableCdn && cdnUrl !== "") {
|
|
26281
|
+
const bulkCdnOptions = {
|
|
26282
|
+
chain,
|
|
26283
|
+
jsonResource,
|
|
26284
|
+
fetch,
|
|
26285
|
+
cdnUrl,
|
|
26286
|
+
maxPerFile
|
|
26287
|
+
};
|
|
26288
|
+
co.bulkIngestors.push(new BulkIngestorCDNBabbage(bulkCdnOptions));
|
|
26289
|
+
}
|
|
26290
|
+
const chaintracksSource = sources.chaintracks ?? (sources.disableChaintracks ? void 0 : createPublicChaintracksSource(chain));
|
|
26291
|
+
if (chaintracksSource != null) {
|
|
26292
|
+
co.bulkIngestors.push(new BulkIngestorChaintracks({
|
|
26293
|
+
chain,
|
|
26294
|
+
jsonResource,
|
|
26295
|
+
chaintracks: chaintracksSource,
|
|
26296
|
+
maxHeadersPerRequest: sources.remoteMaxHeadersPerRequest
|
|
26297
|
+
}));
|
|
26298
|
+
co.liveIngestors.push(new LiveIngestorChaintracksSSE({
|
|
26299
|
+
chain,
|
|
26300
|
+
chaintracks: chaintracksSource
|
|
26301
|
+
}));
|
|
26302
|
+
}
|
|
26303
|
+
if ((chain === "main" || chain === "test") && !sources.disableWhatsOnChain) {
|
|
26304
|
+
const wocOptions = {
|
|
26305
|
+
chain,
|
|
26306
|
+
apiKey: whatsonchainApiKey,
|
|
26307
|
+
timeout: 3e4,
|
|
26308
|
+
userAgent: "BabbageWhatsOnChainServices",
|
|
26309
|
+
enableCache: true,
|
|
26310
|
+
chainInfoMsecs: 5e3
|
|
26311
|
+
};
|
|
26312
|
+
const bulkOptions = {
|
|
26313
|
+
...wocOptions,
|
|
26314
|
+
jsonResource,
|
|
26315
|
+
idleWait: 5e3
|
|
26316
|
+
};
|
|
26317
|
+
co.bulkIngestors.push(new BulkIngestorWhatsOnChainCdn(bulkOptions));
|
|
26318
|
+
const liveOptions = {
|
|
26319
|
+
...wocOptions,
|
|
26320
|
+
idleWait: 1e5
|
|
26321
|
+
};
|
|
26322
|
+
co.liveIngestors.push(new LiveIngestorWhatsOnChainPoll(liveOptions));
|
|
26323
|
+
}
|
|
26324
|
+
if (co.bulkIngestors.length === 0 || co.liveIngestors.length === 0) throw new Error(`ChainTracks ${chain} requires at least one bulk and live source. Configure sources.chaintracks for Teranode networks.`);
|
|
25952
26325
|
return co;
|
|
25953
26326
|
}
|
|
26327
|
+
function createPublicChaintracksSource(chain) {
|
|
26328
|
+
const serviceUrl = publicArcadeUrl(chain);
|
|
26329
|
+
if (serviceUrl == null) return void 0;
|
|
26330
|
+
return new GoChaintracksServiceClient(chain, serviceUrl, { apiPrefix: "/chaintracks/v2" });
|
|
26331
|
+
}
|
|
25954
26332
|
//#endregion
|
|
25955
26333
|
//#region ../src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.ts
|
|
25956
26334
|
function createDefaultNoDbChaintracksOptions(...args) {
|
|
@@ -34546,6 +34924,7 @@ exports.BulkFilesReaderStorage = BulkFilesReaderStorage;
|
|
|
34546
34924
|
exports.BulkIngestorBase = BulkIngestorBase;
|
|
34547
34925
|
exports.BulkIngestorCDN = BulkIngestorCDN;
|
|
34548
34926
|
exports.BulkIngestorCDNBabbage = BulkIngestorCDNBabbage;
|
|
34927
|
+
exports.BulkIngestorChaintracks = BulkIngestorChaintracks;
|
|
34549
34928
|
exports.BulkIngestorWhatsOnChainCdn = BulkIngestorWhatsOnChainCdn;
|
|
34550
34929
|
exports.BulkStorageBase = BulkStorageBase;
|
|
34551
34930
|
exports.CWIStyleWalletManager = CWIStyleWalletManager;
|
|
@@ -34624,7 +35003,12 @@ exports.asBsvSdkTx = asBsvSdkTx;
|
|
|
34624
35003
|
exports.asString = asString;
|
|
34625
35004
|
exports.asUint8Array = asUint8Array;
|
|
34626
35005
|
exports.brc29ProtocolID = brc29ProtocolID;
|
|
35006
|
+
exports.buildChaintracksOptionsWithIngestors = buildChaintracksOptionsWithIngestors;
|
|
34627
35007
|
exports.convertProofToMerklePath = convertProofToMerklePath;
|
|
35008
|
+
exports.createAndStartDefaultChaintracks = createAndStartDefaultChaintracks;
|
|
35009
|
+
exports.createDefaultBulkFileDataManager = createDefaultBulkFileDataManager;
|
|
35010
|
+
exports.createDefaultChaintracksClient = createDefaultChaintracksClient;
|
|
35011
|
+
exports.createDefaultChaintracksStorageOptions = createDefaultChaintracksStorageOptions;
|
|
34628
35012
|
exports.createDefaultIdbChaintracksOptions = createDefaultIdbChaintracksOptions;
|
|
34629
35013
|
exports.createDefaultNoDbChaintracksOptions = createDefaultNoDbChaintracksOptions;
|
|
34630
35014
|
exports.createDefaultWalletServicesOptions = createDefaultWalletServicesOptions;
|
|
@@ -34666,6 +35050,7 @@ exports.partitionActionLabels = partitionActionLabels;
|
|
|
34666
35050
|
exports.randomBytes = randomBytes;
|
|
34667
35051
|
exports.randomBytesBase64 = randomBytesBase64;
|
|
34668
35052
|
exports.randomBytesHex = randomBytesHex;
|
|
35053
|
+
exports.resolveDefaultChaintracksArguments = resolveDefaultChaintracksArguments;
|
|
34669
35054
|
Object.defineProperty(exports, "sdk", {
|
|
34670
35055
|
enumerable: true,
|
|
34671
35056
|
get: function() {
|
|
@@ -34676,9 +35061,11 @@ exports.selectBulkHeaderFiles = selectBulkHeaderFiles;
|
|
|
34676
35061
|
exports.sha256Hash = sha256Hash;
|
|
34677
35062
|
exports.stampLog = stampLog;
|
|
34678
35063
|
exports.stampLogFormat = stampLogFormat;
|
|
35064
|
+
exports.startChaintracks = startChaintracks;
|
|
34679
35065
|
exports.tableAuthSessionToPeerSession = tableAuthSessionToPeerSession;
|
|
34680
35066
|
exports.throwDummyReviewActions = throwDummyReviewActions;
|
|
34681
35067
|
exports.toBinaryBaseBlockHeader = toBinaryBaseBlockHeader;
|
|
35068
|
+
exports.toDefaultChaintracksArguments = toDefaultChaintracksArguments;
|
|
34682
35069
|
exports.toLookupNetworkPreset = toLookupNetworkPreset;
|
|
34683
35070
|
exports.toWalletNetwork = toWalletNetwork;
|
|
34684
35071
|
exports.transactionColumnsWithoutRawTx = transactionColumnsWithoutRawTx;
|