@toon-protocol/rig 3.6.0 → 4.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 +112 -153
- package/dist/{chunk-HJDPM37T.js → chunk-7VCVR4GK.js} +12 -8
- package/dist/{chunk-HJDPM37T.js.map → chunk-7VCVR4GK.js.map} +1 -1
- package/dist/chunk-CDSFVZDV.js +290 -0
- package/dist/chunk-CDSFVZDV.js.map +1 -0
- package/dist/{chunk-B5ISARMU.js → chunk-GVXBUL3C.js} +15 -2
- package/dist/chunk-GVXBUL3C.js.map +1 -0
- package/dist/chunk-LTFMPOHU.js +194 -0
- package/dist/chunk-LTFMPOHU.js.map +1 -0
- package/dist/{chunk-2KJJ7LSO.js → chunk-NCEMQUPA.js} +40 -2
- package/dist/chunk-NCEMQUPA.js.map +1 -0
- package/dist/{chunk-LCYCKWAT.js → chunk-YZRR2UO6.js} +86 -5
- package/dist/chunk-YZRR2UO6.js.map +1 -0
- package/dist/cli/rig.js +631 -568
- package/dist/cli/rig.js.map +1 -1
- package/dist/index.d.ts +10 -115
- package/dist/index.js +16 -122
- package/dist/index.js.map +1 -1
- package/dist/{publisher-BFcnZeJI.d.ts → publisher-DMJ06cuL.d.ts} +98 -2
- package/dist/standalone/index.d.ts +241 -438
- package/dist/standalone/index.js +19 -11
- package/dist/standalone-mode-KTYRTUS6.js +390 -0
- package/dist/standalone-mode-KTYRTUS6.js.map +1 -0
- package/package.json +7 -5
- package/dist/chunk-2KJJ7LSO.js.map +0 -1
- package/dist/chunk-B5ISARMU.js.map +0 -1
- package/dist/chunk-IZ6KLYQ6.js +0 -724
- package/dist/chunk-IZ6KLYQ6.js.map +0 -1
- package/dist/chunk-LCYCKWAT.js.map +0 -1
- package/dist/chunk-PWNZWQOH.js +0 -404
- package/dist/chunk-PWNZWQOH.js.map +0 -1
- package/dist/chunk-UZZ2RN7A.js +0 -469
- package/dist/chunk-UZZ2RN7A.js.map +0 -1
- package/dist/network-bootstrap-27FYE3N7.js +0 -40
- package/dist/network-bootstrap-27FYE3N7.js.map +0 -1
- package/dist/standalone-mode-5MNNJC2D.js +0 -928
- package/dist/standalone-mode-5MNNJC2D.js.map +0 -1
|
@@ -1,8 +1,178 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { extractArweaveTxId } from '@toon-protocol/client';
|
|
3
|
-
import { U as UnsignedEvent, P as Publisher, F as FeeRates, G as GitObjectUpload, a as UploadReceipt, B as BlobUpload, b as PublishReceipt } from '../publisher-BFcnZeJI.js';
|
|
1
|
+
import { P as Publisher, F as FeeRates, G as GitObjectUpload, U as UploadReceipt, B as BlobUpload, S as StoreJobRequest, a as StoreJobResponse, b as UnsignedEvent, c as PublishReceipt } from '../publisher-DMJ06cuL.js';
|
|
4
2
|
import '@toon-protocol/core/nip34';
|
|
5
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The paid write path on `@toon-protocol/client` 2.x — a {@link Publisher}
|
|
6
|
+
* that pays a TOON connector per request.
|
|
7
|
+
*
|
|
8
|
+
* Everything a paid command needs comes from one connector URL: the client
|
|
9
|
+
* reads the node's own `GET /ilp` (addresses, prices, settlement chains,
|
|
10
|
+
* sealing key — connector ADR 0050), opens or adopts a payment channel, and
|
|
11
|
+
* pays each request with a signed claim. There is no relay to discover peers
|
|
12
|
+
* on (kind:10032 was removed by ADR 0046) and no topology to negotiate: a
|
|
13
|
+
* destination is a route the node prices, and `send()` pays what the route
|
|
14
|
+
* costs — including the per-kibibyte part of an ADR 0065 schedule, which the
|
|
15
|
+
* client works out from the sealed payload so this publisher never has to.
|
|
16
|
+
*
|
|
17
|
+
* Three request shapes, all ordinary paid POSTs:
|
|
18
|
+
*
|
|
19
|
+
* 1. `publishEvent` — a NIP-34 event signed with the OWNER's Nostr key,
|
|
20
|
+
* sent as `{ event }` to the publish route; the relay answers
|
|
21
|
+
* `{ eventId, storedAt, payment? }`.
|
|
22
|
+
* 2. `uploadGitObject` / `uploadBlob` — a kind:5094 store job carrying the
|
|
23
|
+
* bytes base64 in an `i` tag; the store answers the Arweave tx id.
|
|
24
|
+
* 3. `submitStoreJob` — a kind:5095 / 5096 job with `param` tags; the
|
|
25
|
+
* DVM's answer comes back as data, refusal included (ADR 0020: an answer
|
|
26
|
+
* is an answer, and the payer was charged for it).
|
|
27
|
+
*
|
|
28
|
+
* The store route may terminate on a different node than the one addressed
|
|
29
|
+
* (the edge forwards it). Then the payload must be sealed to THAT node's
|
|
30
|
+
* identity — `sealTo` — and, when the store node holds its own channel, paid
|
|
31
|
+
* through its own client. Both are options here; the common single-node case
|
|
32
|
+
* needs neither.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/** A paid request, as `ToonClient.send` takes it. */
|
|
36
|
+
interface PaidRequest {
|
|
37
|
+
method?: string;
|
|
38
|
+
target?: string;
|
|
39
|
+
headers?: Record<string, string> | [string, string][];
|
|
40
|
+
body?: string | Uint8Array | object;
|
|
41
|
+
}
|
|
42
|
+
interface PaidSendOptions {
|
|
43
|
+
/** The terminating connector's `GET /ilp` URL or raw key, on a forwarded route. */
|
|
44
|
+
sealTo?: string | Uint8Array;
|
|
45
|
+
timeoutMs?: number;
|
|
46
|
+
}
|
|
47
|
+
interface PaidFulfilled {
|
|
48
|
+
fulfilled: true;
|
|
49
|
+
status: number;
|
|
50
|
+
body: Uint8Array;
|
|
51
|
+
/** What this request paid; absent on a route priced at zero. */
|
|
52
|
+
claim?: {
|
|
53
|
+
amount: bigint;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
interface PaidRefused {
|
|
57
|
+
fulfilled: false;
|
|
58
|
+
code: string;
|
|
59
|
+
message: string;
|
|
60
|
+
refusedBy?: string;
|
|
61
|
+
}
|
|
62
|
+
type PaidSendResult = PaidFulfilled | PaidRefused;
|
|
63
|
+
/** The route terms a connector publishes: a base price and an optional slope. */
|
|
64
|
+
interface RouteTerms {
|
|
65
|
+
price: bigint;
|
|
66
|
+
pricePerKib?: bigint;
|
|
67
|
+
}
|
|
68
|
+
/** The slice of `ToonClient` (2.x) this publisher needs. */
|
|
69
|
+
interface PaidClientLike {
|
|
70
|
+
send(destination: string, request: PaidRequest, options?: PaidSendOptions): Promise<PaidSendResult>;
|
|
71
|
+
/** The node's terms for a destination, or `null` when it prices no such route. */
|
|
72
|
+
routePrice(destination: string): Promise<RouteTerms | null>;
|
|
73
|
+
}
|
|
74
|
+
/** One leg of the write path: who pays, where to, and whom to seal to. */
|
|
75
|
+
interface PaidLeg {
|
|
76
|
+
client: PaidClientLike;
|
|
77
|
+
destination: string;
|
|
78
|
+
sealTo?: string | Uint8Array;
|
|
79
|
+
}
|
|
80
|
+
interface ConnectorPublisherOptions {
|
|
81
|
+
/** Pays the publish route and signs nothing — the Nostr key below signs. */
|
|
82
|
+
publish: PaidLeg;
|
|
83
|
+
/** Pays the store route (often the same client as `publish`). */
|
|
84
|
+
store: PaidLeg;
|
|
85
|
+
/** The owner's Nostr secret key: signs every event this publisher sends. */
|
|
86
|
+
nostrSecretKey: Uint8Array;
|
|
87
|
+
/**
|
|
88
|
+
* A configured per-event fee. Informational floor only: the connector's
|
|
89
|
+
* published price for the publish route wins when it is higher, and the
|
|
90
|
+
* client pays that price whatever this says.
|
|
91
|
+
*/
|
|
92
|
+
eventFee?: bigint;
|
|
93
|
+
/** Per-packet timeout for uploads (the store's Arweave round trip). */
|
|
94
|
+
uploadTimeoutMs?: number;
|
|
95
|
+
warn?(line: string): void;
|
|
96
|
+
}
|
|
97
|
+
declare class ConnectorPublishError extends Error {
|
|
98
|
+
constructor(message: string);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Read the Arweave tx id out of a store's kind:5094 answer.
|
|
102
|
+
*
|
|
103
|
+
* The store answers one of two ways — `{ txId }` as JSON, or the bare id
|
|
104
|
+
* base64 in `data` — and refuses with `{ accept: false, error }`. A non-2xx
|
|
105
|
+
* status is a refusal too; both are thrown, because an upload without an id
|
|
106
|
+
* is an upload that did not happen (even though the packet was paid for).
|
|
107
|
+
*/
|
|
108
|
+
declare function extractArweaveTxId(status: number, body: Uint8Array): string;
|
|
109
|
+
declare class ConnectorPublisher implements Publisher {
|
|
110
|
+
private readonly publish;
|
|
111
|
+
private readonly store;
|
|
112
|
+
private readonly nostrSecretKey;
|
|
113
|
+
private readonly configuredEventFee;
|
|
114
|
+
private readonly uploadTimeoutMs;
|
|
115
|
+
private readonly warn;
|
|
116
|
+
private rates;
|
|
117
|
+
constructor(options: ConnectorPublisherOptions);
|
|
118
|
+
/** Where events go, and where objects go. */
|
|
119
|
+
get destinations(): {
|
|
120
|
+
publish: string;
|
|
121
|
+
store: string;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* The two routes' published terms, read once per publisher. A route the
|
|
125
|
+
* node does not price is a configuration error and says which knob to fix.
|
|
126
|
+
*/
|
|
127
|
+
getFeeRates(): Promise<FeeRates>;
|
|
128
|
+
private readFeeRates;
|
|
129
|
+
private sign;
|
|
130
|
+
/** One paid kind:5094 write; returns the tx id and what the claim spent. */
|
|
131
|
+
private storeWrite;
|
|
132
|
+
uploadGitObject(upload: GitObjectUpload): Promise<UploadReceipt>;
|
|
133
|
+
uploadBlob(upload: BlobUpload): Promise<UploadReceipt>;
|
|
134
|
+
/**
|
|
135
|
+
* One NIP-90 job to the store node's DVM, over the paid path. A refusal is
|
|
136
|
+
* returned, not thrown: `accept: false` and a non-2xx status are the
|
|
137
|
+
* answer's content, and the payer was charged for the answer (ADR 0020).
|
|
138
|
+
*/
|
|
139
|
+
submitStoreJob(request: StoreJobRequest): Promise<StoreJobResponse>;
|
|
140
|
+
/**
|
|
141
|
+
* Sign the event with the owner's key and pay to publish it. `relayUrls`
|
|
142
|
+
* is the seam's plural surface: this publisher routes to one configured
|
|
143
|
+
* destination, so more than one relay is refused rather than half-done.
|
|
144
|
+
*/
|
|
145
|
+
publishEvent(event: UnsignedEvent, relayUrls: string[]): Promise<PublishReceipt>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The Nostr signing key rig derives from a BIP-39 phrase.
|
|
150
|
+
*
|
|
151
|
+
* `@toon-protocol/client` 2.x is a pure payer and carries no Nostr identity
|
|
152
|
+
* (its own words), so the derivation that lived in the 0.x client moves here,
|
|
153
|
+
* unchanged: `m/44'/1237'/0'/0/<accountIndex>`. Unchanged matters — this is
|
|
154
|
+
* the key every existing rig repo is owned by (`toon.owner`, the kind:30617
|
|
155
|
+
* author), and it is also the secp256k1 key the client reads a phrase's EVM
|
|
156
|
+
* account from under `keyDerivation: 'legacy'`, so one phrase still yields one
|
|
157
|
+
* author AND the wallet its channels were funded at.
|
|
158
|
+
*/
|
|
159
|
+
/** A BIP-32 non-hardened child index fits in 31 bits. */
|
|
160
|
+
declare const MAX_ACCOUNT_INDEX = 2147483647;
|
|
161
|
+
/** The path rig has always derived its Nostr key at. */
|
|
162
|
+
declare function nostrDerivationPath(accountIndex?: number): string;
|
|
163
|
+
interface NostrKey {
|
|
164
|
+
/** 32-byte secp256k1 secret. */
|
|
165
|
+
secretKey: Uint8Array;
|
|
166
|
+
/** 32-byte x-only public key, hex. */
|
|
167
|
+
pubkey: string;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Derive the Nostr key of a phrase at an account index.
|
|
171
|
+
*
|
|
172
|
+
* @throws when the index is out of range or the phrase yields no key.
|
|
173
|
+
*/
|
|
174
|
+
declare function deriveNostrKeyFromMnemonic(mnemonic: string, accountIndex?: number): NostrKey;
|
|
175
|
+
|
|
6
176
|
/**
|
|
7
177
|
* Peer→channel map for the STANDALONE embedded publisher (#262).
|
|
8
178
|
*
|
|
@@ -32,6 +202,15 @@ import '@toon-protocol/core/nip34';
|
|
|
32
202
|
* whole lifetime — the same guard that serializes the claim watermark also
|
|
33
203
|
* serializes this file for one identity. `rig channel list` reads only.
|
|
34
204
|
*
|
|
205
|
+
* COUNTERPARTY: the key names a ROUTE, not a node — an ILP name can change
|
|
206
|
+
* hands (the devnet apex `g.toon` was retired and another node took over
|
|
207
|
+
* `g.toon.relay`). A record therefore also carries the counterparty
|
|
208
|
+
* settlement address it was opened against (`context.recipient`), which is
|
|
209
|
+
* re-checked against the destination's announced address before every resume
|
|
210
|
+
* ({@link counterpartyMatch}); a rotated counterparty
|
|
211
|
+
* {@link ChannelMapStore.supersede}s the record instead of signing claims a
|
|
212
|
+
* connector with no record of that channel refuses (`F01`).
|
|
213
|
+
*
|
|
35
214
|
* CORRUPTION: an unreadable/invalid map file is a hard
|
|
36
215
|
* {@link ChannelMapCorruptError} — surfaced BEFORE any on-chain open — never
|
|
37
216
|
* an empty fallback. Falling back to "no channels" would silently open (and
|
|
@@ -87,6 +266,15 @@ interface ChannelMapRecord {
|
|
|
87
266
|
/** ISO timestamps. */
|
|
88
267
|
openedAt: string;
|
|
89
268
|
lastUsedAt: string;
|
|
269
|
+
/**
|
|
270
|
+
* ISO timestamp this record was RETIRED from the resume path because the
|
|
271
|
+
* destination now announces a different settlement address than the channel
|
|
272
|
+
* was opened against (see {@link counterpartyMatch} /
|
|
273
|
+
* {@link ChannelMapStore.supersede}). A superseded record is never resumed
|
|
274
|
+
* again, but stays in {@link ChannelMapStore.list} so `rig channel
|
|
275
|
+
* list/close/settle` can still reclaim whatever it holds on-chain.
|
|
276
|
+
*/
|
|
277
|
+
supersededAt?: string;
|
|
90
278
|
}
|
|
91
279
|
/** The composite key a record is stored under. */
|
|
92
280
|
interface ChannelMapKey {
|
|
@@ -114,6 +302,35 @@ declare class ChannelMapCorruptError extends Error {
|
|
|
114
302
|
readonly path: string;
|
|
115
303
|
constructor(path: string, detail: string);
|
|
116
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Compare settlement addresses. EVM addresses travel in mixed checksum case
|
|
307
|
+
* (an announce may say `0xF29f…` where the record says `0xf29f…`) and are
|
|
308
|
+
* compared case-insensitively; anything else (base58 Solana, base58check
|
|
309
|
+
* Mina) is case-SIGNIFICANT and compared verbatim.
|
|
310
|
+
*/
|
|
311
|
+
declare function sameSettlementAddress(a: string, b: string): boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Does a recorded channel still belong to the counterparty the destination
|
|
314
|
+
* announces TODAY?
|
|
315
|
+
*
|
|
316
|
+
* The map key is `identity|destination|chain|tokenNetwork` — it carries no
|
|
317
|
+
* counterparty. When the node terminating an ILP name is REPLACED (the devnet
|
|
318
|
+
* apex `g.toon` was retired and another node took over `g.toon.relay`), all
|
|
319
|
+
* four key fields still match, so rig resumed a channel opened against the
|
|
320
|
+
* old node and signed claims against it. The new connector holds no record of
|
|
321
|
+
* that channel and refuses every packet: `F01 - claim rejected: names a
|
|
322
|
+
* channel this connector has no record of`. Every paid write failed until the
|
|
323
|
+
* cache entry was deleted by hand.
|
|
324
|
+
*
|
|
325
|
+
* - `'match'` — same counterparty, safe to resume.
|
|
326
|
+
* - `'mismatch'` — the counterparty rotated: the record must be superseded and
|
|
327
|
+
* the channel re-resolved.
|
|
328
|
+
* - `'unrecorded'` — nothing to compare (a record written before this field
|
|
329
|
+
* was validated, or a peer that announced no settlement address). Resume is
|
|
330
|
+
* allowed and the caller should enrich the record with what the announce
|
|
331
|
+
* says, so the NEXT run is verifiable.
|
|
332
|
+
*/
|
|
333
|
+
declare function counterpartyMatch(record: Pick<ChannelMapRecord, 'context'>, announced: string | undefined): 'match' | 'mismatch' | 'unrecorded';
|
|
117
334
|
/** The key fields of a full record. */
|
|
118
335
|
declare function recordKey(record: ChannelMapRecord): ChannelMapKey;
|
|
119
336
|
interface ChannelMapStoreOptions {
|
|
@@ -135,7 +352,9 @@ declare class ChannelMapStore {
|
|
|
135
352
|
list(): ChannelMapRecord[];
|
|
136
353
|
/**
|
|
137
354
|
* Recorded channels for one (identity, destination) pair — the resume
|
|
138
|
-
* candidates for a paid command.
|
|
355
|
+
* candidates for a paid command. Superseded records are EXCLUDED: they are
|
|
356
|
+
* retired from the resume path for good, and only `list()` (what `rig
|
|
357
|
+
* channel` enumerates) still shows them. @throws {ChannelMapCorruptError}
|
|
139
358
|
*/
|
|
140
359
|
listFor(identity: string, destination: string): ChannelMapRecord[];
|
|
141
360
|
/**
|
|
@@ -146,12 +365,27 @@ declare class ChannelMapStore {
|
|
|
146
365
|
*/
|
|
147
366
|
record(record: Omit<ChannelMapRecord, 'openedAt' | 'lastUsedAt'> & Partial<Pick<ChannelMapRecord, 'openedAt' | 'lastUsedAt'>>): void;
|
|
148
367
|
/**
|
|
149
|
-
* Bump a record's `lastUsedAt` (and optionally its known on-chain deposit
|
|
150
|
-
*
|
|
368
|
+
* Bump a record's `lastUsedAt` (and optionally its known on-chain deposit,
|
|
369
|
+
* or the counterparty a pre-validation record was written without) after
|
|
370
|
+
* resuming it. Unknown keys are a no-op.
|
|
151
371
|
*/
|
|
152
372
|
touch(key: ChannelMapKey, update?: {
|
|
153
373
|
depositTotal?: string;
|
|
374
|
+
recipient?: string;
|
|
154
375
|
}): void;
|
|
376
|
+
/**
|
|
377
|
+
* Retire a record from the resume path — the counterparty that terminates
|
|
378
|
+
* its destination has been REPLACED, so the channel it names is dead to the
|
|
379
|
+
* new node (`F01 - claim rejected`) even though every key field still
|
|
380
|
+
* matches (see {@link counterpartyMatch}).
|
|
381
|
+
*
|
|
382
|
+
* The record is MOVED to an archive key rather than deleted: it may still
|
|
383
|
+
* hold an on-chain deposit, and `rig channel list/close/settle` find
|
|
384
|
+
* channels by scanning `list()`, so deleting it would strand those funds
|
|
385
|
+
* behind hand-editing the JSON. Moving it also frees the live key for the
|
|
386
|
+
* re-resolved channel. Idempotent, and a no-op for an unknown record.
|
|
387
|
+
*/
|
|
388
|
+
supersede(record: ChannelMapRecord): void;
|
|
155
389
|
/**
|
|
156
390
|
* Read one channel's nonce-watermark entry from the client's
|
|
157
391
|
* `channels.json` (undefined when the file or entry is missing).
|
|
@@ -283,437 +517,6 @@ interface StandaloneMoneyOps {
|
|
|
283
517
|
walletChainBalances(): Promise<WalletChainBalanceInfo[]>;
|
|
284
518
|
}
|
|
285
519
|
|
|
286
|
-
/**
|
|
287
|
-
* StandalonePublisher — impl 2 of the {@link Publisher} seam (#228): an
|
|
288
|
-
* EMBEDDED ToonClient constructed from the caller's config (mnemonic +
|
|
289
|
-
* account index, the exact `packages/client/src/config.ts` shape) instead of
|
|
290
|
-
* routing through a running toon-clientd. Made for CI jobs, servers, and
|
|
291
|
-
* one-shot CLI runs where no daemon exists.
|
|
292
|
-
*
|
|
293
|
-
* Paid-write mechanics mirror the production daemon path
|
|
294
|
-
* (`client-mcp/src/daemon/client-runner.ts`) and the proven seed pipeline
|
|
295
|
-
* (`rig/tests/e2e/seed/lib/{publish,git-builder}.ts`):
|
|
296
|
-
*
|
|
297
|
-
* - one signed balance-proof CLAIM per write (`signBalanceProof(channelId,
|
|
298
|
-
* fee)` — the ChannelManager accumulates the cumulative watermark),
|
|
299
|
-
* - publishes route to the relay write destination with a flat per-event
|
|
300
|
-
* fee (the daemon's `feePerEvent` convention),
|
|
301
|
-
* - git objects upload as kind:5094 store writes tagged
|
|
302
|
-
* Git-SHA/Git-Type/Repo, priced at bytes × per-byte rate (the seed
|
|
303
|
-
* pipeline's bid), routed to the store destination via `proxyPath:
|
|
304
|
-
* '/store'`, with the Arweave txId decoded from the FULFILL data.
|
|
305
|
-
*
|
|
306
|
-
* Because the embedded client signs claims on the SAME channels a daemon on
|
|
307
|
-
* the same identity would, every paid operation is preceded by the nonce
|
|
308
|
-
* guard (./nonce-guard.ts): refuse if a toon-clientd holds this identity,
|
|
309
|
-
* and hold an exclusive per-pubkey lockfile against other standalone
|
|
310
|
-
* processes for the lifetime of this publisher.
|
|
311
|
-
*
|
|
312
|
-
* Channel REUSE (#262): with a `channelMap` configured, start() resumes the
|
|
313
|
-
* channel recorded for (identity, channel anchor) — `trackChannel` rehydrates
|
|
314
|
-
* the cumulative-claim watermark from the client's channels.json — and
|
|
315
|
-
* records any fresh lazy open, so sequential CLI invocations share ONE
|
|
316
|
-
* on-chain channel instead of stranding a deposit per run (./channel-map.ts).
|
|
317
|
-
*/
|
|
318
|
-
|
|
319
|
-
/** A fully-signed Nostr event (structural subset of nostr-tools' NostrEvent). */
|
|
320
|
-
interface SignedNostrEvent extends UnsignedEvent {
|
|
321
|
-
id: string;
|
|
322
|
-
pubkey: string;
|
|
323
|
-
sig: string;
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* The slice of `ToonClient` the publisher drives. Kept structural so tests
|
|
327
|
-
* inject a mock and alternative client builds stay compatible.
|
|
328
|
-
*/
|
|
329
|
-
interface ToonClientLike {
|
|
330
|
-
start(): Promise<unknown>;
|
|
331
|
-
stop(): Promise<void>;
|
|
332
|
-
isStarted?(): boolean;
|
|
333
|
-
getPublicKey(): string;
|
|
334
|
-
signEvent(template: UnsignedEvent): SignedNostrEvent;
|
|
335
|
-
openChannel(destination?: string): Promise<string>;
|
|
336
|
-
signBalanceProof(channelId: string, amount: bigint): Promise<SignedBalanceProof>;
|
|
337
|
-
publishEvent(event: SignedNostrEvent, options?: {
|
|
338
|
-
destination?: string;
|
|
339
|
-
claim?: SignedBalanceProof;
|
|
340
|
-
ilpAmount?: bigint;
|
|
341
|
-
proxyPath?: string;
|
|
342
|
-
}): Promise<PublishEventResult>;
|
|
343
|
-
/** On-chain deposit total for a tracked channel (channel-map bookkeeping). */
|
|
344
|
-
getChannelDepositTotal?(channelId: string): bigint;
|
|
345
|
-
/** Re-read a RESUMED channel's on-chain deposit (persisted state omits it). */
|
|
346
|
-
rehydrateChannelDeposit?(channelId: string, opts: {
|
|
347
|
-
chain: string;
|
|
348
|
-
tokenNetworkAddress: string;
|
|
349
|
-
}): Promise<bigint | undefined>;
|
|
350
|
-
/** Deposit extra collateral (base-unit delta) into an open channel. */
|
|
351
|
-
depositToChannel?(channelId: string, amount: string | bigint): Promise<{
|
|
352
|
-
channelId: string;
|
|
353
|
-
txHash?: string;
|
|
354
|
-
depositTotal: string;
|
|
355
|
-
}>;
|
|
356
|
-
/** Close a channel — starts the settlement challenge window (on-chain). */
|
|
357
|
-
closeChannel?(channelId: string): Promise<{
|
|
358
|
-
channelId: string;
|
|
359
|
-
txHash?: string;
|
|
360
|
-
/** Unix SECONDS, string-encoded. */
|
|
361
|
-
closedAt: string;
|
|
362
|
-
settleableAt: string;
|
|
363
|
-
}>;
|
|
364
|
-
/** Settle a closed channel after its window — releases funds (on-chain). */
|
|
365
|
-
settleChannel?(channelId: string): Promise<{
|
|
366
|
-
channelId: string;
|
|
367
|
-
txHash?: string;
|
|
368
|
-
}>;
|
|
369
|
-
/**
|
|
370
|
-
* Free FULL multi-chain wallet view (#299) — native coin + configured tokens
|
|
371
|
-
* per chain — works on an UNSTARTED client (Solana/Mina addresses are derived
|
|
372
|
-
* from the mnemonic on demand). `fallback` supplies Solana/Mina channel params
|
|
373
|
-
* to read WHEN the client config has none, without touching settlement config.
|
|
374
|
-
*/
|
|
375
|
-
getWalletBalances?(fallback?: WalletViewFallback): Promise<WalletChainBalanceInfo[]>;
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Wallet-view-only Solana/Mina channel defaults (#299): RPC/GraphQL + token used
|
|
379
|
-
* to READ the balance of a chain the identity has no configured channel for, so
|
|
380
|
-
* `rig balance` shows all three chains (0 for a not-yet-on-chain account). These
|
|
381
|
-
* NEVER enter the client's settlement config — they cannot influence chain
|
|
382
|
-
* negotiation — so a preset default here is safe even for a chain the wallet
|
|
383
|
-
* cannot yet settle on.
|
|
384
|
-
*/
|
|
385
|
-
interface WalletViewFallback {
|
|
386
|
-
solanaChannel?: ToonClientConfig['solanaChannel'];
|
|
387
|
-
minaChannel?: ToonClientConfig['minaChannel'];
|
|
388
|
-
}
|
|
389
|
-
interface StandalonePublisherOptions {
|
|
390
|
-
/**
|
|
391
|
-
* ToonClient config (mnemonic + mnemonicAccountIndex + proxy/BTP uplink +
|
|
392
|
-
* settlement fields — see `packages/client/src/config.ts`). Exactly one of
|
|
393
|
-
* `clientConfig` | `client` is required.
|
|
394
|
-
*/
|
|
395
|
-
clientConfig?: ToonClientConfig;
|
|
396
|
-
/** Pre-built client (tests / advanced callers). */
|
|
397
|
-
client?: ToonClientLike;
|
|
398
|
-
/**
|
|
399
|
-
* ILP route for event publishes (relay `/write`). Default: derived from the
|
|
400
|
-
* config's `destinationAddress` anchor (`<base>.relay.store` → `<base>.relay`,
|
|
401
|
-
* matching the daemon's route derivation), else the anchor itself.
|
|
402
|
-
*/
|
|
403
|
-
publishDestination?: string;
|
|
404
|
-
/**
|
|
405
|
-
* ILP route for git-object uploads (store `/store` → Arweave). Default:
|
|
406
|
-
* derived like `publishDestination` (`<base>.relay.store` → `<base>.store`).
|
|
407
|
-
*/
|
|
408
|
-
storeDestination?: string;
|
|
409
|
-
/**
|
|
410
|
-
* ILP destination the payment channel anchors to. Default: the client
|
|
411
|
-
* config's `destinationAddress`.
|
|
412
|
-
*/
|
|
413
|
-
channelDestination?: string;
|
|
414
|
-
/**
|
|
415
|
-
* Client config for a SECOND uplink dedicated to store writes, when the
|
|
416
|
-
* store route terminates on a different node than publishes.
|
|
417
|
-
*
|
|
418
|
-
* A balance-proof claim is only verifiable by the connector holding that
|
|
419
|
-
* channel — one with no record of it refuses the packet (`F01 - claim
|
|
420
|
-
* rejected: names a channel this connector has no record of`). The store
|
|
421
|
-
* node has its own settlement address and its own channel, and on the
|
|
422
|
-
* two-box fleet the publish node has no route to it, so a store write
|
|
423
|
-
* cannot ride the publish session. Given this, store writes go out on
|
|
424
|
-
* their own client, against their own channel, recorded under their own
|
|
425
|
-
* anchor so `rig channel` still sees it.
|
|
426
|
-
*
|
|
427
|
-
* A separate CLIENT rather than a second destination on the existing one
|
|
428
|
-
* because `@toon-protocol/client` carries a single `btpUrl` per instance —
|
|
429
|
-
* there is no per-destination uplink to configure. Omitted (the
|
|
430
|
-
* single-node case) keeps the historical behaviour: one client, one
|
|
431
|
-
* channel, store writes on the publish session.
|
|
432
|
-
*/
|
|
433
|
-
storeClientConfig?: ToonClientConfig;
|
|
434
|
-
/**
|
|
435
|
-
* Pre-built store-leg client (tests / advanced callers) — the store-side
|
|
436
|
-
* counterpart of `client`, and mutually exclusive with
|
|
437
|
-
* `storeClientConfig` in the same way.
|
|
438
|
-
*/
|
|
439
|
-
storeClient?: ToonClientLike;
|
|
440
|
-
/** Flat fee per published event (daemon `feePerEvent` convention). Default 1n. */
|
|
441
|
-
eventFee?: bigint;
|
|
442
|
-
/**
|
|
443
|
-
* FLAT per-packet route prices for the publish/store destinations, as the
|
|
444
|
-
* payment peer announces them (kind:10032 `capabilities` — e.g.
|
|
445
|
-
* `{capability:'os.publish', address:'g.proxy.relay', price:'1000'}`) or as
|
|
446
|
-
* the terminating connector reports them from `GET /ilp/routes/price`.
|
|
447
|
-
*
|
|
448
|
-
* The connector gates every paid packet at the destination route's price: a
|
|
449
|
-
* balance-proof claim advancing the channel by less is rejected (F06). Since
|
|
450
|
-
* ADR 0020 (toon-client#452) a price is flat per handler, so `store` is the
|
|
451
|
-
* WHOLE upload fee rather than a floor under a per-byte computation — an
|
|
452
|
-
* upload of any size costs it. `publish` still floors {@link eventFee},
|
|
453
|
-
* which remains a caller-chosen flat figure.
|
|
454
|
-
*
|
|
455
|
-
* A destination without a known price prices its packets at 0 here and lets
|
|
456
|
-
* the connector be the one to refuse — this class never invents a rate.
|
|
457
|
-
*/
|
|
458
|
-
routePrices?: {
|
|
459
|
-
publish?: bigint;
|
|
460
|
-
store?: bigint;
|
|
461
|
-
};
|
|
462
|
-
/** Daemon control API port probed by the nonce guard. */
|
|
463
|
-
daemonPort?: number;
|
|
464
|
-
/**
|
|
465
|
-
* Skip Guard 1 (the same-identity daemon refusal, {@link checkDaemonIdentity})
|
|
466
|
-
* — the force-standalone override ({@link standaloneForced} / RIG_STANDALONE
|
|
467
|
-
* / `rig --standalone`). Guard 2, the exclusive per-identity {@link NonceLock},
|
|
468
|
-
* ALWAYS runs regardless, so two standalone processes still can't race the
|
|
469
|
-
* channel watermark. Default false (daemon-aware).
|
|
470
|
-
*/
|
|
471
|
-
skipDaemonCheck?: boolean;
|
|
472
|
-
/** Directory for the per-identity advisory lockfile. */
|
|
473
|
-
lockDir?: string;
|
|
474
|
-
/** Fetch impl for the daemon probe (tests). */
|
|
475
|
-
fetchImpl?: typeof fetch;
|
|
476
|
-
/**
|
|
477
|
-
* Peer→channel map store (#262): start() resumes the channel recorded for
|
|
478
|
-
* (identity, channel anchor) instead of opening a fresh one, and records
|
|
479
|
-
* any fresh lazy open for the next invocation. Absent (embedded callers
|
|
480
|
-
* managing their own channel lifecycle): the historical behaviour — open
|
|
481
|
-
* lazily every run, record nothing.
|
|
482
|
-
*/
|
|
483
|
-
channelMap?: ChannelMapStore;
|
|
484
|
-
/**
|
|
485
|
-
* Per-chain settlement parameters to BACK-FILL into the client's peer
|
|
486
|
-
* negotiations after start (#264/#260): peers whose kind:10032 announce
|
|
487
|
-
* carries no `tokenNetworks`/`preferredTokens` negotiate with those fields
|
|
488
|
-
* empty, and the on-chain channel open then fails ("tokenNetwork address
|
|
489
|
-
* is required"). Values here never override what a peer DID announce —
|
|
490
|
-
* they only fill gaps, keyed by the negotiated chain id.
|
|
491
|
-
*/
|
|
492
|
-
negotiationFallbacks?: {
|
|
493
|
-
tokenNetworks?: Record<string, string>;
|
|
494
|
-
preferredTokens?: Record<string, string>;
|
|
495
|
-
};
|
|
496
|
-
/** Sink for non-fatal channel-persistence warnings (default: stderr). */
|
|
497
|
-
warn?: (line: string) => void;
|
|
498
|
-
}
|
|
499
|
-
/** A relay/store rejected a paid write (fee NOT spent iff the claim failed too). */
|
|
500
|
-
declare class StandalonePublishError extends Error {
|
|
501
|
-
constructor(message: string);
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* Derive publish/store routes from the channel anchor. Behind the devnet
|
|
505
|
-
* proxy the anchor is `<base>.relay.store` (e.g. `g.proxy.relay.store`):
|
|
506
|
-
* publishes terminate at `<base>.relay`, uploads at `<base>.store`. Anchors
|
|
507
|
-
* not matching the convention pass through unchanged.
|
|
508
|
-
*/
|
|
509
|
-
declare function deriveRouteDestinations(anchor: string): {
|
|
510
|
-
publish: string;
|
|
511
|
-
store: string;
|
|
512
|
-
};
|
|
513
|
-
|
|
514
|
-
declare class StandalonePublisher implements Publisher {
|
|
515
|
-
private readonly client;
|
|
516
|
-
private readonly ownsClient;
|
|
517
|
-
private readonly publishDestination;
|
|
518
|
-
private readonly storeDestination;
|
|
519
|
-
private readonly channelDestination;
|
|
520
|
-
private readonly eventFee;
|
|
521
|
-
private readonly routePrices;
|
|
522
|
-
private readonly daemonPort;
|
|
523
|
-
private readonly skipDaemonCheck;
|
|
524
|
-
private readonly lockDir;
|
|
525
|
-
private readonly fetchImpl;
|
|
526
|
-
private readonly channelMap;
|
|
527
|
-
/** ILP anchor the channel is keyed by in the map (peer/apex destination). */
|
|
528
|
-
private readonly channelAnchor;
|
|
529
|
-
private readonly negotiationFallbacks;
|
|
530
|
-
private readonly warn;
|
|
531
|
-
private readonly storeClientConfig;
|
|
532
|
-
private readonly injectedStoreClient;
|
|
533
|
-
/** Lazily built on the first store write — see {@link storeLeg}. */
|
|
534
|
-
private storeClient;
|
|
535
|
-
private storeChannelId;
|
|
536
|
-
private storeLegPromise;
|
|
537
|
-
private lock;
|
|
538
|
-
private channelId;
|
|
539
|
-
private readyPromise;
|
|
540
|
-
/** Guard + client start only (no channel) — see {@link startClientOnly}. */
|
|
541
|
-
private clientReadyPromise;
|
|
542
|
-
/** True when the last start() RESUMED the recorded channel (#263). */
|
|
543
|
-
private lastOpenResumed;
|
|
544
|
-
constructor(options: StandalonePublisherOptions);
|
|
545
|
-
/** Hex Nostr pubkey of the embedded identity (available before start). */
|
|
546
|
-
getPublicKey(): string;
|
|
547
|
-
/**
|
|
548
|
-
* Run the nonce guard, start the embedded client, and open (or resume) the
|
|
549
|
-
* payment channel. Called lazily by the first paid operation; safe to call
|
|
550
|
-
* eagerly to fail fast. Idempotent.
|
|
551
|
-
*/
|
|
552
|
-
start(): Promise<void>;
|
|
553
|
-
/**
|
|
554
|
-
* Run the nonce guard and start the embedded client WITHOUT touching the
|
|
555
|
-
* payment channel (#263): `channel close`/`settle` operate on a RECORDED
|
|
556
|
-
* channel and must never open a fresh one as a side effect of starting.
|
|
557
|
-
* Idempotent; `start()` layers the channel open/resume on top of this.
|
|
558
|
-
*/
|
|
559
|
-
startClientOnly(): Promise<void>;
|
|
560
|
-
private doStartClient;
|
|
561
|
-
/**
|
|
562
|
-
* Back-fill negotiated peer metadata the announce did not carry
|
|
563
|
-
* (#264/#260 root cause 3): after the client's bootstrap negotiation, any
|
|
564
|
-
* peer negotiation missing `tokenNetwork`/`tokenAddress` gets the derived
|
|
565
|
-
* per-chain fallback for its negotiated chain, BEFORE the lazy channel
|
|
566
|
-
* open reads them. Announced values are never overridden.
|
|
567
|
-
*/
|
|
568
|
-
private applyNegotiationFallbacks;
|
|
569
|
-
/**
|
|
570
|
-
* Open the payment channel — or, when the channel map has a record for
|
|
571
|
-
* (identity, anchor), RESUME the recorded on-chain channel (#262).
|
|
572
|
-
*
|
|
573
|
-
* Resume seeds the client's ChannelManager (`trackChannel` rehydrates the
|
|
574
|
-
* cumulative-claim watermark from channels.json; `peerChannels` makes the
|
|
575
|
-
* subsequent `openChannel` return the same id instead of opening on-chain).
|
|
576
|
-
* A fresh open is RECORDED so the next invocation resumes it. A corrupt map
|
|
577
|
-
* file throws BEFORE anything is opened — never a silent duplicate open.
|
|
578
|
-
*/
|
|
579
|
-
private openOrResumeChannel;
|
|
580
|
-
/**
|
|
581
|
-
* {@link openOrResumeChannel} for an arbitrary client + destination, so
|
|
582
|
-
* the store leg gets the same resume-before-open guarantee (and the same
|
|
583
|
-
* corruption check) as the publish leg rather than a second, weaker path.
|
|
584
|
-
*
|
|
585
|
-
* `anchor` defaults to the destination: a leg other than the publish one
|
|
586
|
-
* is keyed in the channel map by the route it pays for.
|
|
587
|
-
* `trackResumeState` is publish-only — {@link lastOpenResumed} feeds the
|
|
588
|
-
* `resumed` field of this publisher's channel status, which describes the
|
|
589
|
-
* publish channel and would be wrong to overwrite from a store open.
|
|
590
|
-
*/
|
|
591
|
-
private openOrResumeChannelOn;
|
|
592
|
-
/**
|
|
593
|
-
* Try to resume one recorded channel: the first candidate whose peer is
|
|
594
|
-
* still negotiated on the SAME chain + tokenNetwork and whose watermark
|
|
595
|
-
* does not show it closed/settled. Returns the resumed record, if any.
|
|
596
|
-
*/
|
|
597
|
-
private resumeRecordedChannel;
|
|
598
|
-
/** Record a freshly opened channel (+ seed its claim watermark at 0/0). */
|
|
599
|
-
private recordOpenedChannel;
|
|
600
|
-
/** Release the identity lock and stop the embedded client (if we own it). */
|
|
601
|
-
stop(): Promise<void>;
|
|
602
|
-
/**
|
|
603
|
-
* Explicit `rig channel open`: the SAME resume-or-open path the lazy paid
|
|
604
|
-
* writes use (guard → start → resume the recorded channel or open + record
|
|
605
|
-
* a fresh one), surfaced with a receipt — plus an optional extra collateral
|
|
606
|
-
* deposit on top of the open/resume.
|
|
607
|
-
*/
|
|
608
|
-
openChannelExplicit(opts?: {
|
|
609
|
-
/** Extra collateral to deposit AFTER the open/resume (base units). */
|
|
610
|
-
deposit?: bigint;
|
|
611
|
-
}): Promise<ChannelOpenOutcome>;
|
|
612
|
-
/**
|
|
613
|
-
* Adopt a RECORDED channel into the running client so on-chain close/
|
|
614
|
-
* settle/deposit can act on it: `trackChannel` rehydrates the claim
|
|
615
|
-
* watermark + withdraw timers from channels.json, `peerChannels` binds the
|
|
616
|
-
* peer, and the on-chain client's context cache is re-seeded (it only
|
|
617
|
-
* learns context at open time — a resumed channel would otherwise throw
|
|
618
|
-
* "No on-chain context").
|
|
619
|
-
*/
|
|
620
|
-
private adoptRecordedChannel;
|
|
621
|
-
/**
|
|
622
|
-
* Close a recorded channel: starts the on-chain settlement challenge
|
|
623
|
-
* window. The client persists `closedAt`/`settleableAt` into the claim
|
|
624
|
-
* watermark store, which is exactly where `rig channel list`/`balance`
|
|
625
|
-
* derive the closing/settleable/settled status from. Guard + client start,
|
|
626
|
-
* but NEVER a channel open ({@link startClientOnly}).
|
|
627
|
-
*/
|
|
628
|
-
closeRecordedChannel(record: ChannelMapRecord): Promise<ChannelCloseOutcome>;
|
|
629
|
-
/**
|
|
630
|
-
* Settle a recorded channel after its challenge window — releases the
|
|
631
|
-
* remaining collateral. The client enforces the `now >= settleableAt` time
|
|
632
|
-
* guard BEFORE spending gas (a too-early call throws its retryable
|
|
633
|
-
* SettleTooEarlyError) and persists `settledAt` into the watermark store.
|
|
634
|
-
*/
|
|
635
|
-
settleRecordedChannel(record: ChannelMapRecord): Promise<ChannelSettleOutcome>;
|
|
636
|
-
/**
|
|
637
|
-
* The full multi-chain wallet view (#299) for the embedded identity — native
|
|
638
|
-
* coin + configured tokens (USDC) per chain — a FREE read on the UNSTARTED
|
|
639
|
-
* client (no nonce guard, no uplink, no channel). The client derives the
|
|
640
|
-
* Solana/Mina addresses from the mnemonic on demand, so ALL configured chains
|
|
641
|
-
* appear even before a start. Best-effort per chain (an unreachable RPC yields
|
|
642
|
-
* an `unreadable` chain, not a failure). `fallback` supplies Solana/Mina RPC
|
|
643
|
-
* defaults (e.g. the network preset) for chains the config has no channel for.
|
|
644
|
-
*/
|
|
645
|
-
readWalletChainBalances(fallback?: WalletViewFallback): Promise<WalletChainBalanceInfo[]>;
|
|
646
|
-
/**
|
|
647
|
-
* Fee rates for `planPush` estimation, both flat per packet (ADR 0020),
|
|
648
|
-
* with the announced route prices folded in so the ESTIMATE always equals
|
|
649
|
-
* the CLAIMS: `eventFee` is returned pre-floored at the publish route price,
|
|
650
|
-
* and `uploadFee` IS the store route price.
|
|
651
|
-
*/
|
|
652
|
-
getFeeRates(): Promise<FeeRates>;
|
|
653
|
-
/**
|
|
654
|
-
* The flat per-event claim: `eventFee`, floored at the publish route's
|
|
655
|
-
* announced price (the connector rejects a claim below it — F06).
|
|
656
|
-
*/
|
|
657
|
-
private effectiveEventFee;
|
|
658
|
-
/**
|
|
659
|
-
* The per-upload claim: the store route's flat price, whatever the object's
|
|
660
|
-
* size. Byte-proportional pricing has no successor (ADR 0020) — the route
|
|
661
|
-
* table is the price list — and the connector charges this figure whether
|
|
662
|
-
* the body is 100 bytes or 100 KB.
|
|
663
|
-
*/
|
|
664
|
-
private uploadFee;
|
|
665
|
-
/**
|
|
666
|
-
* Upload one git object as a kind:5094 store write (Git-SHA/Git-Type/Repo
|
|
667
|
-
* tagged — the proven seed-pipeline shape), signing one balance-proof claim
|
|
668
|
-
* for the store route's flat price
|
|
669
|
-
* ({@link StandalonePublisherOptions.routePrices}) — ADR 0020 prices a
|
|
670
|
-
* packet per handler, not per byte.
|
|
671
|
-
*
|
|
672
|
-
* #368: a blob's `Content-Type` is derived from its path extension (else
|
|
673
|
-
* octet-stream) and sent in the `output` tag, which the store forwards onto
|
|
674
|
-
* the Arweave upload's Content-Type — so a gateway serves `index.html` as
|
|
675
|
-
* `text/html`, not `application/octet-stream`. Non-blob objects (trees,
|
|
676
|
-
* commits, tags) are never served as files, so they stay octet-stream.
|
|
677
|
-
*/
|
|
678
|
-
uploadGitObject(upload: GitObjectUpload): Promise<UploadReceipt>;
|
|
679
|
-
/**
|
|
680
|
-
* Upload one raw blob (no git envelope) with an explicit `Content-Type`
|
|
681
|
-
* (#368) — a kind:5094 store write carrying just the `i`/`bid`/`output`
|
|
682
|
-
* tags (and an optional `Repo` provenance tag), NOT the Git-SHA/Git-Type
|
|
683
|
-
* tags. Without those the store keeps the bytes verbatim instead of
|
|
684
|
-
* re-deriving a git envelope, which is exactly what the ar.io path manifest
|
|
685
|
-
* needs. One balance-proof claim for the store route's flat price.
|
|
686
|
-
*/
|
|
687
|
-
uploadBlob(upload: BlobUpload): Promise<UploadReceipt>;
|
|
688
|
-
/**
|
|
689
|
-
* Sign the event with the embedded identity and pay-to-publish it through
|
|
690
|
-
* the relay write route, one claim for the flat per-event fee.
|
|
691
|
-
*
|
|
692
|
-
* `relayUrls` is the interface's plural forward-compat surface (parked
|
|
693
|
-
* #84): the standalone impl routes over ILP to its single configured
|
|
694
|
-
* publish destination, so more than one relay is refused rather than
|
|
695
|
-
* silently half-published.
|
|
696
|
-
*/
|
|
697
|
-
publishEvent(event: UnsignedEvent, relayUrls: string[]): Promise<PublishReceipt>;
|
|
698
|
-
private requireChannel;
|
|
699
|
-
/**
|
|
700
|
-
* The client + channel a STORE write must be paid on.
|
|
701
|
-
*
|
|
702
|
-
* With no `storeClientConfig` this is the publish leg unchanged — the
|
|
703
|
-
* single-node case, where the store terminates on the connector that
|
|
704
|
-
* already holds the channel. With one, the store node is a different
|
|
705
|
-
* connector holding a different channel, and paying it from the publish
|
|
706
|
-
* channel is precisely the `F01 - claim rejected: names a channel this
|
|
707
|
-
* connector has no record of` failure this exists to prevent.
|
|
708
|
-
*
|
|
709
|
-
* Built on FIRST STORE WRITE, not in `start()`: `rig push` with nothing to
|
|
710
|
-
* upload, and every read-only command, should not open a second on-chain
|
|
711
|
-
* channel (gas) for a leg they never use. Memoised on the promise so
|
|
712
|
-
* concurrent uploads share one open rather than racing two.
|
|
713
|
-
*/
|
|
714
|
-
private storeLeg;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
520
|
/**
|
|
718
521
|
* Nonce-ownership guard for the STANDALONE embedded Publisher (#228).
|
|
719
522
|
*
|
|
@@ -825,4 +628,4 @@ declare class NonceLock {
|
|
|
825
628
|
release(): void;
|
|
826
629
|
}
|
|
827
630
|
|
|
828
|
-
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
|
|
631
|
+
export { type AcquireLockOptions, type ChannelCloseOutcome, ChannelMapCorruptError, type ChannelMapKey, type ChannelMapRecord, ChannelMapStore, type ChannelMapStoreOptions, type ChannelOpenOutcome, type ChannelSettleOutcome, type CheckDaemonOptions, ConnectorPublishError, ConnectorPublisher, type ConnectorPublisherOptions, DEFAULT_DAEMON_PORT, DaemonIdentityConflictError, MAX_ACCOUNT_INDEX, NonceLock, type NostrKey, type PaidClientLike, type PaidFulfilled, type PaidLeg, type PaidRefused, type PaidRequest, type PaidSendOptions, type PaidSendResult, type PersistedChannelContext, RIG_CHANNEL_MAP_FILENAME, type RouteTerms, StandaloneLockError, type StandaloneMoneyOps, type WalletChainBalanceInfo, type WalletTokenAmountInfo, type WatermarkEntry, channelStatus, checkDaemonIdentity, counterpartyMatch, defaultDaemonPort, defaultLockDir, deriveNostrKeyFromMnemonic, extractArweaveTxId, nostrDerivationPath, recordKey, resolveChannelPaths, sameSettlementAddress };
|