@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.mjs
CHANGED
|
@@ -970,6 +970,7 @@ function toWalletNetwork(chain) {
|
|
|
970
970
|
switch (chain) {
|
|
971
971
|
case "main": return "mainnet";
|
|
972
972
|
case "test":
|
|
973
|
+
case "stn":
|
|
973
974
|
case "ttn":
|
|
974
975
|
case "tstn":
|
|
975
976
|
case "mock": return "testnet";
|
|
@@ -983,6 +984,7 @@ function toLookupNetworkPreset(chain) {
|
|
|
983
984
|
switch (chain) {
|
|
984
985
|
case "main": return "mainnet";
|
|
985
986
|
case "test": return "testnet";
|
|
987
|
+
case "stn":
|
|
986
988
|
case "ttn":
|
|
987
989
|
case "tstn":
|
|
988
990
|
case "mock": return "local";
|
|
@@ -11732,9 +11734,7 @@ function genesisHeader(chain) {
|
|
|
11732
11734
|
height: 0,
|
|
11733
11735
|
hash: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
|
11734
11736
|
};
|
|
11735
|
-
case "test":
|
|
11736
|
-
case "ttn":
|
|
11737
|
-
case "tstn": return {
|
|
11737
|
+
case "test": return {
|
|
11738
11738
|
version: 1,
|
|
11739
11739
|
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11740
11740
|
merkleRoot: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
@@ -11744,6 +11744,36 @@ function genesisHeader(chain) {
|
|
|
11744
11744
|
height: 0,
|
|
11745
11745
|
hash: "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
|
11746
11746
|
};
|
|
11747
|
+
case "stn": return {
|
|
11748
|
+
version: 1,
|
|
11749
|
+
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11750
|
+
merkleRoot: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
11751
|
+
time: 1296688602,
|
|
11752
|
+
bits: 486604799,
|
|
11753
|
+
nonce: 173779992,
|
|
11754
|
+
height: 0,
|
|
11755
|
+
hash: "6b38bdbcd73a19f7889d23e1fa6166a9de71affceca60ca3bb1b28af8135c594"
|
|
11756
|
+
};
|
|
11757
|
+
case "ttn": return {
|
|
11758
|
+
version: 1,
|
|
11759
|
+
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11760
|
+
merkleRoot: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
11761
|
+
time: 1755606836,
|
|
11762
|
+
bits: 486604799,
|
|
11763
|
+
nonce: 1092578460,
|
|
11764
|
+
height: 0,
|
|
11765
|
+
hash: "000000000499eabba0a88f5b3747231c74b9191c1a4a04b2c2ea817976b7776d"
|
|
11766
|
+
};
|
|
11767
|
+
case "tstn": return {
|
|
11768
|
+
version: 1,
|
|
11769
|
+
previousHash: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
11770
|
+
merkleRoot: "64452e5b25c65e492ad6a4f5ce9f427ca986626c28315d88de920d66e28cc98f",
|
|
11771
|
+
time: 1782864e3,
|
|
11772
|
+
bits: 486604799,
|
|
11773
|
+
nonce: 1780488216,
|
|
11774
|
+
height: 0,
|
|
11775
|
+
hash: "000000005d221c0e023cb56b5682cf094f32cd959958b40bc931e5797cae706c"
|
|
11776
|
+
};
|
|
11747
11777
|
case "mock": throw new Error("genesisHeader does not support 'mock' chain. Mock chain generates its own genesis block.");
|
|
11748
11778
|
}
|
|
11749
11779
|
}
|
|
@@ -19271,10 +19301,11 @@ var Chaintracks = class {
|
|
|
19271
19301
|
startupError = null;
|
|
19272
19302
|
subscriberCallbacksEnabled = false;
|
|
19273
19303
|
stopMainThread = true;
|
|
19274
|
-
lastPresentHeight =
|
|
19304
|
+
lastPresentHeight = -1;
|
|
19275
19305
|
lastPresentHeightMsecs = 0;
|
|
19276
19306
|
lastPresentHeightMaxAge = 60 * 1e3;
|
|
19277
19307
|
lock = new SingleWriterMultiReaderLock();
|
|
19308
|
+
sourceStatus = /* @__PURE__ */ new Map();
|
|
19278
19309
|
constructor(options) {
|
|
19279
19310
|
this.options = options;
|
|
19280
19311
|
if (options.storage == null) throw new Error("storage is required.");
|
|
@@ -19285,6 +19316,22 @@ var Chaintracks = class {
|
|
|
19285
19316
|
this.storage = options.storage;
|
|
19286
19317
|
this.bulkIngestors = options.bulkIngestors;
|
|
19287
19318
|
this.liveIngestors = options.liveIngestors;
|
|
19319
|
+
for (const [index, source] of this.bulkIngestors.entries()) {
|
|
19320
|
+
const name = this.sourceName("bulk", index, source);
|
|
19321
|
+
this.sourceStatus.set(name, {
|
|
19322
|
+
name,
|
|
19323
|
+
role: "bulk",
|
|
19324
|
+
state: "unknown"
|
|
19325
|
+
});
|
|
19326
|
+
}
|
|
19327
|
+
for (const [index, source] of this.liveIngestors.entries()) {
|
|
19328
|
+
const name = this.sourceName("live", index, source);
|
|
19329
|
+
this.sourceStatus.set(name, {
|
|
19330
|
+
name,
|
|
19331
|
+
role: "live",
|
|
19332
|
+
state: "unknown"
|
|
19333
|
+
});
|
|
19334
|
+
}
|
|
19288
19335
|
this.addLiveRecursionLimit = options.addLiveRecursionLimit;
|
|
19289
19336
|
if (options.logging != null) this.log = options.logging;
|
|
19290
19337
|
this.storage.log = this.log;
|
|
@@ -19299,19 +19346,36 @@ var Chaintracks = class {
|
|
|
19299
19346
|
*/
|
|
19300
19347
|
async getPresentHeight() {
|
|
19301
19348
|
const now = Date.now();
|
|
19302
|
-
if (this.lastPresentHeight && now - this.lastPresentHeightMsecs < this.lastPresentHeightMaxAge) return this.lastPresentHeight;
|
|
19303
|
-
const
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19312
|
-
|
|
19313
|
-
|
|
19314
|
-
|
|
19349
|
+
if (this.lastPresentHeight >= 0 && now - this.lastPresentHeightMsecs < this.lastPresentHeightMaxAge) return this.lastPresentHeight;
|
|
19350
|
+
for (const [index, bulk] of this.bulkIngestors.entries()) {
|
|
19351
|
+
const source = this.sourceName("bulk", index, bulk);
|
|
19352
|
+
try {
|
|
19353
|
+
const presentHeight = await bulk.getPresentHeight();
|
|
19354
|
+
if (presentHeight != null && Number.isInteger(presentHeight) && presentHeight >= 0) {
|
|
19355
|
+
this.markSourceSuccess(source, "bulk");
|
|
19356
|
+
this.lastPresentHeight = presentHeight;
|
|
19357
|
+
this.lastPresentHeightMsecs = now;
|
|
19358
|
+
return presentHeight;
|
|
19359
|
+
}
|
|
19360
|
+
} catch (uerr) {
|
|
19361
|
+
const error = WalletError.fromUnknown(uerr);
|
|
19362
|
+
this.markSourceFailure(source, "bulk", error);
|
|
19363
|
+
this.log(`Present-height source ${source} failed: ${error.message}`);
|
|
19364
|
+
}
|
|
19365
|
+
}
|
|
19366
|
+
if (this.lastPresentHeight >= 0) return this.lastPresentHeight;
|
|
19367
|
+
try {
|
|
19368
|
+
const ranges = await this.storage.getAvailableHeightRanges();
|
|
19369
|
+
const localHeight = Math.max(ranges.bulk.maxHeight, ranges.live.maxHeight);
|
|
19370
|
+
if (localHeight >= 0) {
|
|
19371
|
+
this.lastPresentHeight = localHeight;
|
|
19372
|
+
this.lastPresentHeightMsecs = now;
|
|
19373
|
+
return localHeight;
|
|
19374
|
+
}
|
|
19375
|
+
} catch (error) {
|
|
19376
|
+
this.log(`Unable to read the locally validated ChainTracks height: ${WalletError.fromUnknown(error).message}`);
|
|
19377
|
+
}
|
|
19378
|
+
throw new Error("No present-height source or locally validated headers are available.");
|
|
19315
19379
|
}
|
|
19316
19380
|
async currentHeight() {
|
|
19317
19381
|
return await this.getPresentHeight();
|
|
@@ -19362,7 +19426,7 @@ var Chaintracks = class {
|
|
|
19362
19426
|
for (const bulkIn of this.bulkIngestors) await bulkIn.setStorage(this.storage, this.log);
|
|
19363
19427
|
for (const liveIn of this.liveIngestors) await liveIn.setStorage(this.storage, this.log);
|
|
19364
19428
|
this.stopMainThread = false;
|
|
19365
|
-
for (const liveIngestor of this.liveIngestors) this.promises.push(this.runLiveIngestor(liveIngestor));
|
|
19429
|
+
for (const [index, liveIngestor] of this.liveIngestors.entries()) this.promises.push(this.runLiveIngestor(liveIngestor, index));
|
|
19366
19430
|
this.promises.push(this.mainThreadShiftLiveHeaders());
|
|
19367
19431
|
while (!this.available && this.startupError == null) await wait(100);
|
|
19368
19432
|
if (this.startupError != null) throw this.startupError;
|
|
@@ -19389,10 +19453,12 @@ var Chaintracks = class {
|
|
|
19389
19453
|
async listening() {
|
|
19390
19454
|
return await this.makeAvailable();
|
|
19391
19455
|
}
|
|
19392
|
-
async runLiveIngestor(liveIngestor) {
|
|
19456
|
+
async runLiveIngestor(liveIngestor, index) {
|
|
19393
19457
|
let restartCount = 0;
|
|
19394
19458
|
const name = liveIngestor.constructor.name;
|
|
19459
|
+
const source = this.sourceName("live", index, liveIngestor);
|
|
19395
19460
|
while (!this.stopMainThread) try {
|
|
19461
|
+
this.markSourceSuccess(source, "live");
|
|
19396
19462
|
await liveIngestor.startListening(this.liveHeaders);
|
|
19397
19463
|
if (this.stopMainThread) return;
|
|
19398
19464
|
restartCount++;
|
|
@@ -19403,6 +19469,7 @@ var Chaintracks = class {
|
|
|
19403
19469
|
if (this.stopMainThread) return;
|
|
19404
19470
|
restartCount++;
|
|
19405
19471
|
const e = WalletError.fromUnknown(error_);
|
|
19472
|
+
this.markSourceFailure(source, "live", e);
|
|
19406
19473
|
const waitMsecs = this.liveIngestorRestartWaitMsecs(restartCount);
|
|
19407
19474
|
this.log(`Live ingestor ${name} failed restart=${restartCount} retryMsecs=${waitMsecs}: ${e.stack ?? e.message}`);
|
|
19408
19475
|
await wait(waitMsecs);
|
|
@@ -19450,7 +19517,8 @@ var Chaintracks = class {
|
|
|
19450
19517
|
storage: this.storage.constructor.name,
|
|
19451
19518
|
bulkIngestors: this.bulkIngestors.map((bulkIngestor) => bulkIngestor.constructor.name),
|
|
19452
19519
|
liveIngestors: this.liveIngestors.map((liveIngestor) => liveIngestor.constructor.name),
|
|
19453
|
-
packages: []
|
|
19520
|
+
packages: [],
|
|
19521
|
+
sources: Array.from(this.sourceStatus.values()).map((status) => ({ ...status }))
|
|
19454
19522
|
};
|
|
19455
19523
|
}
|
|
19456
19524
|
async getHeaders(height, count) {
|
|
@@ -19533,26 +19601,30 @@ var Chaintracks = class {
|
|
|
19533
19601
|
let madeProgress = false;
|
|
19534
19602
|
let hadSuccess = false;
|
|
19535
19603
|
let done = false;
|
|
19536
|
-
for (const bulk of this.bulkIngestors)
|
|
19537
|
-
const
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
19550
|
-
|
|
19604
|
+
for (const [index, bulk] of this.bulkIngestors.entries()) {
|
|
19605
|
+
const source = this.sourceName("bulk", index, bulk);
|
|
19606
|
+
try {
|
|
19607
|
+
const beforeBulkMax = before.bulk.maxHeight;
|
|
19608
|
+
const beforeLiveRange = HeightRange.from(newLiveHeaders);
|
|
19609
|
+
const r = await bulk.synchronize(presentHeight, before, newLiveHeaders);
|
|
19610
|
+
hadSuccess = true;
|
|
19611
|
+
this.markSourceSuccess(source, "bulk");
|
|
19612
|
+
newLiveHeaders = r.liveHeaders;
|
|
19613
|
+
after = await this.storage.getAvailableHeightRanges();
|
|
19614
|
+
const added = after.bulk.above(before.bulk);
|
|
19615
|
+
const afterLiveRange = HeightRange.from(newLiveHeaders);
|
|
19616
|
+
if (after.bulk.maxHeight > beforeBulkMax || afterLiveRange.maxHeight > beforeLiveRange.maxHeight) madeProgress = true;
|
|
19617
|
+
before = after;
|
|
19618
|
+
this.log(`Bulk Ingestor: ${added.length} added with ${newLiveHeaders.length} live headers from ${bulk.constructor.name}`);
|
|
19619
|
+
if (r.done) {
|
|
19620
|
+
done = true;
|
|
19621
|
+
break;
|
|
19622
|
+
}
|
|
19623
|
+
} catch (error_) {
|
|
19624
|
+
const e = bulkSyncError = WalletError.fromUnknown(error_);
|
|
19625
|
+
this.markSourceFailure(source, "bulk", e);
|
|
19626
|
+
this.log(`bulk sync error: ${e.message}`);
|
|
19551
19627
|
}
|
|
19552
|
-
} catch (error_) {
|
|
19553
|
-
const e = bulkSyncError = WalletError.fromUnknown(error_);
|
|
19554
|
-
this.log(`bulk sync error: ${e.message}`);
|
|
19555
|
-
if (!this.available) break;
|
|
19556
19628
|
}
|
|
19557
19629
|
if (!this.available && bulkSyncError != null && !hadSuccess) this.startupError = bulkSyncError;
|
|
19558
19630
|
return {
|
|
@@ -19562,10 +19634,41 @@ var Chaintracks = class {
|
|
|
19562
19634
|
madeProgress
|
|
19563
19635
|
};
|
|
19564
19636
|
}
|
|
19637
|
+
sourceName(role, index, source) {
|
|
19638
|
+
return `${role}[${index}]:${source.constructor.name}`;
|
|
19639
|
+
}
|
|
19640
|
+
markSourceSuccess(name, role) {
|
|
19641
|
+
this.sourceStatus.set(name, {
|
|
19642
|
+
...this.sourceStatus.get(name),
|
|
19643
|
+
name,
|
|
19644
|
+
role,
|
|
19645
|
+
state: "healthy",
|
|
19646
|
+
lastSuccess: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19647
|
+
error: void 0
|
|
19648
|
+
});
|
|
19649
|
+
}
|
|
19650
|
+
markSourceFailure(name, role, error) {
|
|
19651
|
+
this.sourceStatus.set(name, {
|
|
19652
|
+
...this.sourceStatus.get(name),
|
|
19653
|
+
name,
|
|
19654
|
+
role,
|
|
19655
|
+
state: "degraded",
|
|
19656
|
+
lastFailure: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19657
|
+
error: error.message
|
|
19658
|
+
});
|
|
19659
|
+
}
|
|
19565
19660
|
async getMissingBlockHeader(hash) {
|
|
19566
|
-
for (const live of this.liveIngestors) {
|
|
19567
|
-
const
|
|
19568
|
-
|
|
19661
|
+
for (const [index, live] of this.liveIngestors.entries()) {
|
|
19662
|
+
const source = this.sourceName("live", index, live);
|
|
19663
|
+
try {
|
|
19664
|
+
const header = await live.getHeaderByHash(hash);
|
|
19665
|
+
this.markSourceSuccess(source, "live");
|
|
19666
|
+
if (header != null) return header;
|
|
19667
|
+
} catch (error) {
|
|
19668
|
+
const resolved = WalletError.fromUnknown(error);
|
|
19669
|
+
this.markSourceFailure(source, "live", resolved);
|
|
19670
|
+
this.log(`Header lookup source ${source} failed: ${resolved.message}`);
|
|
19671
|
+
}
|
|
19569
19672
|
}
|
|
19570
19673
|
}
|
|
19571
19674
|
invalidInsertHeaderResult(ihr) {
|
|
@@ -19898,6 +20001,9 @@ var GoChaintracksServiceClient = class {
|
|
|
19898
20001
|
chain;
|
|
19899
20002
|
baseUrl;
|
|
19900
20003
|
fetcher;
|
|
20004
|
+
requestTimeoutMsecs;
|
|
20005
|
+
reconnectWaitMsecs;
|
|
20006
|
+
reconnectWaitMaxMsecs;
|
|
19901
20007
|
subscriptions = /* @__PURE__ */ new Map();
|
|
19902
20008
|
nextSubscriptionId = 1;
|
|
19903
20009
|
constructor(chain, serviceUrl, options = {}) {
|
|
@@ -19911,6 +20017,15 @@ var GoChaintracksServiceClient = class {
|
|
|
19911
20017
|
}
|
|
19912
20018
|
this.baseUrl = `${base}${prefix}`;
|
|
19913
20019
|
this.fetcher = options.fetch ?? fetch;
|
|
20020
|
+
this.requestTimeoutMsecs = options.requestTimeoutMsecs ?? 3e4;
|
|
20021
|
+
this.reconnectWaitMsecs = options.reconnectWaitMsecs ?? 1e3;
|
|
20022
|
+
this.reconnectWaitMaxMsecs = options.reconnectWaitMaxMsecs ?? 6e4;
|
|
20023
|
+
for (const [name, value] of [
|
|
20024
|
+
["requestTimeoutMsecs", this.requestTimeoutMsecs],
|
|
20025
|
+
["reconnectWaitMsecs", this.reconnectWaitMsecs],
|
|
20026
|
+
["reconnectWaitMaxMsecs", this.reconnectWaitMaxMsecs]
|
|
20027
|
+
]) if (!Number.isSafeInteger(value) || value < 1) throw new Error(`${name} must be a positive integer.`);
|
|
20028
|
+
if (this.reconnectWaitMaxMsecs < this.reconnectWaitMsecs) throw new Error("reconnectWaitMaxMsecs must be greater than or equal to reconnectWaitMsecs.");
|
|
19914
20029
|
}
|
|
19915
20030
|
async currentHeight() {
|
|
19916
20031
|
return await this.getPresentHeight();
|
|
@@ -19920,12 +20035,8 @@ var GoChaintracksServiceClient = class {
|
|
|
19920
20035
|
return h != null && root === asString(h.merkleRoot);
|
|
19921
20036
|
}
|
|
19922
20037
|
async getChain() {
|
|
19923
|
-
|
|
19924
|
-
|
|
19925
|
-
return this.normalizeChain(r.network);
|
|
19926
|
-
} catch {
|
|
19927
|
-
return this.chain;
|
|
19928
|
-
}
|
|
20038
|
+
const r = await this.getJson("/network");
|
|
20039
|
+
return this.normalizeChain(typeof r === "string" ? r : r.network);
|
|
19929
20040
|
}
|
|
19930
20041
|
async getInfo() {
|
|
19931
20042
|
const tip = await this.findChainTipHeader();
|
|
@@ -19940,11 +20051,11 @@ var GoChaintracksServiceClient = class {
|
|
|
19940
20051
|
};
|
|
19941
20052
|
}
|
|
19942
20053
|
async getPresentHeight() {
|
|
19943
|
-
|
|
20054
|
+
const result = await this.getJson("/height");
|
|
20055
|
+
return typeof result === "number" ? result : result.height;
|
|
19944
20056
|
}
|
|
19945
20057
|
async getHeaders(height, count) {
|
|
19946
|
-
|
|
19947
|
-
return Buffer.from(bytes).toString("hex");
|
|
20058
|
+
return asString(await this.getBinary(`/headers.bin?height=${height}&count=${count}`));
|
|
19948
20059
|
}
|
|
19949
20060
|
async findChainTipHeader() {
|
|
19950
20061
|
return await this.getJson("/tip");
|
|
@@ -20000,7 +20111,7 @@ var GoChaintracksServiceClient = class {
|
|
|
20000
20111
|
async subscribe(type, path, onPayload) {
|
|
20001
20112
|
const id = `${type}-${this.nextSubscriptionId++}`;
|
|
20002
20113
|
const abort = new AbortController();
|
|
20003
|
-
const done = this.
|
|
20114
|
+
const done = this.runSseWithReconnect(path, abort.signal, onPayload);
|
|
20004
20115
|
this.subscriptions.set(id, {
|
|
20005
20116
|
id,
|
|
20006
20117
|
type,
|
|
@@ -20012,30 +20123,75 @@ var GoChaintracksServiceClient = class {
|
|
|
20012
20123
|
});
|
|
20013
20124
|
return id;
|
|
20014
20125
|
}
|
|
20015
|
-
async
|
|
20016
|
-
|
|
20017
|
-
|
|
20018
|
-
|
|
20126
|
+
async runSseWithReconnect(path, signal, onPayload) {
|
|
20127
|
+
let failures = 0;
|
|
20128
|
+
while (!signal.aborted) {
|
|
20129
|
+
try {
|
|
20130
|
+
failures = await this.runSse(path, signal, onPayload) ? 0 : failures + 1;
|
|
20131
|
+
} catch {
|
|
20132
|
+
if (signal.aborted) return;
|
|
20133
|
+
failures++;
|
|
20134
|
+
}
|
|
20135
|
+
const multiplier = Math.min(2 ** Math.max(0, failures - 1), 64);
|
|
20136
|
+
const delay = Math.min(this.reconnectWaitMsecs * multiplier, this.reconnectWaitMaxMsecs);
|
|
20137
|
+
await this.waitForReconnect(delay, signal);
|
|
20138
|
+
}
|
|
20139
|
+
}
|
|
20140
|
+
async waitForReconnect(msecs, signal) {
|
|
20141
|
+
if (signal.aborted || msecs <= 0) return;
|
|
20142
|
+
await new Promise((resolve) => {
|
|
20143
|
+
let timeout;
|
|
20144
|
+
const onAbort = () => done();
|
|
20145
|
+
const done = () => {
|
|
20146
|
+
clearTimeout(timeout);
|
|
20147
|
+
signal.removeEventListener("abort", onAbort);
|
|
20148
|
+
resolve();
|
|
20149
|
+
};
|
|
20150
|
+
timeout = setTimeout(done, msecs);
|
|
20151
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
20019
20152
|
});
|
|
20020
|
-
|
|
20021
|
-
|
|
20022
|
-
const
|
|
20023
|
-
const
|
|
20024
|
-
|
|
20153
|
+
}
|
|
20154
|
+
async runSse(path, signal, onPayload) {
|
|
20155
|
+
const controller = new AbortController();
|
|
20156
|
+
const onAbort = () => controller.abort();
|
|
20157
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
20158
|
+
const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMsecs);
|
|
20159
|
+
let receivedEvent = false;
|
|
20160
|
+
const observePayload = (payload) => {
|
|
20161
|
+
receivedEvent = true;
|
|
20162
|
+
onPayload(payload);
|
|
20163
|
+
};
|
|
20025
20164
|
try {
|
|
20026
|
-
|
|
20027
|
-
|
|
20028
|
-
|
|
20029
|
-
|
|
20030
|
-
|
|
20165
|
+
const response = await this.fetcher(this.url(path), {
|
|
20166
|
+
headers: { Accept: "text/event-stream" },
|
|
20167
|
+
signal: controller.signal
|
|
20168
|
+
});
|
|
20169
|
+
clearTimeout(timeout);
|
|
20170
|
+
if (!response.ok) throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`);
|
|
20171
|
+
if (response.body == null) throw new Error(`GET ${this.url(path)} returned no response body`);
|
|
20172
|
+
const reader = response.body.getReader();
|
|
20173
|
+
const decoder = new TextDecoder();
|
|
20174
|
+
let buffer = "";
|
|
20175
|
+
try {
|
|
20176
|
+
for (;;) {
|
|
20177
|
+
const { done, value } = await reader.read();
|
|
20178
|
+
if (done) break;
|
|
20179
|
+
buffer += decoder.decode(value, { stream: true });
|
|
20180
|
+
buffer = this.processSseBuffer(buffer, observePayload);
|
|
20181
|
+
}
|
|
20182
|
+
buffer += decoder.decode();
|
|
20183
|
+
this.processSseBuffer(`${buffer}\n\n`, observePayload);
|
|
20184
|
+
} finally {
|
|
20185
|
+
reader.releaseLock();
|
|
20031
20186
|
}
|
|
20032
|
-
buffer += decoder.decode();
|
|
20033
|
-
this.processSseBuffer(`${buffer}\n\n`, onPayload);
|
|
20034
20187
|
} finally {
|
|
20035
|
-
|
|
20188
|
+
clearTimeout(timeout);
|
|
20189
|
+
signal.removeEventListener("abort", onAbort);
|
|
20036
20190
|
}
|
|
20191
|
+
return receivedEvent;
|
|
20037
20192
|
}
|
|
20038
20193
|
processSseBuffer(buffer, onPayload) {
|
|
20194
|
+
buffer = buffer.replaceAll("\r\n", "\n");
|
|
20039
20195
|
for (;;) {
|
|
20040
20196
|
const boundary = buffer.indexOf("\n\n");
|
|
20041
20197
|
if (boundary < 0) return buffer;
|
|
@@ -20054,32 +20210,51 @@ var GoChaintracksServiceClient = class {
|
|
|
20054
20210
|
return r;
|
|
20055
20211
|
}
|
|
20056
20212
|
async getJsonOrUndefined(path) {
|
|
20057
|
-
const response = await this.
|
|
20213
|
+
const response = await this.fetchWithTimeout(this.url(path), { headers: { Accept: "application/json" } });
|
|
20058
20214
|
if (response.status === 404) return void 0;
|
|
20059
20215
|
if (!response.ok) throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`);
|
|
20060
|
-
|
|
20216
|
+
const value = await response.json();
|
|
20217
|
+
if (value != null && typeof value === "object" && "status" in value) {
|
|
20218
|
+
const envelope = value;
|
|
20219
|
+
if (envelope.status === "success") return envelope.value;
|
|
20220
|
+
if (envelope.status === "error") throw new Error(envelope.description ?? `GET ${this.url(path)} failed`);
|
|
20221
|
+
}
|
|
20222
|
+
return value;
|
|
20061
20223
|
}
|
|
20062
20224
|
async getBinary(path) {
|
|
20063
|
-
const response = await this.
|
|
20225
|
+
const response = await this.fetchWithTimeout(this.url(path), { headers: { Accept: "application/octet-stream" } });
|
|
20064
20226
|
if (!response.ok) throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`);
|
|
20065
20227
|
return new Uint8Array(await response.arrayBuffer());
|
|
20066
20228
|
}
|
|
20229
|
+
async fetchWithTimeout(url, init) {
|
|
20230
|
+
const controller = new AbortController();
|
|
20231
|
+
const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMsecs);
|
|
20232
|
+
try {
|
|
20233
|
+
return await this.fetcher(url, {
|
|
20234
|
+
...init,
|
|
20235
|
+
signal: controller.signal
|
|
20236
|
+
});
|
|
20237
|
+
} finally {
|
|
20238
|
+
clearTimeout(timeout);
|
|
20239
|
+
}
|
|
20240
|
+
}
|
|
20067
20241
|
url(path) {
|
|
20068
20242
|
return `${this.baseUrl}${path}`;
|
|
20069
20243
|
}
|
|
20070
20244
|
normalizeChain(network) {
|
|
20071
|
-
switch (network) {
|
|
20245
|
+
switch (network.trim().toLowerCase()) {
|
|
20072
20246
|
case "main":
|
|
20073
20247
|
case "mainnet": return "main";
|
|
20074
20248
|
case "test":
|
|
20075
20249
|
case "testnet": return "test";
|
|
20250
|
+
case "stn":
|
|
20251
|
+
case "scalingtestnet": return "stn";
|
|
20076
20252
|
case "ttn":
|
|
20077
20253
|
case "teratest":
|
|
20078
20254
|
case "teratestnet": return "ttn";
|
|
20079
20255
|
case "tstn":
|
|
20080
|
-
case "teranodescalingtestnet":
|
|
20081
|
-
|
|
20082
|
-
default: return this.chain;
|
|
20256
|
+
case "teranodescalingtestnet": return "tstn";
|
|
20257
|
+
default: throw new Error(`Unsupported ChainTracks upstream network '${network}'.`);
|
|
20083
20258
|
}
|
|
20084
20259
|
}
|
|
20085
20260
|
};
|
|
@@ -20574,9 +20749,11 @@ var BulkFileDataManager = class BulkFileDataManager {
|
|
|
20574
20749
|
const nextHeight = lbf != null ? lbf.firstHeight + lbf.count : 0;
|
|
20575
20750
|
({headers: newBulkHeaders, incrementalChainWork} = trimAlreadyStoredHeaders(newBulkHeaders, nextHeight, incrementalChainWork));
|
|
20576
20751
|
if (newBulkHeaders.length === 0) return;
|
|
20577
|
-
if (
|
|
20578
|
-
if (!lbf.lastHash) throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`);
|
|
20579
|
-
const
|
|
20752
|
+
if (nextHeight !== newBulkHeaders[0].height) throw new WERR_INVALID_PARAMETER("newBulkHeaders", "an extension of existing bulk headers");
|
|
20753
|
+
if (lbf != null && !lbf.lastHash) throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`);
|
|
20754
|
+
const prevChainWork = lbf?.lastChainWork ?? "00".repeat(32);
|
|
20755
|
+
const prevHash = lbf?.lastHash ?? "00".repeat(32);
|
|
20756
|
+
const lastChainWork = incrementalChainWork ? addWork(incrementalChainWork, prevChainWork) : computeChainWorkFromHeaders(newBulkHeaders, lbf);
|
|
20580
20757
|
const data = serializeBaseBlockHeaders(newBulkHeaders);
|
|
20581
20758
|
const fileHash = asString(Hash.sha256(asArray(data)), "base64");
|
|
20582
20759
|
const bf = {
|
|
@@ -20586,9 +20763,9 @@ var BulkFileDataManager = class BulkFileDataManager {
|
|
|
20586
20763
|
fileName: "incremental",
|
|
20587
20764
|
firstHeight: newBulkHeaders[0].height,
|
|
20588
20765
|
count: newBulkHeaders.length,
|
|
20589
|
-
prevChainWork
|
|
20766
|
+
prevChainWork,
|
|
20590
20767
|
lastChainWork,
|
|
20591
|
-
prevHash
|
|
20768
|
+
prevHash,
|
|
20592
20769
|
lastHash: newBulkHeaders.at(-1).hash,
|
|
20593
20770
|
fileHash,
|
|
20594
20771
|
data
|
|
@@ -21018,12 +21195,13 @@ function trimAlreadyStoredHeaders(headers, nextHeight, incrementalChainWork) {
|
|
|
21018
21195
|
}
|
|
21019
21196
|
/**
|
|
21020
21197
|
* Computes `lastChainWork` for a sequence of new bulk headers extending `lbf`,
|
|
21021
|
-
*
|
|
21198
|
+
* or beginning at genesis when bulk storage is empty, validating that the
|
|
21199
|
+
* sequence is contiguous.
|
|
21022
21200
|
*/
|
|
21023
21201
|
function computeChainWorkFromHeaders(headers, lbf) {
|
|
21024
|
-
let lastHeight = lbf.firstHeight + lbf.count - 1;
|
|
21025
|
-
let lastHash = lbf.
|
|
21026
|
-
let lastChainWork = lbf.
|
|
21202
|
+
let lastHeight = lbf != null ? lbf.firstHeight + lbf.count - 1 : -1;
|
|
21203
|
+
let lastHash = lbf?.lastHash ?? "00".repeat(32);
|
|
21204
|
+
let lastChainWork = lbf?.lastChainWork ?? "00".repeat(32);
|
|
21027
21205
|
for (const h of headers) {
|
|
21028
21206
|
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`);
|
|
21029
21207
|
lastChainWork = addWork(lastChainWork, convertBitsToWork(h.bits));
|
|
@@ -21412,31 +21590,45 @@ var ServiceCollection = class ServiceCollection {
|
|
|
21412
21590
|
//#endregion
|
|
21413
21591
|
//#region ../src/services/networkConfig.ts
|
|
21414
21592
|
/**
|
|
21415
|
-
* Runtime service-endpoint configuration for
|
|
21593
|
+
* Runtime service-endpoint configuration for Teranode networks that do not
|
|
21594
|
+
* have a public, operator-independent service endpoint.
|
|
21416
21595
|
*
|
|
21417
|
-
* Unlike `main`, `test`, and `ttn`, the tstn service endpoints are not public and must not be
|
|
21596
|
+
* Unlike `main`, `test`, and `ttn`, the stn/tstn service endpoints are not public and must not be
|
|
21418
21597
|
* hardcoded in this (public) source tree. They are supplied at runtime through environment
|
|
21419
21598
|
* variables:
|
|
21420
21599
|
*
|
|
21600
|
+
* STN_ARCADE_URL STN Arcade broadcaster / ARC endpoint base.
|
|
21601
|
+
* STN_CHAINTRACKS_URL STN ChainTracks service URL.
|
|
21421
21602
|
* TSTN_ARCADE_URL Arcade broadcaster / ARC endpoint base. Also the fallback host for
|
|
21422
21603
|
* ChainTracks when TSTN_CHAINTRACKS_URL is unset
|
|
21423
21604
|
* (`${TSTN_ARCADE_URL}/chaintracks/v1`, mirroring the ttn layout).
|
|
21424
21605
|
* TSTN_CHAINTRACKS_URL ChainTracks service URL.
|
|
21425
21606
|
*
|
|
21426
|
-
* tstn
|
|
21427
|
-
* WhatsOnChain
|
|
21607
|
+
* stn/tstn run only operator-configured Arcade and ChainTracks services; there is no
|
|
21608
|
+
* documented WhatsOnChain service for them, so no WhatsOnChain endpoint is configured and
|
|
21428
21609
|
* the WhatsOnChain-only lookups (raw tx, utxo status, txid status, script-hash history) are not
|
|
21429
|
-
* available on tstn.
|
|
21610
|
+
* available on stn/tstn.
|
|
21430
21611
|
*
|
|
21431
|
-
* `process` is accessed defensively so importing this module remains safe in
|
|
21432
|
-
*
|
|
21433
|
-
*
|
|
21612
|
+
* `process` is accessed defensively so importing this module remains safe in
|
|
21613
|
+
* browser bundles. Browser applications can still supply an explicit
|
|
21614
|
+
* ChaintracksClientApi without relying on environment variables.
|
|
21434
21615
|
*/
|
|
21435
21616
|
function readEnv(name) {
|
|
21436
21617
|
const value = (typeof process !== "undefined" ? process.env : void 0)?.[name];
|
|
21437
21618
|
return value != null && value.trim() !== "" ? value.trim() : void 0;
|
|
21438
21619
|
}
|
|
21439
|
-
|
|
21620
|
+
/** Credential-free public Arcade host for supported networks. */
|
|
21621
|
+
function publicArcadeUrl(chain) {
|
|
21622
|
+
switch (chain) {
|
|
21623
|
+
case "main": return "https://arcade-v2-us-1.bsvblockchain.tech";
|
|
21624
|
+
case "test": return "https://arcade-v2-testnet-us-1.bsvblockchain.tech";
|
|
21625
|
+
case "ttn": return "https://arcade-v2-ttn-us-1.bsvblockchain.tech";
|
|
21626
|
+
case "stn":
|
|
21627
|
+
case "tstn":
|
|
21628
|
+
case "mock": return;
|
|
21629
|
+
}
|
|
21630
|
+
}
|
|
21631
|
+
const stripTrailingSlash$1 = (url) => {
|
|
21440
21632
|
let end = url.length;
|
|
21441
21633
|
while (end > 0 && url[end - 1] === "/") end--;
|
|
21442
21634
|
return url.slice(0, end);
|
|
@@ -21445,6 +21637,10 @@ const stripTrailingSlash = (url) => {
|
|
|
21445
21637
|
function tstnArcadeUrl() {
|
|
21446
21638
|
return readEnv("TSTN_ARCADE_URL");
|
|
21447
21639
|
}
|
|
21640
|
+
/** Arcade broadcaster / ARC endpoint for stn, or `undefined` when unset. */
|
|
21641
|
+
function stnArcadeUrl() {
|
|
21642
|
+
return readEnv("STN_ARCADE_URL");
|
|
21643
|
+
}
|
|
21448
21644
|
/**
|
|
21449
21645
|
* ChainTracks service URL for tstn. Falls back to `${TSTN_ARCADE_URL}/chaintracks/v1` when
|
|
21450
21646
|
* `TSTN_CHAINTRACKS_URL` is unset (mirrors the ttn layout). Throws when neither is configured.
|
|
@@ -21453,20 +21649,53 @@ function tstnChaintracksUrl() {
|
|
|
21453
21649
|
const explicit = readEnv("TSTN_CHAINTRACKS_URL");
|
|
21454
21650
|
if (explicit != null) return explicit;
|
|
21455
21651
|
const arcade = tstnArcadeUrl();
|
|
21456
|
-
if (arcade != null) return `${stripTrailingSlash(arcade)}/chaintracks/v1`;
|
|
21652
|
+
if (arcade != null) return `${stripTrailingSlash$1(arcade)}/chaintracks/v1`;
|
|
21457
21653
|
throw new Error("tstn chain requires a ChainTracks URL: set TSTN_CHAINTRACKS_URL (or TSTN_ARCADE_URL) in the environment.");
|
|
21458
21654
|
}
|
|
21655
|
+
/**
|
|
21656
|
+
* ChainTracks service URL for stn. Falls back to the configured Arcade host's
|
|
21657
|
+
* legacy-compatible path when STN_CHAINTRACKS_URL is unset.
|
|
21658
|
+
*/
|
|
21659
|
+
function stnChaintracksUrl() {
|
|
21660
|
+
const explicit = readEnv("STN_CHAINTRACKS_URL");
|
|
21661
|
+
if (explicit != null) return explicit;
|
|
21662
|
+
const arcade = stnArcadeUrl();
|
|
21663
|
+
if (arcade != null) return `${stripTrailingSlash$1(arcade)}/chaintracks/v1`;
|
|
21664
|
+
throw new Error("stn chain requires a ChainTracks URL: set STN_CHAINTRACKS_URL (or STN_ARCADE_URL) in the environment.");
|
|
21665
|
+
}
|
|
21459
21666
|
//#endregion
|
|
21460
21667
|
//#region ../src/services/createDefaultWalletServicesOptions.ts
|
|
21668
|
+
function stripTrailingSlash(value) {
|
|
21669
|
+
let end = value.length;
|
|
21670
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
21671
|
+
return value.slice(0, end);
|
|
21672
|
+
}
|
|
21673
|
+
function configuredChaintracksClient(chain, serviceUrl) {
|
|
21674
|
+
let path = "";
|
|
21675
|
+
try {
|
|
21676
|
+
path = stripTrailingSlash(new URL(serviceUrl).pathname);
|
|
21677
|
+
} catch {}
|
|
21678
|
+
if (path.endsWith("/v2")) return new GoChaintracksServiceClient(chain, serviceUrl);
|
|
21679
|
+
return new ChaintracksServiceClient(chain, serviceUrl);
|
|
21680
|
+
}
|
|
21681
|
+
/**
|
|
21682
|
+
* Returns the credential-free default ChainTracks client for a supported
|
|
21683
|
+
* public network, or an operator-configured client for stn/tstn.
|
|
21684
|
+
*/
|
|
21685
|
+
function createDefaultChaintracksClient(chain) {
|
|
21686
|
+
switch (chain) {
|
|
21687
|
+
case "main":
|
|
21688
|
+
case "test":
|
|
21689
|
+
case "ttn": return new GoChaintracksServiceClient(chain, arcadeDefaultUrl(chain), { apiPrefix: "/chaintracks/v2" });
|
|
21690
|
+
case "stn": return configuredChaintracksClient(chain, stnChaintracksUrl());
|
|
21691
|
+
case "tstn": return configuredChaintracksClient(chain, tstnChaintracksUrl());
|
|
21692
|
+
}
|
|
21693
|
+
}
|
|
21461
21694
|
function createDefaultWalletServicesOptions(...[chain, arcCallbackUrl, arcCallbackToken, taalArcApiKey, gorillaPoolArcApiKey, bitailsApiKey, deploymentId, chaintracks, arcadeUrl, arcadeApiKey, arcadeCallbackToken]) {
|
|
21462
21695
|
if (chain === "mock") throw new Error("createDefaultWalletServicesOptions does not support 'mock' chain. Use MockServices directly.");
|
|
21463
21696
|
deploymentId ||= `wallet-toolbox-${randomBytesHex(16)}`;
|
|
21464
|
-
let chaintracksUrl;
|
|
21465
|
-
if (chain === "ttn") chaintracksUrl = "https://arcade-v2-ttn-us-1.bsvblockchain.tech/chaintracks/v1";
|
|
21466
|
-
else if (chain === "tstn") chaintracksUrl = tstnChaintracksUrl();
|
|
21467
|
-
else chaintracksUrl = `https://${chain}net-chaintracks.babbage.systems`;
|
|
21468
21697
|
const chaintracksFiatExchangeRatesUrl = "https://mainnet-chaintracks.babbage.systems/getFiatExchangeRates";
|
|
21469
|
-
chaintracks ||=
|
|
21698
|
+
chaintracks ||= createDefaultChaintracksClient(chain);
|
|
21470
21699
|
const o = {
|
|
21471
21700
|
chain,
|
|
21472
21701
|
taalApiKey: void 0,
|
|
@@ -21524,14 +21753,15 @@ function createDefaultWalletServicesOptions(...[chain, arcCallbackUrl, arcCallba
|
|
|
21524
21753
|
}
|
|
21525
21754
|
/**
|
|
21526
21755
|
* Default Arcade (bsv-blockchain/arcade) endpoint per chain.
|
|
21527
|
-
* Returns undefined when no public default is known for the chain
|
|
21756
|
+
* Returns undefined when no public default is known for the chain.
|
|
21528
21757
|
*/
|
|
21529
21758
|
function arcadeDefaultUrl(chain) {
|
|
21530
21759
|
switch (chain) {
|
|
21531
|
-
case "main":
|
|
21532
|
-
case "
|
|
21760
|
+
case "main":
|
|
21761
|
+
case "test":
|
|
21762
|
+
case "ttn": return publicArcadeUrl(chain);
|
|
21763
|
+
case "stn": return stnArcadeUrl();
|
|
21533
21764
|
case "tstn": return tstnArcadeUrl();
|
|
21534
|
-
case "test": return;
|
|
21535
21765
|
case "mock": return;
|
|
21536
21766
|
}
|
|
21537
21767
|
}
|
|
@@ -21539,6 +21769,7 @@ function arcDefaultUrl(chain) {
|
|
|
21539
21769
|
switch (chain) {
|
|
21540
21770
|
case "main": return "https://arc.taal.com";
|
|
21541
21771
|
case "test": return "https://arc-test.taal.com";
|
|
21772
|
+
case "stn": return stnArcadeUrl() ?? "";
|
|
21542
21773
|
case "ttn": return "https://arcade-v2-ttn-us-1.bsvblockchain.tech/";
|
|
21543
21774
|
case "tstn": return tstnArcadeUrl() ?? "";
|
|
21544
21775
|
case "mock": return "";
|
|
@@ -22920,7 +23151,7 @@ var Services = class Services {
|
|
|
22920
23151
|
telemetry;
|
|
22921
23152
|
constructor(optionsOrChain) {
|
|
22922
23153
|
this.chain = typeof optionsOrChain === "string" ? optionsOrChain : optionsOrChain.chain;
|
|
22923
|
-
if (this.chain === "mock") throw new WERR_INVALID_PARAMETER("chain", "'main', 'test', 'ttn', or 'tstn'. Use MockServices for 'mock' chain.");
|
|
23154
|
+
if (this.chain === "mock") throw new WERR_INVALID_PARAMETER("chain", "'main', 'test', 'stn', 'ttn', or 'tstn'. Use MockServices for 'mock' chain.");
|
|
22924
23155
|
this.options = typeof optionsOrChain === "string" ? Services.createDefaultOptions(this.chain) : optionsOrChain;
|
|
22925
23156
|
this.telemetry = new Telemetry(this.options.telemetry);
|
|
22926
23157
|
this.whatsonchain = new WhatsOnChain(this.chain, { apiKey: this.options.whatsOnChainApiKey }, this);
|
|
@@ -22934,7 +23165,7 @@ var Services = class Services {
|
|
|
22934
23165
|
if (this.options.arcGorillaPoolUrl != null && this.options.arcGorillaPoolUrl !== "") this.arcGorillaPool = new ARC(this.options.arcGorillaPoolUrl, this.options.arcGorillaPoolConfig, "arcGorillaPool");
|
|
22935
23166
|
if (this.options.arcadeUrl != null && this.options.arcadeUrl !== "") this.arcade = new Arcade(this.options.arcadeUrl, this.options.arcadeConfig, "arcade");
|
|
22936
23167
|
const hasBitails = this.chain === "main" || this.chain === "test";
|
|
22937
|
-
const hasWhatsOnChain = this.chain
|
|
23168
|
+
const hasWhatsOnChain = this.chain === "main" || this.chain === "test";
|
|
22938
23169
|
if (hasBitails) this.bitails = new Bitails(this.chain, { apiKey: this.options.bitailsApiKey });
|
|
22939
23170
|
return {
|
|
22940
23171
|
hasBitails,
|
|
@@ -23648,9 +23879,22 @@ function classifyMerklePathResponse(status, statusText, retry) {
|
|
|
23648
23879
|
//#endregion
|
|
23649
23880
|
//#region ../src/services/providers/WhatsOnChain.ts
|
|
23650
23881
|
var WhatsOnChainNoServices = class extends SdkWhatsOnChain {
|
|
23882
|
+
requestGate;
|
|
23651
23883
|
constructor(chain = "main", config = {}) {
|
|
23652
23884
|
if (chain === "mock") throw new Error("WhatsOnChain does not support 'mock' chain. Use MockServices directly.");
|
|
23653
23885
|
super(chain, config);
|
|
23886
|
+
this.requestGate = config.requestGate;
|
|
23887
|
+
}
|
|
23888
|
+
async requestWithAnonymousAuthFallback(url, requestOptions) {
|
|
23889
|
+
await this.requestGate?.();
|
|
23890
|
+
const response = await this.httpClient.request(url, requestOptions);
|
|
23891
|
+
if (response.status !== 401 && response.status !== 403 || this.apiKey.trim() === "") return response;
|
|
23892
|
+
if (this.requestGate != null) await this.requestGate();
|
|
23893
|
+
else await wait(350);
|
|
23894
|
+
return await this.httpClient.request(url, {
|
|
23895
|
+
method: "GET",
|
|
23896
|
+
headers: { Accept: "application/json" }
|
|
23897
|
+
});
|
|
23654
23898
|
}
|
|
23655
23899
|
/**
|
|
23656
23900
|
* POST
|
|
@@ -24059,7 +24303,7 @@ var WhatsOnChainNoServices = class extends SdkWhatsOnChain {
|
|
|
24059
24303
|
};
|
|
24060
24304
|
const url = `${this.URL}/block/${hash}/header`;
|
|
24061
24305
|
for (let retry = 0; retry < 2; retry++) {
|
|
24062
|
-
const response = await this.
|
|
24306
|
+
const response = await this.requestWithAnonymousAuthFallback(url, requestOptions);
|
|
24063
24307
|
if (response.statusText === "Too Many Requests" && retry < 2) {
|
|
24064
24308
|
await wait(2e3);
|
|
24065
24309
|
continue;
|
|
@@ -24077,7 +24321,7 @@ var WhatsOnChainNoServices = class extends SdkWhatsOnChain {
|
|
|
24077
24321
|
};
|
|
24078
24322
|
const url = `${this.URL}/chain/info`;
|
|
24079
24323
|
for (let retry = 0; retry < 2; retry++) {
|
|
24080
|
-
const response = await this.
|
|
24324
|
+
const response = await this.requestWithAnonymousAuthFallback(url, requestOptions);
|
|
24081
24325
|
if (response.statusText === "Too Many Requests" && retry < 2) {
|
|
24082
24326
|
await wait(2e3);
|
|
24083
24327
|
continue;
|
|
@@ -24263,12 +24507,16 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24263
24507
|
timeout: 3e4,
|
|
24264
24508
|
userAgent: "BabbageWhatsOnChainServices",
|
|
24265
24509
|
enableCache: true,
|
|
24266
|
-
chainInfoMsecs: 5e3
|
|
24510
|
+
chainInfoMsecs: 5e3,
|
|
24511
|
+
minRequestIntervalMsecs: 350
|
|
24267
24512
|
};
|
|
24268
24513
|
}
|
|
24269
24514
|
static chainInfo = [];
|
|
24270
24515
|
static chainInfoTime = [];
|
|
24271
24516
|
static chainInfoMsecs = [];
|
|
24517
|
+
static chainInfoPromise = {};
|
|
24518
|
+
static requestTail = Promise.resolve();
|
|
24519
|
+
static nextRequestMsecs = 0;
|
|
24272
24520
|
chain;
|
|
24273
24521
|
woc;
|
|
24274
24522
|
constructor(options) {
|
|
@@ -24277,7 +24525,8 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24277
24525
|
apiKey: this.options.apiKey,
|
|
24278
24526
|
timeout: this.options.timeout,
|
|
24279
24527
|
userAgent: this.options.userAgent,
|
|
24280
|
-
enableCache: this.options.enableCache
|
|
24528
|
+
enableCache: this.options.enableCache,
|
|
24529
|
+
requestGate: async () => await this.waitForRateLimit()
|
|
24281
24530
|
};
|
|
24282
24531
|
this.chain = options.chain;
|
|
24283
24532
|
const chainInfoMsecs = WhatsOnChainServices.chainInfoMsecs;
|
|
@@ -24295,7 +24544,16 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24295
24544
|
let update = chainInfo[this.chain] === void 0;
|
|
24296
24545
|
if (!update && chainInfoTime[this.chain] !== void 0) update = now.getTime() - chainInfoTime[this.chain].getTime() > chainInfoMsecs[this.chain];
|
|
24297
24546
|
if (update) {
|
|
24298
|
-
|
|
24547
|
+
let pending = WhatsOnChainServices.chainInfoPromise[this.chain];
|
|
24548
|
+
if (pending == null) {
|
|
24549
|
+
pending = this.woc.getChainInfo();
|
|
24550
|
+
WhatsOnChainServices.chainInfoPromise[this.chain] = pending;
|
|
24551
|
+
}
|
|
24552
|
+
try {
|
|
24553
|
+
chainInfo[this.chain] = await pending;
|
|
24554
|
+
} finally {
|
|
24555
|
+
if (WhatsOnChainServices.chainInfoPromise[this.chain] === pending) delete WhatsOnChainServices.chainInfoPromise[this.chain];
|
|
24556
|
+
}
|
|
24299
24557
|
chainInfoTime[this.chain] = now;
|
|
24300
24558
|
}
|
|
24301
24559
|
if (!chainInfo[this.chain]) throw new Error("Unexpected failure to update chainInfo.");
|
|
@@ -24313,10 +24571,12 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24313
24571
|
*/
|
|
24314
24572
|
async getHeaders(fetch) {
|
|
24315
24573
|
fetch ||= new ChaintracksFetch();
|
|
24574
|
+
await this.waitForRateLimit();
|
|
24316
24575
|
return await fetch.fetchJson(`https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers`);
|
|
24317
24576
|
}
|
|
24318
24577
|
async getHeaderByteFileLinks(neededRange, fetch) {
|
|
24319
24578
|
fetch ||= new ChaintracksFetch();
|
|
24579
|
+
await this.waitForRateLimit();
|
|
24320
24580
|
const files = await fetch.fetchJson(`https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers/resources`);
|
|
24321
24581
|
const r = [];
|
|
24322
24582
|
let range;
|
|
@@ -24329,6 +24589,21 @@ var WhatsOnChainServices = class WhatsOnChainServices {
|
|
|
24329
24589
|
}
|
|
24330
24590
|
return r;
|
|
24331
24591
|
}
|
|
24592
|
+
async waitForRateLimit() {
|
|
24593
|
+
let release;
|
|
24594
|
+
const previous = WhatsOnChainServices.requestTail;
|
|
24595
|
+
WhatsOnChainServices.requestTail = new Promise((resolve) => {
|
|
24596
|
+
release = resolve;
|
|
24597
|
+
});
|
|
24598
|
+
await previous;
|
|
24599
|
+
try {
|
|
24600
|
+
const delay = Math.max(0, WhatsOnChainServices.nextRequestMsecs - Date.now());
|
|
24601
|
+
if (delay > 0) await wait(delay);
|
|
24602
|
+
WhatsOnChainServices.nextRequestMsecs = Date.now() + (this.options.minRequestIntervalMsecs ?? 350);
|
|
24603
|
+
} finally {
|
|
24604
|
+
release();
|
|
24605
|
+
}
|
|
24606
|
+
}
|
|
24332
24607
|
};
|
|
24333
24608
|
function wocGetHeadersHeaderToBlockHeader(h) {
|
|
24334
24609
|
const bits = typeof h.bits === "string" ? Number.parseInt(h.bits, 16) : h.bits;
|
|
@@ -24389,6 +24664,51 @@ var BulkIngestorWhatsOnChainCdn = class extends BulkIngestorBase {
|
|
|
24389
24664
|
}
|
|
24390
24665
|
};
|
|
24391
24666
|
//#endregion
|
|
24667
|
+
//#region ../src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.ts
|
|
24668
|
+
/**
|
|
24669
|
+
* Uses a go-chaintracks/Arcade-compatible service as a validated bulk source.
|
|
24670
|
+
* Retrieved bytes still pass through ChainTracks' local serialization, hash,
|
|
24671
|
+
* continuity, and genesis checks before storage.
|
|
24672
|
+
*/
|
|
24673
|
+
var BulkIngestorChaintracks = class extends BulkIngestorBase {
|
|
24674
|
+
chaintracks;
|
|
24675
|
+
maxHeadersPerRequest;
|
|
24676
|
+
networkChecked = false;
|
|
24677
|
+
constructor(options) {
|
|
24678
|
+
super(options);
|
|
24679
|
+
this.chaintracks = options.chaintracks;
|
|
24680
|
+
this.maxHeadersPerRequest = options.maxHeadersPerRequest ?? 1e3;
|
|
24681
|
+
if (!Number.isInteger(this.maxHeadersPerRequest) || this.maxHeadersPerRequest < 1) throw new Error("maxHeadersPerRequest must be a positive integer.");
|
|
24682
|
+
}
|
|
24683
|
+
async getPresentHeight() {
|
|
24684
|
+
await this.ensureNetwork();
|
|
24685
|
+
return await this.chaintracks.getPresentHeight();
|
|
24686
|
+
}
|
|
24687
|
+
async fetchHeaders(_before, fetchRange, bulkRange, priorLiveHeaders) {
|
|
24688
|
+
if (fetchRange.isEmpty) return priorLiveHeaders;
|
|
24689
|
+
await this.ensureNetwork();
|
|
24690
|
+
let liveHeaders = priorLiveHeaders;
|
|
24691
|
+
let height = fetchRange.minHeight;
|
|
24692
|
+
while (height <= fetchRange.maxHeight) {
|
|
24693
|
+
const requested = Math.min(this.maxHeadersPerRequest, fetchRange.maxHeight - height + 1);
|
|
24694
|
+
const bytes = asUint8Array(await this.chaintracks.getHeaders(height, requested));
|
|
24695
|
+
if (bytes.length === 0) throw new Error(`ChainTracks upstream returned no headers at height ${height}.`);
|
|
24696
|
+
if (bytes.length % 80 !== 0 || bytes.length > requested * 80) throw new Error(`ChainTracks upstream returned ${bytes.length} bytes for ${requested} headers at height ${height}.`);
|
|
24697
|
+
const headers = deserializeBlockHeaders(height, bytes);
|
|
24698
|
+
liveHeaders = await this.storage().addBulkHeaders(headers, bulkRange, liveHeaders);
|
|
24699
|
+
height += headers.length;
|
|
24700
|
+
if (headers.length < requested && height <= fetchRange.maxHeight) throw new Error(`ChainTracks upstream returned ${headers.length} of ${requested} headers at height ${height - headers.length}.`);
|
|
24701
|
+
}
|
|
24702
|
+
return liveHeaders;
|
|
24703
|
+
}
|
|
24704
|
+
async ensureNetwork() {
|
|
24705
|
+
if (this.networkChecked) return;
|
|
24706
|
+
const actual = await this.chaintracks.getChain();
|
|
24707
|
+
if (actual !== this.chain) throw new Error(`ChainTracks upstream network '${actual}' does not match configured chain '${this.chain}'.`);
|
|
24708
|
+
this.networkChecked = true;
|
|
24709
|
+
}
|
|
24710
|
+
};
|
|
24711
|
+
//#endregion
|
|
24392
24712
|
//#region ../src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.ts
|
|
24393
24713
|
/**
|
|
24394
24714
|
* Reports new headers by polling periodically.
|
|
@@ -24495,9 +24815,17 @@ var LiveIngestorChaintracksSSE = class extends LiveIngestorBase {
|
|
|
24495
24815
|
}
|
|
24496
24816
|
async startListening(liveHeaders) {
|
|
24497
24817
|
this.stopped = false;
|
|
24498
|
-
|
|
24818
|
+
const actual = await this.options.chaintracks.getChain();
|
|
24819
|
+
if (actual !== this.chain) throw new Error(`ChainTracks upstream network '${actual}' does not match configured chain '${this.chain}'.`);
|
|
24820
|
+
if (this.stopped) return;
|
|
24821
|
+
const subscriptionId = await this.options.chaintracks.subscribeHeaders((header) => {
|
|
24499
24822
|
if (!this.stopped) liveHeaders.push(header);
|
|
24500
24823
|
});
|
|
24824
|
+
if (this.stopped) {
|
|
24825
|
+
await this.options.chaintracks.unsubscribe(subscriptionId);
|
|
24826
|
+
return;
|
|
24827
|
+
}
|
|
24828
|
+
this.subscriptionId = subscriptionId;
|
|
24501
24829
|
await new Promise((resolve) => {
|
|
24502
24830
|
this.resolveStopped = resolve;
|
|
24503
24831
|
if (this.stopped) resolve();
|
|
@@ -24510,7 +24838,9 @@ var LiveIngestorChaintracksSSE = class extends LiveIngestorBase {
|
|
|
24510
24838
|
if (subscriptionId != null) this.options.chaintracks.unsubscribe(subscriptionId).catch((e) => {
|
|
24511
24839
|
this.log(`LiveIngestorChaintracksSSE unsubscribe failed: ${e}`);
|
|
24512
24840
|
});
|
|
24513
|
-
this.resolveStopped
|
|
24841
|
+
const resolveStopped = this.resolveStopped;
|
|
24842
|
+
this.resolveStopped = void 0;
|
|
24843
|
+
resolveStopped?.();
|
|
24514
24844
|
}
|
|
24515
24845
|
async shutdown() {
|
|
24516
24846
|
this.stopListening();
|
|
@@ -25206,6 +25536,27 @@ var ChaintracksStorageNoDb = class ChaintracksStorageNoDb extends ChaintracksSto
|
|
|
25206
25536
|
tipHeaderId: 0,
|
|
25207
25537
|
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25208
25538
|
};
|
|
25539
|
+
static stnData = {
|
|
25540
|
+
chain: "stn",
|
|
25541
|
+
liveHeaders: /* @__PURE__ */ new Map(),
|
|
25542
|
+
maxHeaderId: 0,
|
|
25543
|
+
tipHeaderId: 0,
|
|
25544
|
+
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25545
|
+
};
|
|
25546
|
+
static ttnData = {
|
|
25547
|
+
chain: "ttn",
|
|
25548
|
+
liveHeaders: /* @__PURE__ */ new Map(),
|
|
25549
|
+
maxHeaderId: 0,
|
|
25550
|
+
tipHeaderId: 0,
|
|
25551
|
+
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25552
|
+
};
|
|
25553
|
+
static tstnData = {
|
|
25554
|
+
chain: "tstn",
|
|
25555
|
+
liveHeaders: /* @__PURE__ */ new Map(),
|
|
25556
|
+
maxHeaderId: 0,
|
|
25557
|
+
tipHeaderId: 0,
|
|
25558
|
+
hashToHeaderId: /* @__PURE__ */ new Map()
|
|
25559
|
+
};
|
|
25209
25560
|
constructor(options) {
|
|
25210
25561
|
super(options);
|
|
25211
25562
|
}
|
|
@@ -25213,10 +25564,11 @@ var ChaintracksStorageNoDb = class ChaintracksStorageNoDb extends ChaintracksSto
|
|
|
25213
25564
|
async getData() {
|
|
25214
25565
|
switch (this.chain) {
|
|
25215
25566
|
case "main": return ChaintracksStorageNoDb.mainData;
|
|
25216
|
-
case "test":
|
|
25217
|
-
case "
|
|
25218
|
-
case "
|
|
25219
|
-
|
|
25567
|
+
case "test": return ChaintracksStorageNoDb.testData;
|
|
25568
|
+
case "stn": return ChaintracksStorageNoDb.stnData;
|
|
25569
|
+
case "ttn": return ChaintracksStorageNoDb.ttnData;
|
|
25570
|
+
case "tstn": return ChaintracksStorageNoDb.tstnData;
|
|
25571
|
+
default: throw new WERR_INVALID_PARAMETER("chain", `'main', 'test', 'stn', 'ttn', or 'tstn'. '${this.chain}' is unsupported.`);
|
|
25220
25572
|
}
|
|
25221
25573
|
}
|
|
25222
25574
|
async deleteLiveBlockHeaders() {
|
|
@@ -25805,7 +26157,7 @@ var ChaintracksStorageIdb = class extends ChaintracksStorageBase {
|
|
|
25805
26157
|
//#endregion
|
|
25806
26158
|
//#region ../src/services/chaintracker/chaintracks/configureChaintracksIngestors.ts
|
|
25807
26159
|
function resolveDefaultChaintracksArguments(args) {
|
|
25808
|
-
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;
|
|
26160
|
+
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;
|
|
25809
26161
|
return {
|
|
25810
26162
|
chain,
|
|
25811
26163
|
whatsonchainApiKey,
|
|
@@ -25817,11 +26169,12 @@ function resolveDefaultChaintracksArguments(args) {
|
|
|
25817
26169
|
reorgHeightThreshold,
|
|
25818
26170
|
bulkMigrationChunkSize,
|
|
25819
26171
|
batchInsertLimit,
|
|
25820
|
-
addLiveRecursionLimit
|
|
26172
|
+
addLiveRecursionLimit,
|
|
26173
|
+
sources
|
|
25821
26174
|
};
|
|
25822
26175
|
}
|
|
25823
26176
|
function toDefaultChaintracksArguments(params) {
|
|
25824
|
-
|
|
26177
|
+
const args = [
|
|
25825
26178
|
params.chain,
|
|
25826
26179
|
params.whatsonchainApiKey,
|
|
25827
26180
|
params.maxPerFile,
|
|
@@ -25834,6 +26187,8 @@ function toDefaultChaintracksArguments(params) {
|
|
|
25834
26187
|
params.batchInsertLimit,
|
|
25835
26188
|
params.addLiveRecursionLimit
|
|
25836
26189
|
];
|
|
26190
|
+
if (Object.keys(params.sources).length > 0) args.push(params.sources);
|
|
26191
|
+
return args;
|
|
25837
26192
|
}
|
|
25838
26193
|
function createDefaultBulkFileDataManager(params) {
|
|
25839
26194
|
return new BulkFileDataManager({
|
|
@@ -25876,7 +26231,7 @@ function createAndStartDefaultChaintracks(args, createOptions) {
|
|
|
25876
26231
|
* The caller is responsible for providing the storage implementation.
|
|
25877
26232
|
*/
|
|
25878
26233
|
function buildChaintracksOptionsWithIngestors(params, storage) {
|
|
25879
|
-
const { chain, whatsonchainApiKey, maxPerFile, fetch, cdnUrl, addLiveRecursionLimit } = params;
|
|
26234
|
+
const { chain, whatsonchainApiKey, maxPerFile, fetch, cdnUrl, addLiveRecursionLimit, sources } = params;
|
|
25880
26235
|
const co = {
|
|
25881
26236
|
chain,
|
|
25882
26237
|
storage,
|
|
@@ -25887,35 +26242,58 @@ function buildChaintracksOptionsWithIngestors(params, storage) {
|
|
|
25887
26242
|
readonly: false
|
|
25888
26243
|
};
|
|
25889
26244
|
const jsonResource = `${chain}NetBlockHeaders.json`;
|
|
25890
|
-
|
|
25891
|
-
|
|
25892
|
-
|
|
25893
|
-
|
|
25894
|
-
|
|
25895
|
-
|
|
25896
|
-
|
|
25897
|
-
|
|
25898
|
-
|
|
25899
|
-
|
|
25900
|
-
|
|
25901
|
-
|
|
25902
|
-
|
|
25903
|
-
|
|
25904
|
-
|
|
25905
|
-
|
|
25906
|
-
|
|
25907
|
-
|
|
25908
|
-
|
|
25909
|
-
|
|
25910
|
-
|
|
25911
|
-
|
|
25912
|
-
|
|
25913
|
-
|
|
25914
|
-
|
|
25915
|
-
|
|
25916
|
-
|
|
26245
|
+
if (!sources.disableCdn && cdnUrl !== "") {
|
|
26246
|
+
const bulkCdnOptions = {
|
|
26247
|
+
chain,
|
|
26248
|
+
jsonResource,
|
|
26249
|
+
fetch,
|
|
26250
|
+
cdnUrl,
|
|
26251
|
+
maxPerFile
|
|
26252
|
+
};
|
|
26253
|
+
co.bulkIngestors.push(new BulkIngestorCDNBabbage(bulkCdnOptions));
|
|
26254
|
+
}
|
|
26255
|
+
const chaintracksSource = sources.chaintracks ?? (sources.disableChaintracks ? void 0 : createPublicChaintracksSource(chain));
|
|
26256
|
+
if (chaintracksSource != null) {
|
|
26257
|
+
co.bulkIngestors.push(new BulkIngestorChaintracks({
|
|
26258
|
+
chain,
|
|
26259
|
+
jsonResource,
|
|
26260
|
+
chaintracks: chaintracksSource,
|
|
26261
|
+
maxHeadersPerRequest: sources.remoteMaxHeadersPerRequest
|
|
26262
|
+
}));
|
|
26263
|
+
co.liveIngestors.push(new LiveIngestorChaintracksSSE({
|
|
26264
|
+
chain,
|
|
26265
|
+
chaintracks: chaintracksSource
|
|
26266
|
+
}));
|
|
26267
|
+
}
|
|
26268
|
+
if ((chain === "main" || chain === "test") && !sources.disableWhatsOnChain) {
|
|
26269
|
+
const wocOptions = {
|
|
26270
|
+
chain,
|
|
26271
|
+
apiKey: whatsonchainApiKey,
|
|
26272
|
+
timeout: 3e4,
|
|
26273
|
+
userAgent: "BabbageWhatsOnChainServices",
|
|
26274
|
+
enableCache: true,
|
|
26275
|
+
chainInfoMsecs: 5e3
|
|
26276
|
+
};
|
|
26277
|
+
const bulkOptions = {
|
|
26278
|
+
...wocOptions,
|
|
26279
|
+
jsonResource,
|
|
26280
|
+
idleWait: 5e3
|
|
26281
|
+
};
|
|
26282
|
+
co.bulkIngestors.push(new BulkIngestorWhatsOnChainCdn(bulkOptions));
|
|
26283
|
+
const liveOptions = {
|
|
26284
|
+
...wocOptions,
|
|
26285
|
+
idleWait: 1e5
|
|
26286
|
+
};
|
|
26287
|
+
co.liveIngestors.push(new LiveIngestorWhatsOnChainPoll(liveOptions));
|
|
26288
|
+
}
|
|
26289
|
+
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.`);
|
|
25917
26290
|
return co;
|
|
25918
26291
|
}
|
|
26292
|
+
function createPublicChaintracksSource(chain) {
|
|
26293
|
+
const serviceUrl = publicArcadeUrl(chain);
|
|
26294
|
+
if (serviceUrl == null) return void 0;
|
|
26295
|
+
return new GoChaintracksServiceClient(chain, serviceUrl, { apiPrefix: "/chaintracks/v2" });
|
|
26296
|
+
}
|
|
25919
26297
|
//#endregion
|
|
25920
26298
|
//#region ../src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.ts
|
|
25921
26299
|
function createDefaultNoDbChaintracksOptions(...args) {
|
|
@@ -34494,6 +34872,6 @@ var WalletPermissionsManager = class WalletPermissionsManager {
|
|
|
34494
34872
|
}
|
|
34495
34873
|
};
|
|
34496
34874
|
//#endregion
|
|
34497
|
-
export { ARGON2ID_DEFAULT_HASH_LENGTH, ARGON2ID_DEFAULT_ITERATIONS, ARGON2ID_DEFAULT_MEMORY_KIB, ARGON2ID_DEFAULT_PARALLELISM, ARGON2ID_MAX_ITERATIONS, ARGON2ID_MAX_MEMORY_KIB, ARGON2ID_MAX_PARALLELISM, AuthMethodInteractor, BHServiceClient, BulkFileDataManager, BulkFileDataReader, BulkFilesReader, BulkFilesReaderFs, BulkFilesReaderStorage, BulkIngestorBase, BulkIngestorCDN, BulkIngestorCDNBabbage, BulkIngestorWhatsOnChainCdn, BulkStorageBase, CWIStyleWalletManager, Chaintracks, ChaintracksChainTracker, ChaintracksFetch, ChaintracksFetchError, ChaintracksServiceClient, ChaintracksStorageBase, ChaintracksStorageIdb, ChaintracksStorageNoDb, DEFAULT_PROFILE_ID, DEFAULT_SETTINGS, DevConsoleInteractor, EntityBase, EntityCertificate, EntityCertificateField, EntityCommission, EntityOutput, EntityOutputBasket, EntityOutputTag, EntityOutputTagMap, EntityProvenTx, EntityProvenTxReq, EntitySyncState, EntityTransaction, EntityTxLabel, EntityTxLabelMap, EntityUser, GoChaintracksServiceClient, HeightRange, KDF_MAX_HASH_LENGTH, LiveIngestorBase, LiveIngestorChaintracksSSE, LiveIngestorWhatsOnChainPoll, MAX_STATE_SNAPSHOT_BYTES, MergeEntity, Monitor, OverlayUMPTokenInteractor, PBKDF2_MAX_ITERATIONS, PBKDF2_NUM_ROUNDS, PersonaIDInteractor, PrivilegedKeyManager, ScriptTemplateBRC29, Services, SetupClient, SimpleWalletManager, StorageClient, StorageIdb, StorageProvider, StorageSyncReader, TESTNET_DEFAULT_SETTINGS, TwilioPhoneInteractor, UMPTokenLookupError, WABAccountContinuityError, WABClient, WABClientError, WABTransport, Wallet, WalletAuthenticationManager, WalletLogger, WalletPermissionsManager, WalletSettingsManager, WalletSigner, WalletStorageManager, WhatsOnChainServices, arcDefaultUrl, arcGorillaPoolUrl, arcadeDefaultUrl, arraysEqual, asArray, asBsvSdkPrivateKey, asBsvSdkPublickKey, asBsvSdkScript, asBsvSdkTx, asString, asUint8Array, brc29ProtocolID, convertProofToMerklePath, createDefaultIdbChaintracksOptions, createDefaultNoDbChaintracksOptions, createDefaultWalletServicesOptions, createIdbChaintracks, createNoDbChaintracks, createSyncMap, decryptBRC39, doubleSha256BE, doubleSha256LE, encryptBRC39, exportBRC38, exportBRC38Json, exportBRC39, getIdentityKey, getLabelToSpecOp, getListOutputsSpecOp, importBRC38, importBRC39, isAutoSpendableChangeOutput, isBaseBlockHeader, isBlockHeader, isLive, isLiveBlockHeader, isManagedChangeOutput, logCreateActionArgs, logWalletError, logger, makeAtomicBeef, makeBrc114ActionTimeLabel, managedChangeOutputFields, maxDate, optionalArraysEqual, outputColumnsWithoutLockingScript, parseBRC38Json, parseBrc114ActionTimeLabels, parseFileLink, parseTxScriptOffsets, partitionActionLabels, randomBytes, randomBytesBase64, randomBytesHex, sdk_exports as sdk, selectBulkHeaderFiles, sha256Hash, stampLog, stampLogFormat, tableAuthSessionToPeerSession, throwDummyReviewActions, toBinaryBaseBlockHeader, toLookupNetworkPreset, toWalletNetwork, transactionColumnsWithoutRawTx, blockHeaderUtilities_exports as utils, validateScriptHash, validateSecondsSinceEpoch, validateStorageFeeModel, verifyHexString, verifyId, verifyInteger, verifyNumber, verifyOne, verifyOneOrNone, verifyOptionalHexString, verifyTruthy, wait, wocGetHeadersHeaderToBlockHeader };
|
|
34875
|
+
export { ARGON2ID_DEFAULT_HASH_LENGTH, ARGON2ID_DEFAULT_ITERATIONS, ARGON2ID_DEFAULT_MEMORY_KIB, ARGON2ID_DEFAULT_PARALLELISM, ARGON2ID_MAX_ITERATIONS, ARGON2ID_MAX_MEMORY_KIB, ARGON2ID_MAX_PARALLELISM, AuthMethodInteractor, BHServiceClient, BulkFileDataManager, BulkFileDataReader, BulkFilesReader, BulkFilesReaderFs, BulkFilesReaderStorage, BulkIngestorBase, BulkIngestorCDN, BulkIngestorCDNBabbage, BulkIngestorChaintracks, BulkIngestorWhatsOnChainCdn, BulkStorageBase, CWIStyleWalletManager, Chaintracks, ChaintracksChainTracker, ChaintracksFetch, ChaintracksFetchError, ChaintracksServiceClient, ChaintracksStorageBase, ChaintracksStorageIdb, ChaintracksStorageNoDb, DEFAULT_PROFILE_ID, DEFAULT_SETTINGS, DevConsoleInteractor, EntityBase, EntityCertificate, EntityCertificateField, EntityCommission, EntityOutput, EntityOutputBasket, EntityOutputTag, EntityOutputTagMap, EntityProvenTx, EntityProvenTxReq, EntitySyncState, EntityTransaction, EntityTxLabel, EntityTxLabelMap, EntityUser, GoChaintracksServiceClient, HeightRange, KDF_MAX_HASH_LENGTH, LiveIngestorBase, LiveIngestorChaintracksSSE, LiveIngestorWhatsOnChainPoll, MAX_STATE_SNAPSHOT_BYTES, MergeEntity, Monitor, OverlayUMPTokenInteractor, PBKDF2_MAX_ITERATIONS, PBKDF2_NUM_ROUNDS, PersonaIDInteractor, PrivilegedKeyManager, ScriptTemplateBRC29, Services, SetupClient, SimpleWalletManager, StorageClient, StorageIdb, StorageProvider, StorageSyncReader, TESTNET_DEFAULT_SETTINGS, TwilioPhoneInteractor, UMPTokenLookupError, WABAccountContinuityError, WABClient, WABClientError, WABTransport, Wallet, WalletAuthenticationManager, WalletLogger, WalletPermissionsManager, WalletSettingsManager, WalletSigner, WalletStorageManager, WhatsOnChainServices, arcDefaultUrl, arcGorillaPoolUrl, arcadeDefaultUrl, arraysEqual, asArray, asBsvSdkPrivateKey, asBsvSdkPublickKey, asBsvSdkScript, asBsvSdkTx, asString, asUint8Array, brc29ProtocolID, buildChaintracksOptionsWithIngestors, convertProofToMerklePath, createAndStartDefaultChaintracks, createDefaultBulkFileDataManager, createDefaultChaintracksClient, createDefaultChaintracksStorageOptions, createDefaultIdbChaintracksOptions, createDefaultNoDbChaintracksOptions, createDefaultWalletServicesOptions, createIdbChaintracks, createNoDbChaintracks, createSyncMap, decryptBRC39, doubleSha256BE, doubleSha256LE, encryptBRC39, exportBRC38, exportBRC38Json, exportBRC39, getIdentityKey, getLabelToSpecOp, getListOutputsSpecOp, importBRC38, importBRC39, isAutoSpendableChangeOutput, isBaseBlockHeader, isBlockHeader, isLive, isLiveBlockHeader, isManagedChangeOutput, logCreateActionArgs, logWalletError, logger, makeAtomicBeef, makeBrc114ActionTimeLabel, managedChangeOutputFields, maxDate, optionalArraysEqual, outputColumnsWithoutLockingScript, parseBRC38Json, parseBrc114ActionTimeLabels, parseFileLink, parseTxScriptOffsets, partitionActionLabels, randomBytes, randomBytesBase64, randomBytesHex, resolveDefaultChaintracksArguments, sdk_exports as sdk, selectBulkHeaderFiles, sha256Hash, stampLog, stampLogFormat, startChaintracks, tableAuthSessionToPeerSession, throwDummyReviewActions, toBinaryBaseBlockHeader, toDefaultChaintracksArguments, toLookupNetworkPreset, toWalletNetwork, transactionColumnsWithoutRawTx, blockHeaderUtilities_exports as utils, validateScriptHash, validateSecondsSinceEpoch, validateStorageFeeModel, verifyHexString, verifyId, verifyInteger, verifyNumber, verifyOne, verifyOneOrNone, verifyOptionalHexString, verifyTruthy, wait, wocGetHeadersHeaderToBlockHeader };
|
|
34498
34876
|
|
|
34499
34877
|
//# sourceMappingURL=index.client.mjs.map
|