@toon-protocol/rig 2.1.0 → 2.2.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/README.md +92 -13
- package/dist/{chunk-PLKZAUTG.js → chunk-JBB7HBQC.js} +119 -6
- package/dist/chunk-JBB7HBQC.js.map +1 -0
- package/dist/{chunk-3EKP7PMM.js → chunk-OIJNRACA.js} +5 -144
- package/dist/chunk-OIJNRACA.js.map +1 -0
- package/dist/{chunk-LFGDLD6J.js → chunk-PS5QOT62.js} +464 -4
- package/dist/chunk-PS5QOT62.js.map +1 -0
- package/dist/{chunk-O6TXHKWG.js → chunk-SW7ZHMGS.js} +143 -2
- package/dist/chunk-SW7ZHMGS.js.map +1 -0
- package/dist/cli/rig.js +1515 -149
- package/dist/cli/rig.js.map +1 -1
- package/dist/index.d.ts +271 -3
- package/dist/index.js +44 -8
- package/dist/{publisher-Cdr1H1hg.d.ts → publisher-CrwaNQrK.d.ts} +11 -2
- package/dist/standalone/index.d.ts +7 -1
- package/dist/standalone/index.js +9 -9
- package/dist/{standalone-mode-FCKTQ33Y.js → standalone-mode-64CKUVU2.js} +367 -97
- package/dist/standalone-mode-64CKUVU2.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-3EKP7PMM.js.map +0 -1
- package/dist/chunk-HPSOQP7Q.js +0 -109
- package/dist/chunk-HPSOQP7Q.js.map +0 -1
- package/dist/chunk-LFGDLD6J.js.map +0 -1
- package/dist/chunk-O6TXHKWG.js.map +0 -1
- package/dist/chunk-PLKZAUTG.js.map +0 -1
- package/dist/standalone-mode-FCKTQ33Y.js.map +0 -1
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
fetchRemoteState,
|
|
3
|
-
queryRelay
|
|
4
|
-
} from "./chunk-PLKZAUTG.js";
|
|
5
1
|
import {
|
|
6
2
|
resolveIdentity
|
|
7
3
|
} from "./chunk-CW4HJNMU.js";
|
|
8
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
fetchRemoteState,
|
|
6
|
+
queryRelay
|
|
7
|
+
} from "./chunk-JBB7HBQC.js";
|
|
9
8
|
import {
|
|
10
9
|
StandalonePublisher
|
|
11
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-OIJNRACA.js";
|
|
12
11
|
import {
|
|
13
12
|
ChannelMapStore,
|
|
14
13
|
RIG_CHANNEL_MAP_FILENAME
|
|
15
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-SW7ZHMGS.js";
|
|
16
15
|
import "./chunk-X2CZPPDM.js";
|
|
17
16
|
|
|
18
17
|
// src/cli/standalone-mode.ts
|
|
19
|
-
import { readFileSync } from "fs";
|
|
18
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
20
19
|
import { homedir } from "os";
|
|
21
20
|
import { join } from "path";
|
|
22
21
|
import { EvmSigner, deriveNostrKeyFromMnemonic } from "@toon-protocol/client";
|
|
@@ -25,6 +24,161 @@ import {
|
|
|
25
24
|
encodeEventToToon
|
|
26
25
|
} from "@toon-protocol/core";
|
|
27
26
|
|
|
27
|
+
// src/standalone/topology-cache.ts
|
|
28
|
+
import { createHash } from "crypto";
|
|
29
|
+
import { mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
|
|
30
|
+
import { dirname } from "path";
|
|
31
|
+
var TOPOLOGY_CACHE_FILENAME = "rig-topology-cache.json";
|
|
32
|
+
var DEFAULT_TOPOLOGY_TTL_MS = 15 * 60 * 1e3;
|
|
33
|
+
var TOPOLOGY_TTL_ENV = "RIG_TOPOLOGY_TTL_MS";
|
|
34
|
+
function topologyCacheTtlMs(env) {
|
|
35
|
+
const raw = env[TOPOLOGY_TTL_ENV];
|
|
36
|
+
if (raw === void 0 || raw === "") return DEFAULT_TOPOLOGY_TTL_MS;
|
|
37
|
+
const parsed = Number(raw);
|
|
38
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_TOPOLOGY_TTL_MS;
|
|
39
|
+
}
|
|
40
|
+
function topologyCacheKey(args) {
|
|
41
|
+
return createHash("sha256").update(`${args.relayUrl}
|
|
42
|
+
${args.identity}
|
|
43
|
+
${args.fingerprint}`).digest("hex");
|
|
44
|
+
}
|
|
45
|
+
function explicitConfigFingerprint(env, file) {
|
|
46
|
+
const envKeys = [
|
|
47
|
+
"TOON_CLIENT_PROXY_URL",
|
|
48
|
+
"TOON_CLIENT_BTP_URL",
|
|
49
|
+
"TOON_CLIENT_DESTINATION",
|
|
50
|
+
"TOON_CLIENT_PUBLISH_DESTINATION",
|
|
51
|
+
"TOON_CLIENT_STORE_DESTINATION",
|
|
52
|
+
"TOON_CLIENT_CHAIN",
|
|
53
|
+
"TOON_CLIENT_NETWORK"
|
|
54
|
+
];
|
|
55
|
+
const fileKeys = [
|
|
56
|
+
"network",
|
|
57
|
+
"btpUrl",
|
|
58
|
+
"proxyUrl",
|
|
59
|
+
"destination",
|
|
60
|
+
"publishDestination",
|
|
61
|
+
"storeDestination",
|
|
62
|
+
"chain",
|
|
63
|
+
"supportedChains",
|
|
64
|
+
"settlementAddresses",
|
|
65
|
+
"preferredTokens",
|
|
66
|
+
"tokenNetworks",
|
|
67
|
+
"chainRpcUrls"
|
|
68
|
+
];
|
|
69
|
+
const picked = {};
|
|
70
|
+
for (const key of envKeys) {
|
|
71
|
+
if (env[key] !== void 0) picked[`env:${key}`] = env[key];
|
|
72
|
+
}
|
|
73
|
+
for (const key of fileKeys) {
|
|
74
|
+
if (file[key] !== void 0) picked[`file:${key}`] = file[key];
|
|
75
|
+
}
|
|
76
|
+
return JSON.stringify(picked);
|
|
77
|
+
}
|
|
78
|
+
var TopologyCache = class {
|
|
79
|
+
path;
|
|
80
|
+
ttlMs;
|
|
81
|
+
validate;
|
|
82
|
+
now;
|
|
83
|
+
constructor(options) {
|
|
84
|
+
this.path = options.path;
|
|
85
|
+
this.ttlMs = options.ttlMs;
|
|
86
|
+
this.validate = options.validate;
|
|
87
|
+
this.now = options.now ?? Date.now;
|
|
88
|
+
}
|
|
89
|
+
/** True when the cache is disabled (`RIG_TOPOLOGY_TTL_MS=0`). */
|
|
90
|
+
get disabled() {
|
|
91
|
+
return this.ttlMs <= 0;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A fresh, structurally-valid entry for `key` — or undefined (expired,
|
|
95
|
+
* missing, invalid, corrupt file, or disabled). Also reports the entry age
|
|
96
|
+
* for the "topology from cache" stderr line.
|
|
97
|
+
*/
|
|
98
|
+
read(key) {
|
|
99
|
+
if (this.disabled) return void 0;
|
|
100
|
+
const entry = this.readFile().entries[key];
|
|
101
|
+
if (!entry) return void 0;
|
|
102
|
+
const cachedAt = Date.parse(entry.cachedAt);
|
|
103
|
+
if (!Number.isFinite(cachedAt)) return void 0;
|
|
104
|
+
const ageMs = this.now() - cachedAt;
|
|
105
|
+
if (ageMs < 0 || ageMs > this.ttlMs) return void 0;
|
|
106
|
+
if (!this.validate(entry.topology)) return void 0;
|
|
107
|
+
return { topology: entry.topology, ageMs };
|
|
108
|
+
}
|
|
109
|
+
/** Persist `topology` under `key` (prunes expired entries; best-effort). */
|
|
110
|
+
write(key, topology) {
|
|
111
|
+
if (this.disabled) return;
|
|
112
|
+
try {
|
|
113
|
+
const file = this.readFile();
|
|
114
|
+
const nowMs = this.now();
|
|
115
|
+
const fresh = Object.fromEntries(
|
|
116
|
+
Object.entries(file.entries).filter(([, entry]) => {
|
|
117
|
+
const at = Date.parse(entry.cachedAt);
|
|
118
|
+
return Number.isFinite(at) && nowMs - at <= this.ttlMs;
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
fresh[key] = {
|
|
122
|
+
cachedAt: new Date(nowMs).toISOString(),
|
|
123
|
+
topology
|
|
124
|
+
};
|
|
125
|
+
mkdirSync(dirname(this.path), { recursive: true });
|
|
126
|
+
writeFileSync(
|
|
127
|
+
this.path,
|
|
128
|
+
JSON.stringify(
|
|
129
|
+
{ version: 1, entries: fresh },
|
|
130
|
+
null,
|
|
131
|
+
2
|
|
132
|
+
),
|
|
133
|
+
{ mode: 384 }
|
|
134
|
+
);
|
|
135
|
+
} catch {
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Drop `key` (a cached topology failed to bootstrap). Best-effort. */
|
|
139
|
+
invalidate(key) {
|
|
140
|
+
try {
|
|
141
|
+
const file = this.readFile();
|
|
142
|
+
if (!(key in file.entries)) return;
|
|
143
|
+
const remaining = Object.fromEntries(
|
|
144
|
+
Object.entries(file.entries).filter(([k]) => k !== key)
|
|
145
|
+
);
|
|
146
|
+
if (Object.keys(remaining).length === 0) {
|
|
147
|
+
unlinkSync(this.path);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
writeFileSync(
|
|
151
|
+
this.path,
|
|
152
|
+
JSON.stringify(
|
|
153
|
+
{ version: 1, entries: remaining },
|
|
154
|
+
null,
|
|
155
|
+
2
|
|
156
|
+
),
|
|
157
|
+
{ mode: 384 }
|
|
158
|
+
);
|
|
159
|
+
} catch {
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
readFile() {
|
|
163
|
+
const empty = { version: 1, entries: {} };
|
|
164
|
+
let raw;
|
|
165
|
+
try {
|
|
166
|
+
raw = readFileSync(this.path, "utf8");
|
|
167
|
+
} catch {
|
|
168
|
+
return empty;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const parsed = JSON.parse(raw);
|
|
172
|
+
if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || typeof parsed.entries !== "object" || parsed.entries === null) {
|
|
173
|
+
return empty;
|
|
174
|
+
}
|
|
175
|
+
return parsed;
|
|
176
|
+
} catch {
|
|
177
|
+
return empty;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
28
182
|
// src/standalone/network-bootstrap.ts
|
|
29
183
|
import {
|
|
30
184
|
CHAIN_PRESETS,
|
|
@@ -300,7 +454,7 @@ function configDir(env) {
|
|
|
300
454
|
}
|
|
301
455
|
function readClientConfig(path) {
|
|
302
456
|
try {
|
|
303
|
-
return JSON.parse(
|
|
457
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
304
458
|
} catch (err) {
|
|
305
459
|
if (err.code === "ENOENT") return {};
|
|
306
460
|
throw new Error(
|
|
@@ -438,7 +592,7 @@ async function resolveNetworkTopology(inputs) {
|
|
|
438
592
|
const network = env["TOON_CLIENT_NETWORK"] ?? file.network;
|
|
439
593
|
if (network && network !== "custom" && !file.supportedChains?.length) {
|
|
440
594
|
warn(
|
|
441
|
-
`rig: ignoring the "${network}" network preset for settlement \u2014 the chain comes from the announce
|
|
595
|
+
`rig: ignoring the "${network}" network preset for settlement \u2014 the settlement chain comes from the payment peer's announce and your config, because preset chains can point at networks your wallet has no funds on; set supportedChains explicitly to use preset chains`
|
|
442
596
|
);
|
|
443
597
|
}
|
|
444
598
|
return {
|
|
@@ -455,6 +609,87 @@ async function resolveNetworkTopology(inputs) {
|
|
|
455
609
|
...chainRpcUrls && Object.keys(chainRpcUrls).length > 0 ? { chainRpcUrls } : {}
|
|
456
610
|
};
|
|
457
611
|
}
|
|
612
|
+
function isNetworkTopology(value) {
|
|
613
|
+
if (typeof value !== "object" || value === null) return false;
|
|
614
|
+
const t = value;
|
|
615
|
+
return typeof t["destination"] === "string" && Array.isArray(t["knownPeers"]);
|
|
616
|
+
}
|
|
617
|
+
var NON_RECOVERABLE_START_ERRORS = /* @__PURE__ */ new Set([
|
|
618
|
+
"DaemonIdentityConflictError",
|
|
619
|
+
"StandaloneLockError",
|
|
620
|
+
"ChannelMapCorruptError"
|
|
621
|
+
]);
|
|
622
|
+
var TopologyRecoveringPublisher = class {
|
|
623
|
+
inner;
|
|
624
|
+
rebuild;
|
|
625
|
+
warn;
|
|
626
|
+
constructor(inner, rebuild, warn) {
|
|
627
|
+
this.inner = inner;
|
|
628
|
+
this.rebuild = rebuild;
|
|
629
|
+
this.warn = warn;
|
|
630
|
+
}
|
|
631
|
+
getPublicKey() {
|
|
632
|
+
return this.inner.getPublicKey();
|
|
633
|
+
}
|
|
634
|
+
getFeeRates() {
|
|
635
|
+
return this.inner.getFeeRates();
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Run the bootstrap step, recovering ONCE from a stale cached topology.
|
|
639
|
+
* A rebuild failure surfaces the LIVE resolution's error — that is the
|
|
640
|
+
* network's real state, strictly more actionable than the cached failure.
|
|
641
|
+
*/
|
|
642
|
+
async ensure(start) {
|
|
643
|
+
try {
|
|
644
|
+
await start(this.inner);
|
|
645
|
+
return this.inner;
|
|
646
|
+
} catch (err) {
|
|
647
|
+
const rebuild = this.rebuild;
|
|
648
|
+
this.rebuild = void 0;
|
|
649
|
+
const name = err instanceof Error ? err.name : "";
|
|
650
|
+
if (!rebuild || NON_RECOVERABLE_START_ERRORS.has(name)) throw err;
|
|
651
|
+
this.warn(
|
|
652
|
+
`rig: bootstrap with the cached network topology failed (${err instanceof Error ? err.message : String(err)}) \u2014 invalidating the cache and re-resolving live`
|
|
653
|
+
);
|
|
654
|
+
const fresh = await rebuild();
|
|
655
|
+
try {
|
|
656
|
+
await this.inner.stop();
|
|
657
|
+
} catch {
|
|
658
|
+
}
|
|
659
|
+
this.inner = fresh;
|
|
660
|
+
await start(this.inner);
|
|
661
|
+
return this.inner;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
async publishEvent(event, relayUrls) {
|
|
665
|
+
const p = await this.ensure((x) => x.start());
|
|
666
|
+
return p.publishEvent(event, relayUrls);
|
|
667
|
+
}
|
|
668
|
+
async uploadGitObject(upload) {
|
|
669
|
+
const p = await this.ensure((x) => x.start());
|
|
670
|
+
return p.uploadGitObject(upload);
|
|
671
|
+
}
|
|
672
|
+
// ── money lifecycle passthroughs (#263) — same recovery contract ─────────
|
|
673
|
+
async openChannelExplicit(opts) {
|
|
674
|
+
const p = await this.ensure((x) => x.start());
|
|
675
|
+
return p.openChannelExplicit(opts);
|
|
676
|
+
}
|
|
677
|
+
async closeRecordedChannel(record) {
|
|
678
|
+
const p = await this.ensure((x) => x.startClientOnly());
|
|
679
|
+
return p.closeRecordedChannel(record);
|
|
680
|
+
}
|
|
681
|
+
async settleRecordedChannel(record) {
|
|
682
|
+
const p = await this.ensure((x) => x.startClientOnly());
|
|
683
|
+
return p.settleRecordedChannel(record);
|
|
684
|
+
}
|
|
685
|
+
/** Free read on the unstarted client — no bootstrap, no recovery needed. */
|
|
686
|
+
readWalletBalances() {
|
|
687
|
+
return this.inner.readWalletBalances();
|
|
688
|
+
}
|
|
689
|
+
async stop() {
|
|
690
|
+
await this.inner.stop();
|
|
691
|
+
}
|
|
692
|
+
};
|
|
458
693
|
function chainRecordsFor(map, identity) {
|
|
459
694
|
return map.list().filter((r) => r.identity === identity).map((r) => {
|
|
460
695
|
const watermark = map.readWatermark(r.channelId);
|
|
@@ -474,101 +709,136 @@ async function createStandaloneContext(options) {
|
|
|
474
709
|
const identity = await resolveIdentity(options);
|
|
475
710
|
const genesisSeed = loadGenesisSeed();
|
|
476
711
|
const relayUrl = options.relayUrl ?? env["TOON_CLIENT_RELAY_URL"] ?? file.relayUrl ?? genesisSeed?.relayUrl ?? "ws://localhost:7100";
|
|
477
|
-
const fullyExplicit = Boolean(
|
|
478
|
-
(env["TOON_CLIENT_PROXY_URL"] ?? file.proxyUrl) || (env["TOON_CLIENT_BTP_URL"] ?? file.btpUrl)
|
|
479
|
-
) && Boolean(env["TOON_CLIENT_DESTINATION"] ?? file.destination) && Boolean(file.supportedChains?.length);
|
|
480
|
-
let announce;
|
|
481
|
-
if (!fullyExplicit) {
|
|
482
|
-
try {
|
|
483
|
-
const peers = await discoverAnnouncedPeers(relayUrl, {
|
|
484
|
-
timeoutMs: DISCOVERY_TIMEOUT_MS
|
|
485
|
-
});
|
|
486
|
-
announce = pickPaymentPeer(peers, genesisSeedPubkeys());
|
|
487
|
-
if (!announce) {
|
|
488
|
-
warn(
|
|
489
|
-
`rig: no payment-peer announce (kind:10032) found on ${relayUrl} \u2014 falling back to the genesis peer seed`
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
} catch (err) {
|
|
493
|
-
warn(
|
|
494
|
-
`rig: announce discovery on ${relayUrl} failed (${err instanceof Error ? err.message : String(err)}) \u2014 falling back to the genesis peer seed`
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
712
|
const channelStorePath = file.channelStorePath ?? join(dir, "channels.json");
|
|
499
713
|
const channelMap = new ChannelMapStore({
|
|
500
714
|
mapPath: join(dir, RIG_CHANNEL_MAP_FILENAME),
|
|
501
715
|
watermarkPath: channelStorePath
|
|
502
716
|
});
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
717
|
+
const cache = new TopologyCache({
|
|
718
|
+
path: join(dir, TOPOLOGY_CACHE_FILENAME),
|
|
719
|
+
ttlMs: topologyCacheTtlMs(env),
|
|
720
|
+
validate: isNetworkTopology
|
|
721
|
+
});
|
|
722
|
+
const cacheKey = topologyCacheKey({
|
|
507
723
|
relayUrl,
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
pubkey: identity.pubkey
|
|
514
|
-
},
|
|
515
|
-
channelRecords: () => chainRecordsFor(channelMap, identity.pubkey),
|
|
516
|
-
...options.requireUplink !== void 0 ? { requireUplink: options.requireUplink } : {},
|
|
517
|
-
warn
|
|
724
|
+
identity: identity.pubkey,
|
|
725
|
+
fingerprint: explicitConfigFingerprint(
|
|
726
|
+
env,
|
|
727
|
+
file
|
|
728
|
+
)
|
|
518
729
|
});
|
|
730
|
+
const resolveLiveTopology = async () => {
|
|
731
|
+
const fullyExplicit = Boolean(
|
|
732
|
+
(env["TOON_CLIENT_PROXY_URL"] ?? file.proxyUrl) || (env["TOON_CLIENT_BTP_URL"] ?? file.btpUrl)
|
|
733
|
+
) && Boolean(env["TOON_CLIENT_DESTINATION"] ?? file.destination) && Boolean(file.supportedChains?.length);
|
|
734
|
+
let announce;
|
|
735
|
+
if (!fullyExplicit) {
|
|
736
|
+
try {
|
|
737
|
+
const peers = await discoverAnnouncedPeers(relayUrl, {
|
|
738
|
+
timeoutMs: DISCOVERY_TIMEOUT_MS
|
|
739
|
+
});
|
|
740
|
+
announce = pickPaymentPeer(peers, genesisSeedPubkeys());
|
|
741
|
+
if (!announce) {
|
|
742
|
+
warn(
|
|
743
|
+
`rig: no payment-peer announce (kind:10032) found on ${relayUrl} \u2014 falling back to the genesis peer seed`
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
} catch (err) {
|
|
747
|
+
warn(
|
|
748
|
+
`rig: announce discovery on ${relayUrl} failed (${err instanceof Error ? err.message : String(err)}) \u2014 falling back to the genesis peer seed`
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
const resolved = await resolveNetworkTopology({
|
|
753
|
+
env,
|
|
754
|
+
file,
|
|
755
|
+
configPath,
|
|
756
|
+
relayUrl,
|
|
757
|
+
announce,
|
|
758
|
+
genesisSeed,
|
|
759
|
+
identity: {
|
|
760
|
+
mnemonic: identity.mnemonic,
|
|
761
|
+
accountIndex: identity.accountIndex,
|
|
762
|
+
pubkey: identity.pubkey
|
|
763
|
+
},
|
|
764
|
+
channelRecords: () => chainRecordsFor(channelMap, identity.pubkey),
|
|
765
|
+
...options.requireUplink !== void 0 ? { requireUplink: options.requireUplink } : {},
|
|
766
|
+
warn
|
|
767
|
+
});
|
|
768
|
+
if (options.requireUplink !== false) cache.write(cacheKey, resolved);
|
|
769
|
+
return resolved;
|
|
770
|
+
};
|
|
771
|
+
const cached = cache.read(cacheKey);
|
|
772
|
+
if (cached) {
|
|
773
|
+
warn(
|
|
774
|
+
`rig: network topology from cache (${Math.round(cached.ageMs / 1e3)}s old; ${TOPOLOGY_TTL_ENV}=0 disables) \u2014 skipping announce discovery`
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
const topology = cached?.topology ?? await resolveLiveTopology();
|
|
519
778
|
const eventFee = BigInt(file.feePerEvent ?? "1");
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
779
|
+
const buildPublisher = (topo) => {
|
|
780
|
+
const clientConfig = {
|
|
781
|
+
// validateConfig requires connectorUrl OR proxyUrl; with BTP-only
|
|
782
|
+
// config a dummy connectorUrl satisfies it (unused at runtime — same
|
|
783
|
+
// convention as the daemon).
|
|
784
|
+
...topo.proxyUrl ? { proxyUrl: topo.proxyUrl } : { connectorUrl: "http://127.0.0.1:1" },
|
|
785
|
+
mnemonic: identity.mnemonic,
|
|
786
|
+
mnemonicAccountIndex: identity.accountIndex,
|
|
787
|
+
ilpInfo: {
|
|
788
|
+
pubkey: "00".repeat(32),
|
|
789
|
+
ilpAddress: "g.toon.client",
|
|
790
|
+
btpEndpoint: topo.btpUrl ?? "",
|
|
791
|
+
assetCode: "USD",
|
|
792
|
+
assetScale: 6
|
|
793
|
+
},
|
|
794
|
+
toonEncoder: encodeEventToToon,
|
|
795
|
+
toonDecoder: decodeEventFromToon,
|
|
796
|
+
...topo.btpUrl ? { btpUrl: topo.btpUrl, btpAuthToken: "" } : {},
|
|
797
|
+
destinationAddress: topo.destination,
|
|
798
|
+
// The embedded client bootstraps against the known peer above; its
|
|
799
|
+
// `relayUrl` config only seeds ArDrive-merged peers, so it stays unset.
|
|
800
|
+
relayUrl: "",
|
|
801
|
+
knownPeers: topo.knownPeers,
|
|
802
|
+
channelStorePath,
|
|
803
|
+
...topo.supportedChains ? { supportedChains: topo.supportedChains } : {},
|
|
804
|
+
...file.settlementAddresses ? { settlementAddresses: file.settlementAddresses } : {},
|
|
805
|
+
...topo.preferredTokens ? { preferredTokens: topo.preferredTokens } : {},
|
|
806
|
+
...topo.tokenNetworks ? { tokenNetworks: topo.tokenNetworks } : {},
|
|
807
|
+
...topo.chainRpcUrls ? { chainRpcUrls: topo.chainRpcUrls } : {},
|
|
808
|
+
...file.solanaChannel ? { solanaChannel: file.solanaChannel } : {},
|
|
809
|
+
...file.minaChannel ? { minaChannel: file.minaChannel } : {}
|
|
810
|
+
};
|
|
811
|
+
return new StandalonePublisher({
|
|
812
|
+
clientConfig,
|
|
813
|
+
eventFee,
|
|
814
|
+
channelMap,
|
|
815
|
+
warn,
|
|
816
|
+
...topo.publishDestination ? { publishDestination: topo.publishDestination } : {},
|
|
817
|
+
...topo.storeDestination ? { storeDestination: topo.storeDestination } : {},
|
|
818
|
+
// `rig channel open --peer` (#263): anchor the channel (and its map
|
|
819
|
+
// key) to an explicit peer destination instead of the configured
|
|
820
|
+
// default.
|
|
821
|
+
...options.channelDestination ? { channelDestination: options.channelDestination } : {},
|
|
822
|
+
// The peer's announce does not carry TokenNetwork/token parameters, so
|
|
823
|
+
// the client's negotiation leaves them empty (#260 root cause 3) — the
|
|
824
|
+
// publisher back-fills them from the derived per-chain maps before the
|
|
825
|
+
// channel opens.
|
|
826
|
+
...topo.tokenNetworks || topo.preferredTokens ? {
|
|
827
|
+
negotiationFallbacks: {
|
|
828
|
+
...topo.tokenNetworks ? { tokenNetworks: topo.tokenNetworks } : {},
|
|
829
|
+
...topo.preferredTokens ? { preferredTokens: topo.preferredTokens } : {}
|
|
830
|
+
}
|
|
831
|
+
} : {}
|
|
832
|
+
});
|
|
550
833
|
};
|
|
551
|
-
const publisher = new
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
// to an explicit peer destination instead of the configured default.
|
|
560
|
-
...options.channelDestination ? { channelDestination: options.channelDestination } : {},
|
|
561
|
-
// The peer's announce does not carry TokenNetwork/token parameters, so
|
|
562
|
-
// the client's negotiation leaves them empty (#260 root cause 3) — the
|
|
563
|
-
// publisher back-fills them from the derived per-chain maps before the
|
|
564
|
-
// channel opens.
|
|
565
|
-
...topology.tokenNetworks || topology.preferredTokens ? {
|
|
566
|
-
negotiationFallbacks: {
|
|
567
|
-
...topology.tokenNetworks ? { tokenNetworks: topology.tokenNetworks } : {},
|
|
568
|
-
...topology.preferredTokens ? { preferredTokens: topology.preferredTokens } : {}
|
|
569
|
-
}
|
|
570
|
-
} : {}
|
|
571
|
-
});
|
|
834
|
+
const publisher = new TopologyRecoveringPublisher(
|
|
835
|
+
buildPublisher(topology),
|
|
836
|
+
cached ? async () => {
|
|
837
|
+
cache.invalidate(cacheKey);
|
|
838
|
+
return buildPublisher(await resolveLiveTopology());
|
|
839
|
+
} : void 0,
|
|
840
|
+
warn
|
|
841
|
+
);
|
|
572
842
|
return {
|
|
573
843
|
ownerPubkey: publisher.getPublicKey(),
|
|
574
844
|
identitySource: identity.source,
|
|
@@ -592,4 +862,4 @@ export {
|
|
|
592
862
|
createStandaloneContext,
|
|
593
863
|
resolveNetworkTopology
|
|
594
864
|
};
|
|
595
|
-
//# sourceMappingURL=standalone-mode-
|
|
865
|
+
//# sourceMappingURL=standalone-mode-64CKUVU2.js.map
|