@toon-protocol/rig 2.0.0 → 2.1.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 +10 -3
- package/dist/chunk-3EKP7PMM.js +727 -0
- package/dist/chunk-3EKP7PMM.js.map +1 -0
- package/dist/{chunk-QD437XAW.js → chunk-CW4HJNMU.js} +2 -8
- package/dist/chunk-CW4HJNMU.js.map +1 -0
- package/dist/chunk-O6TXHKWG.js +217 -0
- package/dist/chunk-O6TXHKWG.js.map +1 -0
- package/dist/{chunk-G4W4MH6G.js → chunk-PLKZAUTG.js} +2 -1
- package/dist/chunk-PLKZAUTG.js.map +1 -0
- package/dist/cli/rig.js +1286 -398
- package/dist/cli/rig.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{publisher-CClD9OIZ.d.ts → publisher-Cdr1H1hg.d.ts} +1 -1
- package/dist/standalone/index.d.ts +404 -3
- package/dist/standalone/index.js +16 -2
- package/dist/standalone-mode-FCKTQ33Y.js +595 -0
- package/dist/standalone-mode-FCKTQ33Y.js.map +1 -0
- package/package.json +3 -11
- package/dist/chunk-G4W4MH6G.js.map +0 -1
- package/dist/chunk-QD437XAW.js.map +0 -1
- package/dist/chunk-XRRU6YBQ.js +0 -402
- package/dist/chunk-XRRU6YBQ.js.map +0 -1
- package/dist/standalone-mode-CAYWOURK.js +0 -111
- package/dist/standalone-mode-CAYWOURK.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { C as COMMENT_KIND,
|
|
1
|
+
import { G as GitObjectType, P as Publisher, F as FeeRates, a as PublishReceipt } from './publisher-Cdr1H1hg.js';
|
|
2
|
+
export { C as COMMENT_KIND, b as GitObject, c as GitObjectUpload, M as MAX_OBJECT_SIZE, R as REPOSITORY_STATE_KIND, S as StatusKind, U as UnsignedEvent, d as UploadReceipt, e as buildComment, f as buildIssue, g as buildPatch, h as buildRepoAnnouncement, i as buildRepoRefs, j as buildStatus, k as createGitBlob, l as createGitCommit, m as createGitTag, n as createGitTree, o as hashGitObject } from './publisher-Cdr1H1hg.js';
|
|
3
3
|
import '@toon-protocol/core/nip34';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/index.js
CHANGED
|
@@ -251,4 +251,4 @@ interface Publisher {
|
|
|
251
251
|
publishEvent(event: UnsignedEvent, relayUrls: string[]): Promise<PublishReceipt>;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
export { COMMENT_KIND as C, type FeeRates as F, type
|
|
254
|
+
export { COMMENT_KIND as C, type FeeRates as F, type GitObjectType as G, MAX_OBJECT_SIZE as M, type Publisher as P, REPOSITORY_STATE_KIND as R, type StatusKind as S, type UnsignedEvent as U, type PublishReceipt as a, type GitObject as b, type GitObjectUpload as c, type UploadReceipt as d, buildComment as e, buildIssue as f, buildPatch as g, buildRepoAnnouncement as h, buildRepoRefs as i, buildStatus as j, createGitBlob as k, createGitCommit as l, createGitTag as m, createGitTree as n, hashGitObject as o };
|
|
@@ -1,7 +1,266 @@
|
|
|
1
1
|
import { ToonClientConfig, SignedBalanceProof, PublishEventResult } from '@toon-protocol/client';
|
|
2
|
-
import { U as UnsignedEvent, P as Publisher, F as FeeRates,
|
|
2
|
+
import { U as UnsignedEvent, P as Publisher, F as FeeRates, c as GitObjectUpload, d as UploadReceipt, a as PublishReceipt } from '../publisher-Cdr1H1hg.js';
|
|
3
3
|
import '@toon-protocol/core/nip34';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Peer→channel map for the STANDALONE embedded publisher (#262).
|
|
7
|
+
*
|
|
8
|
+
* Why this exists: `@toon-protocol/client`'s `ChannelManager` persists the
|
|
9
|
+
* off-chain nonce/cumulative-claim watermark (its `ChannelStore`,
|
|
10
|
+
* `channels.json`, keyed by channelId) but keeps the peer→channelId mapping
|
|
11
|
+
* ONLY in memory. So every standalone CLI invocation used to open (and fund)
|
|
12
|
+
* a FRESH on-chain channel — the #260 fresh-outsider e2e stranded five
|
|
13
|
+
* deposits across five commands. This store remembers WHICH channel the
|
|
14
|
+
* identity holds with each peer, keyed by
|
|
15
|
+
* `identity pubkey | ILP anchor (peer/apex destination) | chain | tokenNetwork`,
|
|
16
|
+
* so the next invocation resumes it via `ChannelManager.trackChannel` (which
|
|
17
|
+
* rehydrates the nonce watermark from `channels.json`) with zero on-chain
|
|
18
|
+
* writes.
|
|
19
|
+
*
|
|
20
|
+
* It is the standalone twin of the daemon's
|
|
21
|
+
* `packages/client-mcp/src/daemon/apex-channel-store.ts` — same record shape
|
|
22
|
+
* (channelId + the chain context `trackChannel` needs), extended with the
|
|
23
|
+
* identity pubkey (rig identities come from an env/`.env` precedence chain,
|
|
24
|
+
* so one state dir can serve several identities) and the tokenNetwork.
|
|
25
|
+
* `@toon-protocol/rig` must not import `@toon-protocol/client-mcp` (that
|
|
26
|
+
* package depends on this one — circular), hence the twin; keep the
|
|
27
|
+
* semantics in sync.
|
|
28
|
+
*
|
|
29
|
+
* CONCURRENCY: writes happen only from paid commands, which already hold the
|
|
30
|
+
* per-identity advisory lockfile (./nonce-guard.ts `NonceLock`) for their
|
|
31
|
+
* whole lifetime — the same guard that serializes the claim watermark also
|
|
32
|
+
* serializes this file for one identity. `rig channel list` reads only.
|
|
33
|
+
*
|
|
34
|
+
* CORRUPTION: an unreadable/invalid map file is a hard
|
|
35
|
+
* {@link ChannelMapCorruptError} — surfaced BEFORE any on-chain open — never
|
|
36
|
+
* an empty fallback. Falling back to "no channels" would silently open (and
|
|
37
|
+
* fund) a duplicate channel, which is exactly the #262 bug.
|
|
38
|
+
*
|
|
39
|
+
* This module is dependency-light on purpose (node:fs only): the free
|
|
40
|
+
* `rig channel list` command reads it without the optional
|
|
41
|
+
* `@toon-protocol/client` peer dependency installed.
|
|
42
|
+
*/
|
|
43
|
+
/** Map filename under the shared client state dir. */
|
|
44
|
+
declare const RIG_CHANNEL_MAP_FILENAME = "rig-channels.json";
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the two channel-state files under `TOON_CLIENT_HOME` (default
|
|
47
|
+
* `~/.toon-client`): the rig peer→channel map, and the client's nonce
|
|
48
|
+
* watermark store (`config.json`'s `channelStorePath`, default
|
|
49
|
+
* `<dir>/channels.json` — the same resolution `cli/standalone-mode.ts` feeds
|
|
50
|
+
* the embedded ToonClient).
|
|
51
|
+
*/
|
|
52
|
+
declare function resolveChannelPaths(env: NodeJS.ProcessEnv): {
|
|
53
|
+
mapPath: string;
|
|
54
|
+
watermarkPath: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Chain context `ChannelManager.trackChannel` needs to resume a channel
|
|
58
|
+
* (same shape the daemon's apex-channel-store persists).
|
|
59
|
+
*/
|
|
60
|
+
interface PersistedChannelContext {
|
|
61
|
+
chainType: string;
|
|
62
|
+
chainId: number;
|
|
63
|
+
tokenNetworkAddress: string;
|
|
64
|
+
tokenAddress?: string;
|
|
65
|
+
/** Counterparty settlement address (required for Solana/Mina proofs). */
|
|
66
|
+
recipient?: string;
|
|
67
|
+
}
|
|
68
|
+
/** One persisted peer→channel binding. */
|
|
69
|
+
interface ChannelMapRecord {
|
|
70
|
+
/** On-chain payment channel id. */
|
|
71
|
+
channelId: string;
|
|
72
|
+
/** Registered peer id the negotiation was keyed by (`peerNegotiations`). */
|
|
73
|
+
peerId: string;
|
|
74
|
+
/** Hex Nostr pubkey of the identity that opened the channel. */
|
|
75
|
+
identity: string;
|
|
76
|
+
/** ILP anchor destination the channel was opened against (peer/apex). */
|
|
77
|
+
destination: string;
|
|
78
|
+
/** Negotiated settlement chain, e.g. `evm:31337`. */
|
|
79
|
+
chain: string;
|
|
80
|
+
/** TokenNetwork contract address ('' when the peer announced none). */
|
|
81
|
+
tokenNetwork: string;
|
|
82
|
+
/** Context for `trackChannel` on resume. */
|
|
83
|
+
context: PersistedChannelContext;
|
|
84
|
+
/** On-chain deposit total (base units, string), when known. */
|
|
85
|
+
depositTotal?: string;
|
|
86
|
+
/** ISO timestamps. */
|
|
87
|
+
openedAt: string;
|
|
88
|
+
lastUsedAt: string;
|
|
89
|
+
}
|
|
90
|
+
/** The composite key a record is stored under. */
|
|
91
|
+
interface ChannelMapKey {
|
|
92
|
+
identity: string;
|
|
93
|
+
destination: string;
|
|
94
|
+
chain: string;
|
|
95
|
+
tokenNetwork: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* One entry of the client's nonce-watermark store (`channels.json`) —
|
|
99
|
+
* format DUPLICATED from `@toon-protocol/client`'s `JsonFileChannelStore`
|
|
100
|
+
* (`packages/client/src/channel/ChannelStore.ts`); keep in sync.
|
|
101
|
+
*/
|
|
102
|
+
interface WatermarkEntry {
|
|
103
|
+
nonce: number;
|
|
104
|
+
/** Cumulative claimed amount, base units (string-encoded bigint). */
|
|
105
|
+
cumulativeAmount: string;
|
|
106
|
+
/** Withdraw-flow timers, string-encoded unix SECONDS. */
|
|
107
|
+
closedAt?: string;
|
|
108
|
+
settleableAt?: string;
|
|
109
|
+
settledAt?: string;
|
|
110
|
+
}
|
|
111
|
+
/** The peer→channel map file is unreadable or malformed. */
|
|
112
|
+
declare class ChannelMapCorruptError extends Error {
|
|
113
|
+
readonly path: string;
|
|
114
|
+
constructor(path: string, detail: string);
|
|
115
|
+
}
|
|
116
|
+
/** The key fields of a full record. */
|
|
117
|
+
declare function recordKey(record: ChannelMapRecord): ChannelMapKey;
|
|
118
|
+
interface ChannelMapStoreOptions {
|
|
119
|
+
/** The rig peer→channel map file (`rig-channels.json`). */
|
|
120
|
+
mapPath: string;
|
|
121
|
+
/** The client's nonce-watermark store (`channels.json`). */
|
|
122
|
+
watermarkPath: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* File-backed peer→channel map + read/seed access to the client's nonce
|
|
126
|
+
* watermark store. Synchronous I/O (matches the client's `ChannelStore`
|
|
127
|
+
* surface); see the module doc for the locking and corruption contracts.
|
|
128
|
+
*/
|
|
129
|
+
declare class ChannelMapStore {
|
|
130
|
+
readonly mapPath: string;
|
|
131
|
+
readonly watermarkPath: string;
|
|
132
|
+
constructor(options: ChannelMapStoreOptions);
|
|
133
|
+
/** All recorded channels. @throws {ChannelMapCorruptError} */
|
|
134
|
+
list(): ChannelMapRecord[];
|
|
135
|
+
/**
|
|
136
|
+
* Recorded channels for one (identity, destination) pair — the resume
|
|
137
|
+
* candidates for a paid command. @throws {ChannelMapCorruptError}
|
|
138
|
+
*/
|
|
139
|
+
listFor(identity: string, destination: string): ChannelMapRecord[];
|
|
140
|
+
/**
|
|
141
|
+
* Record a (freshly opened) channel. Overwrites any previous record under
|
|
142
|
+
* the same (identity, destination, chain, tokenNetwork) key — the old
|
|
143
|
+
* channel is closed/stale by then; its claim watermark stays in the
|
|
144
|
+
* watermark store.
|
|
145
|
+
*/
|
|
146
|
+
record(record: Omit<ChannelMapRecord, 'openedAt' | 'lastUsedAt'> & Partial<Pick<ChannelMapRecord, 'openedAt' | 'lastUsedAt'>>): void;
|
|
147
|
+
/**
|
|
148
|
+
* Bump a record's `lastUsedAt` (and optionally its known on-chain deposit)
|
|
149
|
+
* after resuming it. Unknown keys are a no-op.
|
|
150
|
+
*/
|
|
151
|
+
touch(key: ChannelMapKey, update?: {
|
|
152
|
+
depositTotal?: string;
|
|
153
|
+
}): void;
|
|
154
|
+
/**
|
|
155
|
+
* Read one channel's nonce-watermark entry from the client's
|
|
156
|
+
* `channels.json` (undefined when the file or entry is missing).
|
|
157
|
+
* @throws {ChannelMapCorruptError} when the watermark file is unreadable.
|
|
158
|
+
*/
|
|
159
|
+
readWatermark(channelId: string): WatermarkEntry | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Seed a fresh channel's watermark entry (`nonce 0, cumulative 0`) so a
|
|
162
|
+
* later resume can tell "never claimed against" apart from "watermark
|
|
163
|
+
* lost". Never overwrites an existing entry.
|
|
164
|
+
*/
|
|
165
|
+
seedWatermark(channelId: string): void;
|
|
166
|
+
private readMap;
|
|
167
|
+
private writeMap;
|
|
168
|
+
private readWatermarkFile;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Where a channel sits in the withdraw journey, from its watermark timers —
|
|
172
|
+
* mirrors `ChannelManager.getChannelCloseState`. A missing entry reads as
|
|
173
|
+
* `open` (recorded channels are seeded at open time; a lost watermark file
|
|
174
|
+
* surfaces separately as unknown claim state).
|
|
175
|
+
*/
|
|
176
|
+
declare function channelStatus(entry: WatermarkEntry | undefined, nowSec?: number): 'open' | 'closing' | 'settleable' | 'settled';
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Dependency-light types for the client money lifecycle (#263): the seam
|
|
180
|
+
* between the money CLI commands (`rig fund` / `rig balance` /
|
|
181
|
+
* `rig channel open|close|settle`) and the standalone publisher's money
|
|
182
|
+
* operations.
|
|
183
|
+
*
|
|
184
|
+
* Lives beside channel-map.ts (not in standalone-publisher.ts) so
|
|
185
|
+
* `cli/standalone-context.ts` — which command modules `import type` without
|
|
186
|
+
* dragging in `@toon-protocol/client` — can reference these shapes: the
|
|
187
|
+
* publisher module statically imports the heavy client package, this module
|
|
188
|
+
* imports nothing but the (node:fs-only) channel map types.
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* One on-chain wallet token balance — structural twin of
|
|
193
|
+
* `@toon-protocol/client`'s `WalletBalance` (`balance/WalletBalanceReader.ts`,
|
|
194
|
+
* not exported from the package root); keep in sync.
|
|
195
|
+
*/
|
|
196
|
+
interface WalletBalanceInfo {
|
|
197
|
+
chain: 'evm' | 'solana' | 'mina';
|
|
198
|
+
address: string;
|
|
199
|
+
/** Base-unit integer, decimal string. */
|
|
200
|
+
amount: string;
|
|
201
|
+
/** Token symbol, when resolved (e.g. `'USDC'`, `'MINA'`). */
|
|
202
|
+
asset?: string;
|
|
203
|
+
/** Token decimals, when resolved. */
|
|
204
|
+
assetScale?: number;
|
|
205
|
+
}
|
|
206
|
+
/** Receipt of an explicit `rig channel open` (fresh open OR resume). */
|
|
207
|
+
interface ChannelOpenOutcome {
|
|
208
|
+
channelId: string;
|
|
209
|
+
/** True when the recorded channel was resumed (no on-chain open). */
|
|
210
|
+
resumed: boolean;
|
|
211
|
+
/** ILP anchor destination the channel is keyed by in the map. */
|
|
212
|
+
destination: string;
|
|
213
|
+
/** Negotiated settlement chain, when recorded (e.g. `evm:31337`). */
|
|
214
|
+
chain?: string;
|
|
215
|
+
/** Registered peer id, when recorded. */
|
|
216
|
+
peerId?: string;
|
|
217
|
+
/** On-chain deposit total (base units), when known. */
|
|
218
|
+
depositTotal?: string;
|
|
219
|
+
/** Extra collateral added by `--deposit` (base units), when any. */
|
|
220
|
+
depositAdded?: string;
|
|
221
|
+
/** Tx hash of the `--deposit` top-up, when any. */
|
|
222
|
+
depositTxHash?: string;
|
|
223
|
+
}
|
|
224
|
+
/** Receipt of a channel close (start of the settlement challenge window). */
|
|
225
|
+
interface ChannelCloseOutcome {
|
|
226
|
+
channelId: string;
|
|
227
|
+
txHash?: string;
|
|
228
|
+
/** Unix SECONDS (string-encoded bigint) the close landed on-chain. */
|
|
229
|
+
closedAt: string;
|
|
230
|
+
/** Unix SECONDS (string-encoded bigint) settle becomes possible. */
|
|
231
|
+
settleableAt: string;
|
|
232
|
+
}
|
|
233
|
+
/** Receipt of a channel settle (collateral released). */
|
|
234
|
+
interface ChannelSettleOutcome {
|
|
235
|
+
channelId: string;
|
|
236
|
+
txHash?: string;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* The money operations a standalone context exposes to the CLI commands.
|
|
240
|
+
* Implemented by `StandalonePublisher` (guard + client start shared with the
|
|
241
|
+
* paid-write path); tests inject fakes.
|
|
242
|
+
*/
|
|
243
|
+
interface StandaloneMoneyOps {
|
|
244
|
+
/**
|
|
245
|
+
* Explicitly open (or resume) the payment channel for the context's
|
|
246
|
+
* channel anchor — the SAME resume-or-open path lazy paid writes use, so
|
|
247
|
+
* the result lands in the #262 peer→channel map. `deposit` adds that much
|
|
248
|
+
* extra collateral (base units) after the open/resume.
|
|
249
|
+
*/
|
|
250
|
+
openChannel(opts?: {
|
|
251
|
+
deposit?: bigint;
|
|
252
|
+
}): Promise<ChannelOpenOutcome>;
|
|
253
|
+
/** Close a recorded channel — starts the on-chain challenge window. */
|
|
254
|
+
closeChannel(record: ChannelMapRecord): Promise<ChannelCloseOutcome>;
|
|
255
|
+
/** Settle a closed channel after its challenge window — releases funds. */
|
|
256
|
+
settleChannel(record: ChannelMapRecord): Promise<ChannelSettleOutcome>;
|
|
257
|
+
/**
|
|
258
|
+
* On-chain wallet balances for the identity's configured chains — a FREE
|
|
259
|
+
* read (no client start, no nonce guard, no uplink). Best-effort per chain.
|
|
260
|
+
*/
|
|
261
|
+
walletBalances(): Promise<WalletBalanceInfo[]>;
|
|
262
|
+
}
|
|
263
|
+
|
|
5
264
|
/**
|
|
6
265
|
* StandalonePublisher — impl 2 of the {@link Publisher} seam (#228): an
|
|
7
266
|
* EMBEDDED ToonClient constructed from the caller's config (mnemonic +
|
|
@@ -27,6 +286,12 @@ import '@toon-protocol/core/nip34';
|
|
|
27
286
|
* guard (./nonce-guard.ts): refuse if a toon-clientd holds this identity,
|
|
28
287
|
* and hold an exclusive per-pubkey lockfile against other standalone
|
|
29
288
|
* processes for the lifetime of this publisher.
|
|
289
|
+
*
|
|
290
|
+
* Channel REUSE (#262): with a `channelMap` configured, start() resumes the
|
|
291
|
+
* channel recorded for (identity, channel anchor) — `trackChannel` rehydrates
|
|
292
|
+
* the cumulative-claim watermark from the client's channels.json — and
|
|
293
|
+
* records any fresh lazy open, so sequential CLI invocations share ONE
|
|
294
|
+
* on-chain channel instead of stranding a deposit per run (./channel-map.ts).
|
|
30
295
|
*/
|
|
31
296
|
|
|
32
297
|
/** A fully-signed Nostr event (structural subset of nostr-tools' NostrEvent). */
|
|
@@ -53,6 +318,34 @@ interface ToonClientLike {
|
|
|
53
318
|
ilpAmount?: bigint;
|
|
54
319
|
proxyPath?: string;
|
|
55
320
|
}): Promise<PublishEventResult>;
|
|
321
|
+
/** On-chain deposit total for a tracked channel (channel-map bookkeeping). */
|
|
322
|
+
getChannelDepositTotal?(channelId: string): bigint;
|
|
323
|
+
/** Re-read a RESUMED channel's on-chain deposit (persisted state omits it). */
|
|
324
|
+
rehydrateChannelDeposit?(channelId: string, opts: {
|
|
325
|
+
chain: string;
|
|
326
|
+
tokenNetworkAddress: string;
|
|
327
|
+
}): Promise<bigint | undefined>;
|
|
328
|
+
/** Deposit extra collateral (base-unit delta) into an open channel. */
|
|
329
|
+
depositToChannel?(channelId: string, amount: string | bigint): Promise<{
|
|
330
|
+
channelId: string;
|
|
331
|
+
txHash?: string;
|
|
332
|
+
depositTotal: string;
|
|
333
|
+
}>;
|
|
334
|
+
/** Close a channel — starts the settlement challenge window (on-chain). */
|
|
335
|
+
closeChannel?(channelId: string): Promise<{
|
|
336
|
+
channelId: string;
|
|
337
|
+
txHash?: string;
|
|
338
|
+
/** Unix SECONDS, string-encoded. */
|
|
339
|
+
closedAt: string;
|
|
340
|
+
settleableAt: string;
|
|
341
|
+
}>;
|
|
342
|
+
/** Settle a closed channel after its window — releases funds (on-chain). */
|
|
343
|
+
settleChannel?(channelId: string): Promise<{
|
|
344
|
+
channelId: string;
|
|
345
|
+
txHash?: string;
|
|
346
|
+
}>;
|
|
347
|
+
/** Free on-chain wallet-balance read (works on an UNSTARTED client). */
|
|
348
|
+
getBalances?(): Promise<WalletBalanceInfo[]>;
|
|
56
349
|
}
|
|
57
350
|
interface StandalonePublisherOptions {
|
|
58
351
|
/**
|
|
@@ -89,6 +382,28 @@ interface StandalonePublisherOptions {
|
|
|
89
382
|
lockDir?: string;
|
|
90
383
|
/** Fetch impl for the daemon probe (tests). */
|
|
91
384
|
fetchImpl?: typeof fetch;
|
|
385
|
+
/**
|
|
386
|
+
* Peer→channel map store (#262): start() resumes the channel recorded for
|
|
387
|
+
* (identity, channel anchor) instead of opening a fresh one, and records
|
|
388
|
+
* any fresh lazy open for the next invocation. Absent (embedded callers
|
|
389
|
+
* managing their own channel lifecycle): the historical behaviour — open
|
|
390
|
+
* lazily every run, record nothing.
|
|
391
|
+
*/
|
|
392
|
+
channelMap?: ChannelMapStore;
|
|
393
|
+
/**
|
|
394
|
+
* Per-chain settlement parameters to BACK-FILL into the client's peer
|
|
395
|
+
* negotiations after start (#264/#260): peers whose kind:10032 announce
|
|
396
|
+
* carries no `tokenNetworks`/`preferredTokens` negotiate with those fields
|
|
397
|
+
* empty, and the on-chain channel open then fails ("tokenNetwork address
|
|
398
|
+
* is required"). Values here never override what a peer DID announce —
|
|
399
|
+
* they only fill gaps, keyed by the negotiated chain id.
|
|
400
|
+
*/
|
|
401
|
+
negotiationFallbacks?: {
|
|
402
|
+
tokenNetworks?: Record<string, string>;
|
|
403
|
+
preferredTokens?: Record<string, string>;
|
|
404
|
+
};
|
|
405
|
+
/** Sink for non-fatal channel-persistence warnings (default: stderr). */
|
|
406
|
+
warn?: (line: string) => void;
|
|
92
407
|
}
|
|
93
408
|
/** A relay/store rejected a paid write (fee NOT spent iff the claim failed too). */
|
|
94
409
|
declare class StandalonePublishError extends Error {
|
|
@@ -124,9 +439,18 @@ declare class StandalonePublisher implements Publisher {
|
|
|
124
439
|
private readonly daemonPort;
|
|
125
440
|
private readonly lockDir;
|
|
126
441
|
private readonly fetchImpl;
|
|
442
|
+
private readonly channelMap;
|
|
443
|
+
/** ILP anchor the channel is keyed by in the map (peer/apex destination). */
|
|
444
|
+
private readonly channelAnchor;
|
|
445
|
+
private readonly negotiationFallbacks;
|
|
446
|
+
private readonly warn;
|
|
127
447
|
private lock;
|
|
128
448
|
private channelId;
|
|
129
449
|
private readyPromise;
|
|
450
|
+
/** Guard + client start only (no channel) — see {@link startClientOnly}. */
|
|
451
|
+
private clientReadyPromise;
|
|
452
|
+
/** True when the last start() RESUMED the recorded channel (#263). */
|
|
453
|
+
private lastOpenResumed;
|
|
130
454
|
constructor(options: StandalonePublisherOptions);
|
|
131
455
|
/** Hex Nostr pubkey of the embedded identity (available before start). */
|
|
132
456
|
getPublicKey(): string;
|
|
@@ -136,9 +460,86 @@ declare class StandalonePublisher implements Publisher {
|
|
|
136
460
|
* eagerly to fail fast. Idempotent.
|
|
137
461
|
*/
|
|
138
462
|
start(): Promise<void>;
|
|
139
|
-
|
|
463
|
+
/**
|
|
464
|
+
* Run the nonce guard and start the embedded client WITHOUT touching the
|
|
465
|
+
* payment channel (#263): `channel close`/`settle` operate on a RECORDED
|
|
466
|
+
* channel and must never open a fresh one as a side effect of starting.
|
|
467
|
+
* Idempotent; `start()` layers the channel open/resume on top of this.
|
|
468
|
+
*/
|
|
469
|
+
startClientOnly(): Promise<void>;
|
|
470
|
+
private doStartClient;
|
|
471
|
+
/**
|
|
472
|
+
* Back-fill negotiated peer metadata the announce did not carry
|
|
473
|
+
* (#264/#260 root cause 3): after the client's bootstrap negotiation, any
|
|
474
|
+
* peer negotiation missing `tokenNetwork`/`tokenAddress` gets the derived
|
|
475
|
+
* per-chain fallback for its negotiated chain, BEFORE the lazy channel
|
|
476
|
+
* open reads them. Announced values are never overridden.
|
|
477
|
+
*/
|
|
478
|
+
private applyNegotiationFallbacks;
|
|
479
|
+
/**
|
|
480
|
+
* Open the payment channel — or, when the channel map has a record for
|
|
481
|
+
* (identity, anchor), RESUME the recorded on-chain channel (#262).
|
|
482
|
+
*
|
|
483
|
+
* Resume seeds the client's ChannelManager (`trackChannel` rehydrates the
|
|
484
|
+
* cumulative-claim watermark from channels.json; `peerChannels` makes the
|
|
485
|
+
* subsequent `openChannel` return the same id instead of opening on-chain).
|
|
486
|
+
* A fresh open is RECORDED so the next invocation resumes it. A corrupt map
|
|
487
|
+
* file throws BEFORE anything is opened — never a silent duplicate open.
|
|
488
|
+
*/
|
|
489
|
+
private openOrResumeChannel;
|
|
490
|
+
/**
|
|
491
|
+
* Try to resume one recorded channel: the first candidate whose peer is
|
|
492
|
+
* still negotiated on the SAME chain + tokenNetwork and whose watermark
|
|
493
|
+
* does not show it closed/settled. Returns the resumed record, if any.
|
|
494
|
+
*/
|
|
495
|
+
private resumeRecordedChannel;
|
|
496
|
+
/** Record a freshly opened channel (+ seed its claim watermark at 0/0). */
|
|
497
|
+
private recordOpenedChannel;
|
|
140
498
|
/** Release the identity lock and stop the embedded client (if we own it). */
|
|
141
499
|
stop(): Promise<void>;
|
|
500
|
+
/**
|
|
501
|
+
* Explicit `rig channel open`: the SAME resume-or-open path the lazy paid
|
|
502
|
+
* writes use (guard → start → resume the recorded channel or open + record
|
|
503
|
+
* a fresh one), surfaced with a receipt — plus an optional extra collateral
|
|
504
|
+
* deposit on top of the open/resume.
|
|
505
|
+
*/
|
|
506
|
+
openChannelExplicit(opts?: {
|
|
507
|
+
/** Extra collateral to deposit AFTER the open/resume (base units). */
|
|
508
|
+
deposit?: bigint;
|
|
509
|
+
}): Promise<ChannelOpenOutcome>;
|
|
510
|
+
/**
|
|
511
|
+
* Adopt a RECORDED channel into the running client so on-chain close/
|
|
512
|
+
* settle/deposit can act on it: `trackChannel` rehydrates the claim
|
|
513
|
+
* watermark + withdraw timers from channels.json, `peerChannels` binds the
|
|
514
|
+
* peer, and the on-chain client's context cache is re-seeded (it only
|
|
515
|
+
* learns context at open time — a resumed channel would otherwise throw
|
|
516
|
+
* "No on-chain context").
|
|
517
|
+
*/
|
|
518
|
+
private adoptRecordedChannel;
|
|
519
|
+
/**
|
|
520
|
+
* Close a recorded channel: starts the on-chain settlement challenge
|
|
521
|
+
* window. The client persists `closedAt`/`settleableAt` into the claim
|
|
522
|
+
* watermark store, which is exactly where `rig channel list`/`balance`
|
|
523
|
+
* derive the closing/settleable/settled status from. Guard + client start,
|
|
524
|
+
* but NEVER a channel open ({@link startClientOnly}).
|
|
525
|
+
*/
|
|
526
|
+
closeRecordedChannel(record: ChannelMapRecord): Promise<ChannelCloseOutcome>;
|
|
527
|
+
/**
|
|
528
|
+
* Settle a recorded channel after its challenge window — releases the
|
|
529
|
+
* remaining collateral. The client enforces the `now >= settleableAt` time
|
|
530
|
+
* guard BEFORE spending gas (a too-early call throws its retryable
|
|
531
|
+
* SettleTooEarlyError) and persists `settledAt` into the watermark store.
|
|
532
|
+
*/
|
|
533
|
+
settleRecordedChannel(record: ChannelMapRecord): Promise<ChannelSettleOutcome>;
|
|
534
|
+
/**
|
|
535
|
+
* On-chain wallet balances for the embedded identity — a FREE read on the
|
|
536
|
+
* UNSTARTED client (no nonce guard, no uplink, no channel): the client
|
|
537
|
+
* reads the settlement chain its channels actually use (its EVM key is
|
|
538
|
+
* derived at construction; Solana/Mina keys only exist after a start, so
|
|
539
|
+
* those chains appear once a start-requiring command ran — same
|
|
540
|
+
* best-effort contract as the client's own getBalances).
|
|
541
|
+
*/
|
|
542
|
+
readWalletBalances(): Promise<WalletBalanceInfo[]>;
|
|
142
543
|
/**
|
|
143
544
|
* Fee rates for `planPush` estimation: the flat per-event fee and the
|
|
144
545
|
* per-byte upload rate this publisher pays (daemon `feePerEvent` and seed
|
|
@@ -269,4 +670,4 @@ declare class NonceLock {
|
|
|
269
670
|
release(): void;
|
|
270
671
|
}
|
|
271
672
|
|
|
272
|
-
export { type AcquireLockOptions, type CheckDaemonOptions, DEFAULT_DAEMON_PORT, DaemonIdentityConflictError, NonceLock, type SignedNostrEvent, StandaloneLockError, StandalonePublishError, StandalonePublisher, type StandalonePublisherOptions, type ToonClientLike, checkDaemonIdentity, defaultDaemonPort, defaultLockDir, deriveRouteDestinations, extractArweaveTxId };
|
|
673
|
+
export { type AcquireLockOptions, type ChannelCloseOutcome, ChannelMapCorruptError, type ChannelMapKey, type ChannelMapRecord, ChannelMapStore, type ChannelMapStoreOptions, type ChannelOpenOutcome, type ChannelSettleOutcome, type CheckDaemonOptions, DEFAULT_DAEMON_PORT, DaemonIdentityConflictError, NonceLock, type PersistedChannelContext, RIG_CHANNEL_MAP_FILENAME, type SignedNostrEvent, StandaloneLockError, type StandaloneMoneyOps, StandalonePublishError, StandalonePublisher, type StandalonePublisherOptions, type ToonClientLike, type WalletBalanceInfo, type WatermarkEntry, channelStatus, checkDaemonIdentity, defaultDaemonPort, defaultLockDir, deriveRouteDestinations, extractArweaveTxId, recordKey, resolveChannelPaths };
|
package/dist/standalone/index.js
CHANGED
|
@@ -10,19 +10,33 @@ import {
|
|
|
10
10
|
defaultLockDir,
|
|
11
11
|
deriveRouteDestinations,
|
|
12
12
|
extractArweaveTxId
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-3EKP7PMM.js";
|
|
14
|
+
import {
|
|
15
|
+
ChannelMapCorruptError,
|
|
16
|
+
ChannelMapStore,
|
|
17
|
+
RIG_CHANNEL_MAP_FILENAME,
|
|
18
|
+
channelStatus,
|
|
19
|
+
recordKey,
|
|
20
|
+
resolveChannelPaths
|
|
21
|
+
} from "../chunk-O6TXHKWG.js";
|
|
14
22
|
import "../chunk-X2CZPPDM.js";
|
|
15
23
|
export {
|
|
24
|
+
ChannelMapCorruptError,
|
|
25
|
+
ChannelMapStore,
|
|
16
26
|
DEFAULT_DAEMON_PORT,
|
|
17
27
|
DaemonIdentityConflictError,
|
|
18
28
|
NonceLock,
|
|
29
|
+
RIG_CHANNEL_MAP_FILENAME,
|
|
19
30
|
StandaloneLockError,
|
|
20
31
|
StandalonePublishError,
|
|
21
32
|
StandalonePublisher,
|
|
33
|
+
channelStatus,
|
|
22
34
|
checkDaemonIdentity,
|
|
23
35
|
defaultDaemonPort,
|
|
24
36
|
defaultLockDir,
|
|
25
37
|
deriveRouteDestinations,
|
|
26
|
-
extractArweaveTxId
|
|
38
|
+
extractArweaveTxId,
|
|
39
|
+
recordKey,
|
|
40
|
+
resolveChannelPaths
|
|
27
41
|
};
|
|
28
42
|
//# sourceMappingURL=index.js.map
|