@toon-protocol/rig 3.5.2 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-4CAOEXGQ.js → chunk-IZ6KLYQ6.js} +122 -29
- package/dist/chunk-IZ6KLYQ6.js.map +1 -0
- package/dist/{chunk-FFQXFV4W.js → chunk-PWNZWQOH.js} +7 -3
- package/dist/chunk-PWNZWQOH.js.map +1 -0
- package/dist/{chunk-TTJCBGKW.js → chunk-UZZ2RN7A.js} +23 -1
- package/dist/chunk-UZZ2RN7A.js.map +1 -0
- package/dist/cli/rig.js +80 -38
- package/dist/cli/rig.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/{network-bootstrap-CTYIZMP6.js → network-bootstrap-27FYE3N7.js} +2 -2
- package/dist/standalone/index.d.ts +60 -0
- package/dist/standalone/index.js +1 -1
- package/dist/{standalone-mode-LBWGU7NV.js → standalone-mode-5MNNJC2D.js} +251 -47
- package/dist/standalone-mode-5MNNJC2D.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-4CAOEXGQ.js.map +0 -1
- package/dist/chunk-FFQXFV4W.js.map +0 -1
- package/dist/chunk-TTJCBGKW.js.map +0 -1
- package/dist/standalone-mode-LBWGU7NV.js.map +0 -1
- /package/dist/{network-bootstrap-CTYIZMP6.js.map → network-bootstrap-27FYE3N7.js.map} +0 -0
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
resolveIdentity,
|
|
8
8
|
topologyCacheKey,
|
|
9
9
|
topologyCacheTtlMs
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PWNZWQOH.js";
|
|
11
11
|
import {
|
|
12
12
|
StandalonePublisher,
|
|
13
13
|
deriveRouteDestinations
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-IZ6KLYQ6.js";
|
|
15
15
|
import {
|
|
16
16
|
ChannelMapStore,
|
|
17
17
|
RIG_CHANNEL_MAP_FILENAME,
|
|
@@ -32,13 +32,13 @@ import {
|
|
|
32
32
|
resolveChainSettlement,
|
|
33
33
|
selectSettlementChain,
|
|
34
34
|
solanaTokenBalance
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-UZZ2RN7A.js";
|
|
36
36
|
import {
|
|
37
37
|
fetchRemoteState
|
|
38
38
|
} from "./chunk-2KJJ7LSO.js";
|
|
39
39
|
|
|
40
40
|
// src/cli/standalone-mode.ts
|
|
41
|
-
import { readFileSync } from "fs";
|
|
41
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
42
42
|
import { homedir } from "os";
|
|
43
43
|
import { join } from "path";
|
|
44
44
|
import {
|
|
@@ -51,8 +51,101 @@ import {
|
|
|
51
51
|
encodeEventToToon,
|
|
52
52
|
resolveClientNetwork
|
|
53
53
|
} from "@toon-protocol/core";
|
|
54
|
-
|
|
54
|
+
|
|
55
|
+
// src/standalone/notice.ts
|
|
56
|
+
import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
57
|
+
import { dirname } from "path";
|
|
58
|
+
var NOTICE_STORE_FILENAME = "rig-seen-notices.json";
|
|
59
|
+
function normalizeNotice(value) {
|
|
60
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
61
|
+
const { id, severity, summary, url } = value;
|
|
62
|
+
if (typeof id !== "string" || id.length === 0) return void 0;
|
|
63
|
+
if (typeof summary !== "string" || summary.length === 0) return void 0;
|
|
64
|
+
if (typeof url !== "string" || url.length === 0) return void 0;
|
|
65
|
+
return {
|
|
66
|
+
id,
|
|
67
|
+
summary,
|
|
68
|
+
url,
|
|
69
|
+
severity: severity === "action-required" ? "action-required" : "info"
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function trustedNoticeFrom(peer, seedPubkeys) {
|
|
73
|
+
if (!peer || !seedPubkeys.includes(peer.pubkey)) return void 0;
|
|
74
|
+
return normalizeNotice(peer.info.notice);
|
|
75
|
+
}
|
|
76
|
+
var ACTION_REQUIRED_BORDER = "=".repeat(70);
|
|
77
|
+
function formatNoticeLines(notice) {
|
|
78
|
+
if (notice.severity === "action-required") {
|
|
79
|
+
return [
|
|
80
|
+
"",
|
|
81
|
+
ACTION_REQUIRED_BORDER,
|
|
82
|
+
`rig: ACTION REQUIRED \u2014 ${notice.summary}`,
|
|
83
|
+
`rig: ${notice.url}`,
|
|
84
|
+
ACTION_REQUIRED_BORDER,
|
|
85
|
+
""
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
return [`rig: notice \u2014 ${notice.summary} (${notice.url})`];
|
|
89
|
+
}
|
|
90
|
+
var NoticeStore = class {
|
|
91
|
+
path;
|
|
92
|
+
constructor(options) {
|
|
93
|
+
this.path = options.path;
|
|
94
|
+
}
|
|
95
|
+
hasSeen(id) {
|
|
96
|
+
return this.readFile().seenIds.includes(id);
|
|
97
|
+
}
|
|
98
|
+
/** Best-effort; a failed write just means the notice reprints next run. */
|
|
99
|
+
markSeen(id) {
|
|
100
|
+
const file = this.readFile();
|
|
101
|
+
if (file.seenIds.includes(id)) return;
|
|
102
|
+
try {
|
|
103
|
+
mkdirSync(dirname(this.path), { recursive: true });
|
|
104
|
+
writeFileSync(
|
|
105
|
+
this.path,
|
|
106
|
+
JSON.stringify(
|
|
107
|
+
{
|
|
108
|
+
version: 1,
|
|
109
|
+
seenIds: [...file.seenIds, id]
|
|
110
|
+
},
|
|
111
|
+
null,
|
|
112
|
+
2
|
|
113
|
+
),
|
|
114
|
+
{ mode: 384 }
|
|
115
|
+
);
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
readFile() {
|
|
120
|
+
const empty = { version: 1, seenIds: [] };
|
|
121
|
+
let raw;
|
|
122
|
+
try {
|
|
123
|
+
raw = readFileSync(this.path, "utf8");
|
|
124
|
+
} catch {
|
|
125
|
+
return empty;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(raw);
|
|
129
|
+
if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || !Array.isArray(parsed.seenIds) || !parsed.seenIds.every((x) => typeof x === "string")) {
|
|
130
|
+
return empty;
|
|
131
|
+
}
|
|
132
|
+
return parsed;
|
|
133
|
+
} catch {
|
|
134
|
+
return empty;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
function showOperatorNoticeOnce(peer, seedPubkeys, store, warn) {
|
|
139
|
+
const notice = trustedNoticeFrom(peer, seedPubkeys);
|
|
140
|
+
if (!notice || store.hasSeen(notice.id)) return;
|
|
141
|
+
for (const line of formatNoticeLines(notice)) warn(line);
|
|
142
|
+
store.markSeen(notice.id);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/cli/standalone-mode.ts
|
|
146
|
+
var OFFICIAL_PROXY_URL = "https://proxy.relay.devnet.toonprotocol.dev/ilp";
|
|
55
147
|
var OFFICIAL_PUBLISH_DESTINATION = "g.toon.relay";
|
|
148
|
+
var OFFICIAL_BTP_URL = "wss://proxy.relay.devnet.toonprotocol.dev/ilp/btp";
|
|
56
149
|
var MissingUplinkError = class extends Error {
|
|
57
150
|
constructor(configPath, relayUrl) {
|
|
58
151
|
const discovered = relayUrl ? `no announce with a btp/http endpoint was found on ${relayUrl} and the genesis seed has none; ` : "";
|
|
@@ -67,7 +160,7 @@ function configDir(env) {
|
|
|
67
160
|
}
|
|
68
161
|
function readClientConfig(path) {
|
|
69
162
|
try {
|
|
70
|
-
return JSON.parse(
|
|
163
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
71
164
|
} catch (err) {
|
|
72
165
|
if (err.code === "ENOENT") return {};
|
|
73
166
|
throw new Error(
|
|
@@ -181,18 +274,38 @@ async function resolveNetworkTopology(inputs) {
|
|
|
181
274
|
...file.tokenNetworks ? { tokenNetworks: file.tokenNetworks } : {}
|
|
182
275
|
};
|
|
183
276
|
let proxyUrl = explicitProxyUrl;
|
|
184
|
-
|
|
277
|
+
let btpUrl = explicitBtpUrl;
|
|
185
278
|
if (!proxyUrl && !btpUrl) {
|
|
186
279
|
proxyUrl = OFFICIAL_PROXY_URL;
|
|
187
280
|
}
|
|
281
|
+
let btpUrlDerived = false;
|
|
282
|
+
if (!explicitProxyUrl && !explicitBtpUrl) {
|
|
283
|
+
btpUrl = announce?.info.btpEndpoint || OFFICIAL_BTP_URL;
|
|
284
|
+
btpUrlDerived = true;
|
|
285
|
+
}
|
|
188
286
|
const destination = explicitDestination ?? announce?.info.ilpAddress ?? genesisSeed?.ilpAddress ?? "g.proxy";
|
|
189
287
|
const publishDestination = explicitPublish ?? announce?.routes?.publish ?? (proxyUrl === OFFICIAL_PROXY_URL ? OFFICIAL_PUBLISH_DESTINATION : void 0);
|
|
190
288
|
const storeDestination = explicitStore ?? announce?.routes?.store;
|
|
289
|
+
const explicitStoreBtpUrl = env["TOON_CLIENT_STORE_BTP_URL"] ?? file.storeBtpUrl;
|
|
290
|
+
let storeBtpUrl;
|
|
291
|
+
if (storeDestination && storeDestination !== publishDestination) {
|
|
292
|
+
const storePeer = inputs.peers?.find(
|
|
293
|
+
(peer) => peer.info.ilpAddress === storeDestination
|
|
294
|
+
);
|
|
295
|
+
storeBtpUrl = explicitStoreBtpUrl || storePeer?.info.btpEndpoint || void 0;
|
|
296
|
+
if (!storeBtpUrl && inputs.peers?.length) {
|
|
297
|
+
warn(
|
|
298
|
+
`rig: no announce found for the store route "${storeDestination}" \u2014 store writes (git objects, the rig page) will be attempted on the publish uplink and the terminating connector will refuse them if it does not hold that channel`
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
191
302
|
let routePrices;
|
|
192
|
-
|
|
193
|
-
if (capabilities && capabilities.length > 0) {
|
|
303
|
+
{
|
|
194
304
|
const derived = deriveRouteDestinations(destination);
|
|
195
|
-
const priceOf = (address) =>
|
|
305
|
+
const priceOf = (address) => {
|
|
306
|
+
const owner = inputs.peers?.find((p) => p.info.ilpAddress === address) ?? announce;
|
|
307
|
+
return owner?.routePrices?.[address] ?? owner?.capabilities?.find((c) => c.address === address)?.price;
|
|
308
|
+
};
|
|
196
309
|
const publishPrice = priceOf(publishDestination ?? derived.publish);
|
|
197
310
|
const storePrice = priceOf(storeDestination ?? derived.store);
|
|
198
311
|
if (publishPrice !== void 0 || storePrice !== void 0) {
|
|
@@ -386,10 +499,11 @@ async function resolveNetworkTopology(inputs) {
|
|
|
386
499
|
}
|
|
387
500
|
return {
|
|
388
501
|
...proxyUrl ? { proxyUrl } : {},
|
|
389
|
-
...btpUrl ? { btpUrl } : {},
|
|
502
|
+
...btpUrl ? { btpUrl, ...btpUrlDerived ? { btpUrlDerived } : {} } : {},
|
|
390
503
|
destination,
|
|
391
504
|
...publishDestination ? { publishDestination } : {},
|
|
392
505
|
...storeDestination ? { storeDestination } : {},
|
|
506
|
+
...storeBtpUrl ? { storeBtpUrl } : {},
|
|
393
507
|
...routePrices ? { routePrices } : {},
|
|
394
508
|
knownPeers,
|
|
395
509
|
...selection ? { selection } : {},
|
|
@@ -401,6 +515,49 @@ async function resolveNetworkTopology(inputs) {
|
|
|
401
515
|
...minaChannel ? { minaChannel } : {}
|
|
402
516
|
};
|
|
403
517
|
}
|
|
518
|
+
function resolveUplinkConfig(topo) {
|
|
519
|
+
return {
|
|
520
|
+
// validateConfig requires connectorUrl OR proxyUrl; with BTP-only
|
|
521
|
+
// config a dummy connectorUrl satisfies it (unused at runtime — same
|
|
522
|
+
// convention as the daemon).
|
|
523
|
+
...topo.proxyUrl ? { proxyUrl: topo.proxyUrl } : { connectorUrl: "http://127.0.0.1:1" },
|
|
524
|
+
...topo.btpUrl ? {
|
|
525
|
+
btpUrl: topo.btpUrl,
|
|
526
|
+
btpAuthToken: "",
|
|
527
|
+
preferBtpForPaidWrites: true
|
|
528
|
+
} : {}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
function isBtpTransportError(err) {
|
|
532
|
+
const name = err instanceof Error ? err.name : "";
|
|
533
|
+
return name === "BtpConnectionError" || name === "BtpAuthError";
|
|
534
|
+
}
|
|
535
|
+
function bootstrapRecoveries(args) {
|
|
536
|
+
let active = args.topology;
|
|
537
|
+
const detail = (err) => err instanceof Error ? err.message : String(err);
|
|
538
|
+
const recoveries = [];
|
|
539
|
+
const reresolve = args.reresolve;
|
|
540
|
+
if (reresolve) {
|
|
541
|
+
recoveries.push({
|
|
542
|
+
applies: () => true,
|
|
543
|
+
describe: (err) => `rig: bootstrap with the cached network topology failed (${detail(err)}) \u2014 invalidating the cache and re-resolving live`,
|
|
544
|
+
rebuild: async () => {
|
|
545
|
+
active = await reresolve();
|
|
546
|
+
return args.buildPublisher(active);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
recoveries.push({
|
|
551
|
+
applies: (err) => active.btpUrlDerived === true && isBtpTransportError(err),
|
|
552
|
+
describe: (err) => `rig: the discovered BTP uplink ${active.btpUrl} is unreachable (${detail(err)}) \u2014 continuing over the HTTP uplink alone; paid writes an edge accepts only over BTP will still fail, so pin a reachable endpoint with \`rig entry <url>\` if they do`,
|
|
553
|
+
rebuild: async () => {
|
|
554
|
+
const { btpUrl: _btpUrl, btpUrlDerived: _derived, ...http } = active;
|
|
555
|
+
active = http;
|
|
556
|
+
return args.buildPublisher(active);
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
return recoveries;
|
|
560
|
+
}
|
|
404
561
|
function isNetworkTopology(value) {
|
|
405
562
|
if (typeof value !== "object" || value === null) return false;
|
|
406
563
|
const t = value;
|
|
@@ -417,11 +574,11 @@ var NON_RECOVERABLE_START_ERRORS = /* @__PURE__ */ new Set([
|
|
|
417
574
|
]);
|
|
418
575
|
var TopologyRecoveringPublisher = class {
|
|
419
576
|
inner;
|
|
420
|
-
|
|
577
|
+
recoveries;
|
|
421
578
|
warn;
|
|
422
|
-
constructor(inner,
|
|
579
|
+
constructor(inner, recoveries, warn) {
|
|
423
580
|
this.inner = inner;
|
|
424
|
-
this.
|
|
581
|
+
this.recoveries = [...recoveries];
|
|
425
582
|
this.warn = warn;
|
|
426
583
|
}
|
|
427
584
|
getPublicKey() {
|
|
@@ -431,30 +588,31 @@ var TopologyRecoveringPublisher = class {
|
|
|
431
588
|
return this.inner.getFeeRates();
|
|
432
589
|
}
|
|
433
590
|
/**
|
|
434
|
-
* Run the bootstrap step,
|
|
435
|
-
*
|
|
436
|
-
*
|
|
591
|
+
* Run the bootstrap step, retrying against a repaired publisher for as long
|
|
592
|
+
* as an unused recovery applies. The LAST attempt's error is what surfaces
|
|
593
|
+
* — after a live re-resolution or an HTTP-only rebuild that is the
|
|
594
|
+
* network's real state, strictly more actionable than the failure that
|
|
595
|
+
* triggered the retry.
|
|
437
596
|
*/
|
|
438
597
|
async ensure(start) {
|
|
439
|
-
|
|
440
|
-
await start(this.inner);
|
|
441
|
-
return this.inner;
|
|
442
|
-
} catch (err) {
|
|
443
|
-
const rebuild = this.rebuild;
|
|
444
|
-
this.rebuild = void 0;
|
|
445
|
-
const name = err instanceof Error ? err.name : "";
|
|
446
|
-
if (!rebuild || NON_RECOVERABLE_START_ERRORS.has(name)) throw err;
|
|
447
|
-
this.warn(
|
|
448
|
-
`rig: bootstrap with the cached network topology failed (${err instanceof Error ? err.message : String(err)}) \u2014 invalidating the cache and re-resolving live`
|
|
449
|
-
);
|
|
450
|
-
const fresh = await rebuild();
|
|
598
|
+
for (; ; ) {
|
|
451
599
|
try {
|
|
452
|
-
await this.inner
|
|
453
|
-
|
|
600
|
+
await start(this.inner);
|
|
601
|
+
return this.inner;
|
|
602
|
+
} catch (err) {
|
|
603
|
+
const name = err instanceof Error ? err.name : "";
|
|
604
|
+
if (NON_RECOVERABLE_START_ERRORS.has(name)) throw err;
|
|
605
|
+
const index = this.recoveries.findIndex((r) => r.applies(err));
|
|
606
|
+
if (index < 0) throw err;
|
|
607
|
+
const [recovery] = this.recoveries.splice(index, 1);
|
|
608
|
+
this.warn(recovery.describe(err));
|
|
609
|
+
const fresh = await recovery.rebuild();
|
|
610
|
+
try {
|
|
611
|
+
await this.inner.stop();
|
|
612
|
+
} catch {
|
|
613
|
+
}
|
|
614
|
+
this.inner = fresh;
|
|
454
615
|
}
|
|
455
|
-
this.inner = fresh;
|
|
456
|
-
await start(this.inner);
|
|
457
|
-
return this.inner;
|
|
458
616
|
}
|
|
459
617
|
}
|
|
460
618
|
async publishEvent(event, relayUrls) {
|
|
@@ -519,6 +677,10 @@ async function createStandaloneContext(options) {
|
|
|
519
677
|
// shared public devnet relay rather than a dead local default.
|
|
520
678
|
"wss://relay-ws.devnet.toonprotocol.dev";
|
|
521
679
|
const channelStorePath = file.channelStorePath ?? join(dir, "channels.json");
|
|
680
|
+
const storeChannelStorePath = channelStorePath.replace(
|
|
681
|
+
/(\.json)?$/,
|
|
682
|
+
".store.json"
|
|
683
|
+
);
|
|
522
684
|
const channelMap = new ChannelMapStore({
|
|
523
685
|
mapPath: join(dir, RIG_CHANNEL_MAP_FILENAME),
|
|
524
686
|
watermarkPath: channelStorePath
|
|
@@ -536,6 +698,9 @@ async function createStandaloneContext(options) {
|
|
|
536
698
|
file
|
|
537
699
|
)
|
|
538
700
|
});
|
|
701
|
+
const noticeStore = new NoticeStore({
|
|
702
|
+
path: join(dir, NOTICE_STORE_FILENAME)
|
|
703
|
+
});
|
|
539
704
|
const resolveLiveTopology = async () => {
|
|
540
705
|
const solanaExplicitlyComplete = (file.supportedChains ?? []).every(
|
|
541
706
|
(chain) => !chain.startsWith("solana:") || Boolean(file.solanaChannel) || Boolean(
|
|
@@ -545,21 +710,28 @@ async function createStandaloneContext(options) {
|
|
|
545
710
|
const minaExplicitlyComplete = (file.supportedChains ?? []).every(
|
|
546
711
|
(chain) => !chain.startsWith("mina:") || Boolean(file.minaChannel)
|
|
547
712
|
);
|
|
713
|
+
const explicitStoreDest = env["TOON_CLIENT_STORE_DESTINATION"] ?? file.storeDestination;
|
|
714
|
+
const explicitPublishDest = env["TOON_CLIENT_PUBLISH_DESTINATION"] ?? file.publishDestination;
|
|
715
|
+
const storeUplinkKnown = !explicitStoreDest || explicitStoreDest === explicitPublishDest || Boolean(env["TOON_CLIENT_STORE_BTP_URL"] ?? file.storeBtpUrl);
|
|
548
716
|
const fullyExplicit = Boolean(
|
|
549
717
|
(env["TOON_CLIENT_PROXY_URL"] ?? file.proxyUrl) || (env["TOON_CLIENT_BTP_URL"] ?? file.btpUrl)
|
|
550
|
-
) && Boolean(env["TOON_CLIENT_DESTINATION"] ?? file.destination) && Boolean(file.supportedChains?.length) && solanaExplicitlyComplete && minaExplicitlyComplete;
|
|
718
|
+
) && Boolean(env["TOON_CLIENT_DESTINATION"] ?? file.destination) && Boolean(file.supportedChains?.length) && storeUplinkKnown && solanaExplicitlyComplete && minaExplicitlyComplete;
|
|
551
719
|
let announce;
|
|
720
|
+
let discoveredPeers;
|
|
552
721
|
if (!fullyExplicit) {
|
|
553
722
|
try {
|
|
554
723
|
const peers = await discoverAnnouncedPeers(relayUrl, {
|
|
555
724
|
timeoutMs: DISCOVERY_TIMEOUT_MS
|
|
556
725
|
});
|
|
557
|
-
|
|
726
|
+
discoveredPeers = peers;
|
|
727
|
+
const seedPubkeys = genesisSeedPubkeys();
|
|
728
|
+
announce = pickPaymentPeer(peers, seedPubkeys);
|
|
558
729
|
if (!announce) {
|
|
559
730
|
warn(
|
|
560
731
|
`rig: no payment-peer announce (kind:10032) found on ${relayUrl} \u2014 falling back to the genesis peer seed`
|
|
561
732
|
);
|
|
562
733
|
}
|
|
734
|
+
showOperatorNoticeOnce(announce, seedPubkeys, noticeStore, warn);
|
|
563
735
|
} catch (err) {
|
|
564
736
|
warn(
|
|
565
737
|
`rig: announce discovery on ${relayUrl} failed (${err instanceof Error ? err.message : String(err)}) \u2014 falling back to the genesis peer seed`
|
|
@@ -572,6 +744,7 @@ async function createStandaloneContext(options) {
|
|
|
572
744
|
configPath,
|
|
573
745
|
relayUrl,
|
|
574
746
|
announce,
|
|
747
|
+
...discoveredPeers ? { peers: discoveredPeers } : {},
|
|
575
748
|
genesisSeed,
|
|
576
749
|
identity: {
|
|
577
750
|
mnemonic: identity.mnemonic,
|
|
@@ -595,10 +768,7 @@ async function createStandaloneContext(options) {
|
|
|
595
768
|
const eventFee = BigInt(file.feePerEvent ?? "1");
|
|
596
769
|
const buildPublisher = (topo) => {
|
|
597
770
|
const clientConfig = {
|
|
598
|
-
|
|
599
|
-
// config a dummy connectorUrl satisfies it (unused at runtime — same
|
|
600
|
-
// convention as the daemon).
|
|
601
|
-
...topo.proxyUrl ? { proxyUrl: topo.proxyUrl } : { connectorUrl: "http://127.0.0.1:1" },
|
|
771
|
+
...resolveUplinkConfig(topo),
|
|
602
772
|
mnemonic: identity.mnemonic,
|
|
603
773
|
mnemonicAccountIndex: identity.accountIndex,
|
|
604
774
|
ilpInfo: {
|
|
@@ -610,7 +780,6 @@ async function createStandaloneContext(options) {
|
|
|
610
780
|
},
|
|
611
781
|
toonEncoder: encodeEventToToon,
|
|
612
782
|
toonDecoder: decodeEventFromToon,
|
|
613
|
-
...topo.btpUrl ? { btpUrl: topo.btpUrl, btpAuthToken: "" } : {},
|
|
614
783
|
destinationAddress: topo.destination,
|
|
615
784
|
// The embedded client bootstraps against the known peer above; its
|
|
616
785
|
// `relayUrl` config only seeds ArDrive-merged peers, so it stays unset.
|
|
@@ -646,8 +815,31 @@ async function createStandaloneContext(options) {
|
|
|
646
815
|
}
|
|
647
816
|
} : {}
|
|
648
817
|
};
|
|
818
|
+
const storeClientConfig = topo.storeBtpUrl ? {
|
|
819
|
+
...clientConfig,
|
|
820
|
+
proxyUrl: void 0,
|
|
821
|
+
connectorUrl: "http://127.0.0.1:1",
|
|
822
|
+
btpUrl: topo.storeBtpUrl,
|
|
823
|
+
btpAuthToken: "",
|
|
824
|
+
preferBtpForPaidWrites: true,
|
|
825
|
+
// Its OWN watermark file. A client's channel store and its
|
|
826
|
+
// `.peers.json` binding sidecar are one unit that the client
|
|
827
|
+
// rewrites wholesale, so pointing two live clients at one path has
|
|
828
|
+
// them clobber each other's watermarks — observed as the publish
|
|
829
|
+
// leg losing its channel ("is not being tracked", then F01) the
|
|
830
|
+
// moment the store leg opened. Separate files; the legs stay
|
|
831
|
+
// correlated through rig's own channel map, which is keyed by
|
|
832
|
+
// anchor and records both.
|
|
833
|
+
channelStorePath: storeChannelStorePath,
|
|
834
|
+
ilpInfo: {
|
|
835
|
+
...clientConfig.ilpInfo,
|
|
836
|
+
btpEndpoint: topo.storeBtpUrl
|
|
837
|
+
},
|
|
838
|
+
destinationAddress: topo.storeDestination ?? topo.destination
|
|
839
|
+
} : void 0;
|
|
649
840
|
return new StandalonePublisher({
|
|
650
841
|
clientConfig,
|
|
842
|
+
...storeClientConfig ? { storeClientConfig } : {},
|
|
651
843
|
eventFee,
|
|
652
844
|
channelMap,
|
|
653
845
|
warn,
|
|
@@ -680,10 +872,18 @@ async function createStandaloneContext(options) {
|
|
|
680
872
|
};
|
|
681
873
|
const publisher = new TopologyRecoveringPublisher(
|
|
682
874
|
buildPublisher(topology),
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
875
|
+
bootstrapRecoveries({
|
|
876
|
+
topology,
|
|
877
|
+
buildPublisher,
|
|
878
|
+
// Only a CACHE-sourced publisher gets the re-resolve recovery;
|
|
879
|
+
// live-resolved ones have nothing staler to fall back from.
|
|
880
|
+
...cached ? {
|
|
881
|
+
reresolve: async () => {
|
|
882
|
+
cache.invalidate(cacheKey);
|
|
883
|
+
return resolveLiveTopology();
|
|
884
|
+
}
|
|
885
|
+
} : {}
|
|
886
|
+
}),
|
|
687
887
|
warn
|
|
688
888
|
);
|
|
689
889
|
const walletViewNetwork = env["TOON_CLIENT_NETWORK"] ?? file.network;
|
|
@@ -715,10 +915,14 @@ async function createStandaloneContext(options) {
|
|
|
715
915
|
}
|
|
716
916
|
export {
|
|
717
917
|
MissingUplinkError,
|
|
918
|
+
OFFICIAL_BTP_URL,
|
|
718
919
|
OFFICIAL_PROXY_URL,
|
|
719
920
|
OFFICIAL_PUBLISH_DESTINATION,
|
|
921
|
+
bootstrapRecoveries,
|
|
720
922
|
buildMinaAutoDeploy,
|
|
721
923
|
createStandaloneContext,
|
|
722
|
-
|
|
924
|
+
isBtpTransportError,
|
|
925
|
+
resolveNetworkTopology,
|
|
926
|
+
resolveUplinkConfig
|
|
723
927
|
};
|
|
724
|
-
//# sourceMappingURL=standalone-mode-
|
|
928
|
+
//# sourceMappingURL=standalone-mode-5MNNJC2D.js.map
|