@dvmkit/sdk 0.1.3-rc.7 → 0.1.4-rc.7
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 +107 -8
- package/dist/{chunk-YDIYXGYL.js → chunk-E4EVGPDX.js} +16 -9
- package/dist/{chunk-EPNDZ5DH.js → chunk-EDDYHZ6W.js} +4 -4
- package/dist/{chunk-NFRM5QYP.js → chunk-EVBK675R.js} +5 -0
- package/dist/{chunk-3ZHMQCYP.js → chunk-QK3VJNCK.js} +329 -28
- package/dist/{chunk-LLXV32HA.js → chunk-SSSZUVWM.js} +96 -3
- package/dist/{chunk-4B56DEEV.js → chunk-U6M3ATSG.js} +7 -1
- package/dist/{chunk-2K7E3N2D.js → chunk-VRQDX5P4.js} +47 -14
- package/dist/{credit-menu-C7zAJElJ.d.ts → credit-menu-C1ezIFlJ.d.ts} +76 -4
- package/dist/{fx-BF_SG2i0.d.ts → fx-C6dl2LVI.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/internal/caller.d.ts +29 -17
- package/dist/internal/caller.js +150 -29
- package/dist/internal/server.d.ts +8 -8
- package/dist/internal/server.js +5 -5
- package/dist/{job-store-Bn23V3QU.d.ts → job-store-DHnW4Cg_.d.ts} +16 -1
- package/dist/{lightning-backend-C04nH94l.d.ts → lightning-backend-Ci1nogk_.d.ts} +1 -1
- package/dist/{postgres-job-store-TAONYLIF.js → postgres-job-store-3RAXMNSY.js} +1 -1
- package/dist/{revenue-reporter-XXSU5KVB.js → revenue-reporter-ASZ7SHHH.js} +1 -1
- package/dist/server/index.d.ts +22 -8
- package/dist/server/index.js +7 -7
- package/dist/{step-cache-3cT4Shk0.d.ts → step-cache-BLPZNizw.d.ts} +148 -3
- package/dist/testing/index.d.ts +13 -3
- package/dist/testing/index.js +31 -2
- package/dist/{usd-BnuXoFl5.d.ts → usd-BgOfZlk6.d.ts} +1 -1
- package/package.json +6 -4
|
@@ -125,6 +125,7 @@ var ListenChannel = class {
|
|
|
125
125
|
|
|
126
126
|
// src/sdk/server/postgres-job-store.ts
|
|
127
127
|
var JOB_MESSAGES_CHANNEL = "job_messages";
|
|
128
|
+
var JOB_DVM_ID = /* @__PURE__ */ Symbol("jobDvmId");
|
|
128
129
|
var PostgresJobStore = class {
|
|
129
130
|
pool;
|
|
130
131
|
listenChannel = null;
|
|
@@ -177,6 +178,18 @@ var PostgresJobStore = class {
|
|
|
177
178
|
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS native_amount DOUBLE PRECISION;
|
|
178
179
|
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS native_asset TEXT;
|
|
179
180
|
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS cashu_flow TEXT;
|
|
181
|
+
-- internal-review: what the job cost the BUILDER to serve, declared by the
|
|
182
|
+
-- handler through ctx.cost(). NULL is "unreported", deliberately
|
|
183
|
+
-- distinguishable from a declared zero.
|
|
184
|
+
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS cost_amount_micro BIGINT;
|
|
185
|
+
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS cost_currency TEXT;
|
|
186
|
+
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS cost_revision BIGINT;
|
|
187
|
+
-- Cost-only reports are queued after the terminal row lands. Keep the
|
|
188
|
+
-- owning DVM and the last durably-enqueued revision on that row so a
|
|
189
|
+
-- restarted (or sibling) process can close that crash window without
|
|
190
|
+
-- replaying another mount's jobs.
|
|
191
|
+
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS dvm_id TEXT;
|
|
192
|
+
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS cost_reported_revision BIGINT;
|
|
180
193
|
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS required_msats BIGINT;
|
|
181
194
|
-- next_seq is intentionally absent from isolate_jobs (platform/db.ts).
|
|
182
195
|
-- It powers StreamableJobStore cross-machine seq allocation; isolate
|
|
@@ -245,6 +258,10 @@ var PostgresJobStore = class {
|
|
|
245
258
|
CREATE INDEX IF NOT EXISTS idx_jobs_retention
|
|
246
259
|
ON jobs (last_activity_at, id)
|
|
247
260
|
WHERE redacted_at IS NULL AND status IN ('completed', 'failed', 'cancelled');
|
|
261
|
+
CREATE INDEX IF NOT EXISTS idx_jobs_pending_cost_report
|
|
262
|
+
ON jobs (dvm_id, id)
|
|
263
|
+
WHERE cost_revision IS NOT NULL
|
|
264
|
+
AND status IN ('completed', 'failed', 'cancelled');
|
|
248
265
|
-- internal-review: the idempotent-replay lookup. payment_tx_hash carries the
|
|
249
266
|
-- caller's X-Cashu-Request-Id on the accumulator path, so a retried paid
|
|
250
267
|
-- submit finds the job its payment already created.
|
|
@@ -413,18 +430,32 @@ var PostgresJobStore = class {
|
|
|
413
430
|
held.client.release();
|
|
414
431
|
}
|
|
415
432
|
async save(record) {
|
|
433
|
+
await this.saveRecord(record, record[JOB_DVM_ID]);
|
|
434
|
+
}
|
|
435
|
+
/** Persist a job while retaining its mount identity for cost-report recovery. */
|
|
436
|
+
async saveForDvm(record, dvmId) {
|
|
437
|
+
const scoped = record;
|
|
438
|
+
scoped[JOB_DVM_ID] = dvmId;
|
|
439
|
+
try {
|
|
440
|
+
await this.save(scoped);
|
|
441
|
+
} finally {
|
|
442
|
+
delete scoped[JOB_DVM_ID];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
async saveRecord(record, dvmId) {
|
|
416
446
|
const { rowCount } = await this.pool.query(
|
|
417
447
|
`INSERT INTO jobs (
|
|
418
448
|
id, tags, capability, input, params, requester_id, status, summary,
|
|
419
449
|
messages, seq, paid_msats, payment_mint, payment_rail,
|
|
420
450
|
payment_tx_hash, payment_transaction_hash, native_amount, native_asset, cashu_flow,
|
|
451
|
+
cost_amount_micro, cost_currency, cost_revision,
|
|
421
452
|
received_proofs, pending_payment_msats, pending_mpp_challenge_ids,
|
|
422
453
|
pending_x402_nonce, pending_x402_amount_usdc_micro, required_msats, step_cache, state, created_at,
|
|
423
454
|
last_activity_at, next_seq, requester_token_hash, requester_token,
|
|
424
455
|
request_fingerprint, requester_pubkey, request_id, credit_id, draw_id,
|
|
425
456
|
pending_payment_fiat_micro, pending_payment_fiat_currency, auth_request_path,
|
|
426
|
-
funding_receipt, funding_credit
|
|
427
|
-
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41)
|
|
457
|
+
funding_receipt, funding_credit, dvm_id
|
|
458
|
+
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43,$44,$45)
|
|
428
459
|
ON CONFLICT (id) DO UPDATE SET
|
|
429
460
|
status = EXCLUDED.status,
|
|
430
461
|
summary = EXCLUDED.summary,
|
|
@@ -440,6 +471,29 @@ var PostgresJobStore = class {
|
|
|
440
471
|
native_amount = EXCLUDED.native_amount,
|
|
441
472
|
native_asset = EXCLUDED.native_asset,
|
|
442
473
|
cashu_flow = EXCLUDED.cashu_flow,
|
|
474
|
+
-- Cost declarations are revisioned because a terminal snapshot can be
|
|
475
|
+
-- re-saved by a different machine. Never let a stale persisted prefix
|
|
476
|
+
-- replace the handler owner's later cumulative declaration; a higher
|
|
477
|
+
-- revision with NULL amount/currency is an intentional invalidation.
|
|
478
|
+
cost_amount_micro = CASE
|
|
479
|
+
WHEN EXCLUDED.cost_revision IS NOT NULL
|
|
480
|
+
AND (jobs.cost_revision IS NULL OR EXCLUDED.cost_revision >= jobs.cost_revision)
|
|
481
|
+
THEN EXCLUDED.cost_amount_micro
|
|
482
|
+
ELSE jobs.cost_amount_micro
|
|
483
|
+
END,
|
|
484
|
+
cost_currency = CASE
|
|
485
|
+
WHEN EXCLUDED.cost_revision IS NOT NULL
|
|
486
|
+
AND (jobs.cost_revision IS NULL OR EXCLUDED.cost_revision >= jobs.cost_revision)
|
|
487
|
+
THEN EXCLUDED.cost_currency
|
|
488
|
+
ELSE jobs.cost_currency
|
|
489
|
+
END,
|
|
490
|
+
cost_revision = CASE
|
|
491
|
+
WHEN EXCLUDED.cost_revision IS NOT NULL
|
|
492
|
+
AND (jobs.cost_revision IS NULL OR EXCLUDED.cost_revision >= jobs.cost_revision)
|
|
493
|
+
THEN EXCLUDED.cost_revision
|
|
494
|
+
ELSE jobs.cost_revision
|
|
495
|
+
END,
|
|
496
|
+
dvm_id = COALESCE(jobs.dvm_id, EXCLUDED.dvm_id),
|
|
443
497
|
received_proofs = EXCLUDED.received_proofs,
|
|
444
498
|
pending_mpp_challenge_ids = EXCLUDED.pending_mpp_challenge_ids,
|
|
445
499
|
pending_x402_nonce = EXCLUDED.pending_x402_nonce,
|
|
@@ -478,6 +532,9 @@ var PostgresJobStore = class {
|
|
|
478
532
|
record.nativeAmount ?? null,
|
|
479
533
|
record.nativeAsset ?? null,
|
|
480
534
|
record.cashuFlow ?? null,
|
|
535
|
+
record.costAmountMicro ?? null,
|
|
536
|
+
record.costCurrency ?? null,
|
|
537
|
+
record.costRevision ?? null,
|
|
481
538
|
JSON.stringify(record.receivedProofs),
|
|
482
539
|
record.pendingPaymentMsats ?? null,
|
|
483
540
|
record.pendingMppChallengeIds ? JSON.stringify(record.pendingMppChallengeIds) : null,
|
|
@@ -513,7 +570,8 @@ var PostgresJobStore = class {
|
|
|
513
570
|
// whose live gate accepted this proof.
|
|
514
571
|
record.authRequestPath ?? null,
|
|
515
572
|
record.fundingReceipt ? JSON.stringify(record.fundingReceipt) : null,
|
|
516
|
-
record.fundingCredit ? JSON.stringify(record.fundingCredit) : null
|
|
573
|
+
record.fundingCredit ? JSON.stringify(record.fundingCredit) : null,
|
|
574
|
+
dvmId ?? null
|
|
517
575
|
]
|
|
518
576
|
);
|
|
519
577
|
if (rowCount === 0) {
|
|
@@ -530,6 +588,38 @@ var PostgresJobStore = class {
|
|
|
530
588
|
await this.pool.query("DELETE FROM job_messages WHERE job_id = $1", [record.id]).catch(() => void 0);
|
|
531
589
|
}
|
|
532
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Read terminal zero-revenue jobs whose latest declared-cost revision has
|
|
593
|
+
* not yet reached the durable reporter outbox.
|
|
594
|
+
*/
|
|
595
|
+
async listUnreportedTerminalCosts(args) {
|
|
596
|
+
const { rows } = await this.pool.query(
|
|
597
|
+
`SELECT *
|
|
598
|
+
FROM jobs
|
|
599
|
+
WHERE dvm_id = $1
|
|
600
|
+
AND cost_revision IS NOT NULL
|
|
601
|
+
AND (cost_reported_revision IS NULL OR cost_reported_revision < cost_revision)
|
|
602
|
+
AND (
|
|
603
|
+
status IN ('failed', 'cancelled')
|
|
604
|
+
OR (status = 'completed' AND paid_msats = 0)
|
|
605
|
+
)
|
|
606
|
+
AND ($2::text IS NULL OR id > $2)
|
|
607
|
+
ORDER BY id
|
|
608
|
+
LIMIT $3`,
|
|
609
|
+
[args.dvmId, args.afterJobId ?? null, args.limit]
|
|
610
|
+
);
|
|
611
|
+
return rows.map(rowToRecord);
|
|
612
|
+
}
|
|
613
|
+
/** Mark one revision only after its report has reached durable enqueue. */
|
|
614
|
+
async markTerminalCostReported(jobId, costRevision) {
|
|
615
|
+
const { rowCount } = await this.pool.query(
|
|
616
|
+
`UPDATE jobs
|
|
617
|
+
SET cost_reported_revision = GREATEST(COALESCE(cost_reported_revision, -1), $2)
|
|
618
|
+
WHERE id = $1 AND cost_revision = $2`,
|
|
619
|
+
[jobId, costRevision]
|
|
620
|
+
);
|
|
621
|
+
return rowCount === 1;
|
|
622
|
+
}
|
|
533
623
|
async delete(id) {
|
|
534
624
|
await this.pool.query("DELETE FROM jobs WHERE id = $1", [id]);
|
|
535
625
|
await this.pool.query("DELETE FROM job_messages WHERE job_id = $1", [id]).catch(() => void 0);
|
|
@@ -1203,6 +1293,9 @@ function rowToRecord(row) {
|
|
|
1203
1293
|
nativeAmount: row.native_amount,
|
|
1204
1294
|
nativeAsset: row.native_asset,
|
|
1205
1295
|
cashuFlow: row.cashu_flow,
|
|
1296
|
+
costAmountMicro: row.cost_amount_micro == null ? void 0 : Number(row.cost_amount_micro),
|
|
1297
|
+
costCurrency: row.cost_currency ?? void 0,
|
|
1298
|
+
costRevision: row.cost_revision == null ? void 0 : Number(row.cost_revision),
|
|
1206
1299
|
creditId: row.credit_id ?? void 0,
|
|
1207
1300
|
drawId: row.draw_id ?? void 0,
|
|
1208
1301
|
fundingReceipt: row.funding_receipt ?? void 0,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StepCache,
|
|
3
3
|
loggers
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E4EVGPDX.js";
|
|
5
5
|
import {
|
|
6
6
|
redactUrl
|
|
7
7
|
} from "./chunk-FUJ36YDV.js";
|
|
@@ -33,6 +33,9 @@ function toJobRecord(job) {
|
|
|
33
33
|
nativeAmount: job.nativeAmount,
|
|
34
34
|
nativeAsset: job.nativeAsset,
|
|
35
35
|
cashuFlow: job.cashuFlow,
|
|
36
|
+
costAmountMicro: job.costAmountMicro,
|
|
37
|
+
costCurrency: job.costCurrency,
|
|
38
|
+
costRevision: job.costRevision,
|
|
36
39
|
creditId: job.creditId,
|
|
37
40
|
drawId: job.drawId,
|
|
38
41
|
fundingReceipt: job.fundingReceipt,
|
|
@@ -76,6 +79,9 @@ function fromJobRecord(record) {
|
|
|
76
79
|
nativeAmount: record.nativeAmount,
|
|
77
80
|
nativeAsset: record.nativeAsset,
|
|
78
81
|
cashuFlow: record.cashuFlow,
|
|
82
|
+
costAmountMicro: record.costAmountMicro,
|
|
83
|
+
costCurrency: record.costCurrency,
|
|
84
|
+
costRevision: record.costRevision,
|
|
79
85
|
creditId: record.creditId,
|
|
80
86
|
drawId: record.drawId,
|
|
81
87
|
fundingReceipt: record.fundingReceipt,
|
|
@@ -162,7 +162,7 @@ var LOCK_FILE = `${WALLET_FILE}.lock`;
|
|
|
162
162
|
var DEFAULT_LOCK_STALE_MS = 3e4;
|
|
163
163
|
var DEFAULT_LOCK_RETRIES = 30;
|
|
164
164
|
var DEFAULT_LOCK_RETRY_INTERVAL_MS = 1e3;
|
|
165
|
-
var WALLET_VERSION =
|
|
165
|
+
var WALLET_VERSION = 9;
|
|
166
166
|
var RECENT_SPENDS_CAP = 10;
|
|
167
167
|
var DEFAULT_AGENT_MINT_URL = "https://mint.coinos.io";
|
|
168
168
|
function loadAgentWallet() {
|
|
@@ -187,37 +187,54 @@ function loadAgentWallet() {
|
|
|
187
187
|
}
|
|
188
188
|
const version = parsed.version;
|
|
189
189
|
if (version === 1) {
|
|
190
|
-
return
|
|
191
|
-
|
|
190
|
+
return migrateV8ToV9(
|
|
191
|
+
migrateV7ToV8(
|
|
192
|
+
migrateV6ToV7(
|
|
193
|
+
migrateV5ToV6(migrateV4ToV5(migrateV1ToV4(parsed)))
|
|
194
|
+
)
|
|
195
|
+
)
|
|
192
196
|
);
|
|
193
197
|
}
|
|
194
198
|
if (version === 2) {
|
|
195
|
-
return
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
return migrateV8ToV9(
|
|
200
|
+
migrateV7ToV8(
|
|
201
|
+
migrateV6ToV7(
|
|
202
|
+
migrateV5ToV6(
|
|
203
|
+
migrateV4ToV5(migrateV3ToV4(migrateV2ToV3(parsed)))
|
|
204
|
+
)
|
|
199
205
|
)
|
|
200
206
|
)
|
|
201
207
|
);
|
|
202
208
|
}
|
|
203
209
|
if (version === 3) {
|
|
204
|
-
return
|
|
205
|
-
|
|
210
|
+
return migrateV8ToV9(
|
|
211
|
+
migrateV7ToV8(
|
|
212
|
+
migrateV6ToV7(
|
|
213
|
+
migrateV5ToV6(migrateV4ToV5(migrateV3ToV4(parsed)))
|
|
214
|
+
)
|
|
215
|
+
)
|
|
206
216
|
);
|
|
207
217
|
}
|
|
208
218
|
if (version === 4) {
|
|
209
|
-
return
|
|
210
|
-
|
|
219
|
+
return migrateV8ToV9(
|
|
220
|
+
migrateV7ToV8(
|
|
221
|
+
migrateV6ToV7(migrateV5ToV6(migrateV4ToV5(parsed)))
|
|
222
|
+
)
|
|
211
223
|
);
|
|
212
224
|
}
|
|
213
225
|
if (version === 5) {
|
|
214
|
-
return
|
|
226
|
+
return migrateV8ToV9(
|
|
227
|
+
migrateV7ToV8(migrateV6ToV7(migrateV5ToV6(parsed)))
|
|
228
|
+
);
|
|
215
229
|
}
|
|
216
230
|
if (version === 6) {
|
|
217
|
-
return migrateV7ToV8(migrateV6ToV7(parsed));
|
|
231
|
+
return migrateV8ToV9(migrateV7ToV8(migrateV6ToV7(parsed)));
|
|
218
232
|
}
|
|
219
233
|
if (version === 7) {
|
|
220
|
-
return migrateV7ToV8(parsed);
|
|
234
|
+
return migrateV8ToV9(migrateV7ToV8(parsed));
|
|
235
|
+
}
|
|
236
|
+
if (version === 8) {
|
|
237
|
+
return migrateV8ToV9(parsed);
|
|
221
238
|
}
|
|
222
239
|
if (version !== WALLET_VERSION) {
|
|
223
240
|
throw new DvmError(
|
|
@@ -366,6 +383,22 @@ function migrateV6ToV7(parsed) {
|
|
|
366
383
|
};
|
|
367
384
|
}
|
|
368
385
|
function migrateV7ToV8(parsed) {
|
|
386
|
+
return {
|
|
387
|
+
version: 8,
|
|
388
|
+
lock_privkey: String(parsed.lock_privkey),
|
|
389
|
+
lock_pubkey: String(parsed.lock_pubkey),
|
|
390
|
+
mnemonic_fingerprint: typeof parsed.mnemonic_fingerprint === "string" ? parsed.mnemonic_fingerprint : null,
|
|
391
|
+
mints: Array.isArray(parsed.mints) ? parsed.mints : [],
|
|
392
|
+
proofs: Array.isArray(parsed.proofs) ? parsed.proofs : [],
|
|
393
|
+
nut13_counters: isCounterMap(parsed.nut13_counters) ? parsed.nut13_counters : {},
|
|
394
|
+
pending_mints: Array.isArray(parsed.pending_mints) ? parsed.pending_mints : [],
|
|
395
|
+
pending_melts: Array.isArray(parsed.pending_melts) ? parsed.pending_melts : [],
|
|
396
|
+
pending_submissions: Array.isArray(parsed.pending_submissions) ? parsed.pending_submissions : [],
|
|
397
|
+
recent_spends: Array.isArray(parsed.recent_spends) ? parsed.recent_spends : [],
|
|
398
|
+
created_at: typeof parsed.created_at === "string" ? parsed.created_at : (/* @__PURE__ */ new Date()).toISOString()
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function migrateV8ToV9(parsed) {
|
|
369
402
|
return {
|
|
370
403
|
version: WALLET_VERSION,
|
|
371
404
|
lock_privkey: String(parsed.lock_privkey),
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Hono, Context } from 'hono';
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
|
-
import {
|
|
4
|
-
import { b as FxRateSnapshot, F as FxFetcher } from './fx-
|
|
5
|
-
import { g as LockPubkey, f as CheckMintHealthOptions, b as LightningBackend, A as AttestationPayload } from './lightning-backend-
|
|
6
|
-
import { T as TopUpCapUnenforcedReason, A as AppendOutgoingOptions, J as JobRecord, b as JobStore } from './job-store-
|
|
3
|
+
import { a1 as Message, ah as FundingMethod, X as FundingReceipt, bO as CreditSnapshot, Y as JobReceipt, S as SDKJobContext, aw as StepCache, u as ResponseContent, P as PaymentContent, a2 as MessageType, bj as X402Receipt, aE as X402Config, bi as X402ExactVersionSupport, cS as X402SettlementIntent, aq as PaymentRequirementsV2, c1 as CreditLedgerQuerier, cT as X402SettlementCursor, bQ as X402SettlementStatus, cU as X402SettlementWriteOff, bN as X402RefundSettlementGate, cV as X402FacilitatorAuth, cW as X402BatchSettlementConfig, cy as PostgresX402ChannelStorage, cX as X402PayoutObserver, br as MppxServer, ab as CashuMode, bM as CreditLedgerLike, cY as CreditDepositEnqueue, cZ as X402SettlementReconciliationReason, ao as PaymentRequirements, a0 as MppxCredential, o as PaymentMethod, bm as CreditDepositPayload, bP as DrawResult, cn as CreditLedgerError, a6 as ReceiptCredit, ae as DrainReceiptEvent, ad as DrainReceipt, K as KVStore, y as SignedRequestAudience, c_ as CreditDrawReleaseEnqueue, cx as JobCostReportPayload, cA as RevenueSkippedNoRailPayload, Z as ZodLike, a as DVMDescriptor, bV as CreditInvoiceRecord, bW as InvoiceSettlement, ch as ClientCompatibilityGate, cf as ClientCompatibility, bu as PayoutReporter, R as ResolvedCreditConfig, g as CreditView } from './step-cache-BLPZNizw.js';
|
|
4
|
+
import { b as FxRateSnapshot, F as FxFetcher } from './fx-C6dl2LVI.js';
|
|
5
|
+
import { g as LockPubkey, f as CheckMintHealthOptions, b as LightningBackend, A as AttestationPayload } from './lightning-backend-Ci1nogk_.js';
|
|
6
|
+
import { T as TopUpCapUnenforcedReason, A as AppendOutgoingOptions, J as JobRecord, b as JobStore } from './job-store-DHnW4Cg_.js';
|
|
7
7
|
import { ProofLike, SerializedDLEQ } from '@cashu/cashu-ts';
|
|
8
8
|
import { Challenge } from 'mppx';
|
|
9
9
|
import { SettleResponse, SupportedResponse } from '@x402/core/types';
|
|
@@ -239,6 +239,25 @@ interface ServerJob {
|
|
|
239
239
|
nativeAsset?: "sats" | "usdc" | "usdc.e" | "usd-cents";
|
|
240
240
|
/** Cashu flow discriminator written into `revenue_events.metadata.cashu_flow` (internal-review). */
|
|
241
241
|
cashuFlow?: "p2pk_accumulator";
|
|
242
|
+
/**
|
|
243
|
+
* What this job cost the **builder** to serve, in 1e-6 of
|
|
244
|
+
* {@link ServerJob.costCurrency} — the running total the handler declared
|
|
245
|
+
* through `ctx.cost()` (internal-review). Absent until a handler declares
|
|
246
|
+
* something; absent is "unreported", which is not the same fact as a
|
|
247
|
+
* declared zero and is reported differently.
|
|
248
|
+
*
|
|
249
|
+
* Persisted on the row rather than held in the context because the report
|
|
250
|
+
* has to survive a crash between the job finishing and the report landing:
|
|
251
|
+
* the terminal funnel writes this row before it books, and Postgres cost
|
|
252
|
+
* reconciliation retries any revision whose durable-enqueue marker still
|
|
253
|
+
* lags. Never netted against `paidMsats` or the draw — the builder's cost
|
|
254
|
+
* and the caller's payment are two questions.
|
|
255
|
+
*/
|
|
256
|
+
costAmountMicro?: number;
|
|
257
|
+
/** Currency {@link ServerJob.costAmountMicro} is 1e-6 of (lowercase ISO-4217). */
|
|
258
|
+
costCurrency?: string;
|
|
259
|
+
/** Number of `ctx.cost()` declarations incorporated into the current cost state. */
|
|
260
|
+
costRevision?: number;
|
|
242
261
|
/** Credit the upfront payment funded/drew (internal-review). See `JobRecord.creditId`. */
|
|
243
262
|
creditId?: string;
|
|
244
263
|
/** The draw placed for this job on `creditId` (internal-review). */
|
|
@@ -2702,6 +2721,8 @@ interface JobManagerOpts {
|
|
|
2702
2721
|
onJobCompleted?: (info: {
|
|
2703
2722
|
dvmId: string;
|
|
2704
2723
|
jobId: string;
|
|
2724
|
+
/** Dispatched capability. Omitted only for legacy persisted jobs that predate dispatch. */
|
|
2725
|
+
capability?: string;
|
|
2705
2726
|
paidMsats: number;
|
|
2706
2727
|
paymentMint?: string;
|
|
2707
2728
|
rail: string;
|
|
@@ -2709,6 +2730,10 @@ interface JobManagerOpts {
|
|
|
2709
2730
|
nativeAmount?: number;
|
|
2710
2731
|
nativeAsset?: string;
|
|
2711
2732
|
cashuFlow?: string;
|
|
2733
|
+
cost?: {
|
|
2734
|
+
amountMicro: number;
|
|
2735
|
+
currency: string;
|
|
2736
|
+
};
|
|
2712
2737
|
creditId?: string;
|
|
2713
2738
|
drawId?: string;
|
|
2714
2739
|
drawAmountMicro?: number;
|
|
@@ -2717,6 +2742,13 @@ interface JobManagerOpts {
|
|
|
2717
2742
|
fundingRef?: string;
|
|
2718
2743
|
kind?: string;
|
|
2719
2744
|
}) => void | Promise<void>;
|
|
2745
|
+
/**
|
|
2746
|
+
* Callback fired when a terminal job declared a builder cost but emitted no
|
|
2747
|
+
* revenue report (internal-review). Container-runtime DVMs use the reporter's
|
|
2748
|
+
* durable `job-cost` outbox path. The receiver de-duplicates by DVM + job,
|
|
2749
|
+
* independently of the rail-keyed revenue ledger.
|
|
2750
|
+
*/
|
|
2751
|
+
onJobCost?: (info: JobCostReportPayload) => void | Promise<void>;
|
|
2720
2752
|
/**
|
|
2721
2753
|
* Callback fired when the stale-job reaper force-fails a *paid* job — its
|
|
2722
2754
|
* pending credit draw is released rather than settled, because only a
|
|
@@ -2895,6 +2927,8 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
2895
2927
|
private readonly jobStore;
|
|
2896
2928
|
private readonly idleTimers;
|
|
2897
2929
|
private readonly cleanupTimers;
|
|
2930
|
+
/** Cost revisions held only by a terminal handler owner until its durable merge succeeds. */
|
|
2931
|
+
private readonly terminalCostHandoffRetryTimers;
|
|
2898
2932
|
/** Per-job NOTIFY unsubscribe handles for the durable-status watch (internal-review). */
|
|
2899
2933
|
private readonly statusWatchers;
|
|
2900
2934
|
/** Job ids whose durable-status re-read is in flight — coalesces notify storms (internal-review). */
|
|
@@ -2918,6 +2952,7 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
2918
2952
|
private staleSweepTimer?;
|
|
2919
2953
|
private heartbeatTimer?;
|
|
2920
2954
|
private orphanDrawSweepTimer?;
|
|
2955
|
+
private terminalCostRecoveryTimer?;
|
|
2921
2956
|
private jobRetentionSweepTimer?;
|
|
2922
2957
|
private jobRetentionBootTimer?;
|
|
2923
2958
|
/** This manager holds {@link ORPHAN_SWEEP_CLAIMS} for its ledger. */
|
|
@@ -2935,6 +2970,8 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
2935
2970
|
private readonly monotonicNowMs;
|
|
2936
2971
|
private sweepInFlight;
|
|
2937
2972
|
private orphanSweepInFlight;
|
|
2973
|
+
private terminalCostRecoveryInFlight;
|
|
2974
|
+
private terminalCostRecoveryResumeAfter?;
|
|
2938
2975
|
private jobRetentionSweepInFlight;
|
|
2939
2976
|
private heartbeatInFlight;
|
|
2940
2977
|
/**
|
|
@@ -3086,6 +3123,16 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
3086
3123
|
* stores' terminal-sticky `save`, which keeps the row itself correct).
|
|
3087
3124
|
*/
|
|
3088
3125
|
private adoptDurableTerminal;
|
|
3126
|
+
/**
|
|
3127
|
+
* Persist an adopted terminal cost, retaining the in-memory revision for a
|
|
3128
|
+
* later retry when the durable store is transiently unavailable.
|
|
3129
|
+
*/
|
|
3130
|
+
private tryPersistAdoptedTerminalCost;
|
|
3131
|
+
/** Retry outside the status watcher, which correctly stops once the job is terminal. */
|
|
3132
|
+
private scheduleTerminalCostHandoffRetry;
|
|
3133
|
+
private retryTerminalCostHandoff;
|
|
3134
|
+
/** Durably merge a terminal handler owner's latest cost before reporting it. */
|
|
3135
|
+
private persistAdoptedTerminalCost;
|
|
3089
3136
|
/**
|
|
3090
3137
|
* Watch the durable status of a locally-active job (internal-review).
|
|
3091
3138
|
*
|
|
@@ -3645,8 +3692,27 @@ declare class JobManager<State, InputSchema extends ZodLike | undefined> {
|
|
|
3645
3692
|
* from whatever the caller happened to have in hand.
|
|
3646
3693
|
*/
|
|
3647
3694
|
issueReceiptForStoredJob(jobId: string): Promise<JobReceipt | undefined>;
|
|
3695
|
+
/**
|
|
3696
|
+
* Finish accounting for a terminal written directly to the store — the
|
|
3697
|
+
* stale reaper and a cancel handled on a different machine (internal-review).
|
|
3698
|
+
*/
|
|
3699
|
+
finalizeStoredTerminal(jobId: string): Promise<JobReceipt | undefined>;
|
|
3648
3700
|
/** Handle job reaching terminal state (completed, failed, cancelled). */
|
|
3649
3701
|
private handleJobTerminal;
|
|
3702
|
+
/**
|
|
3703
|
+
* Re-enqueue terminal cost-only rows left between the job commit and outbox
|
|
3704
|
+
* insert. The marker advances only after `onJobCost` resolves, which for the
|
|
3705
|
+
* SDK reporter means the local durable insert has committed; a crash after
|
|
3706
|
+
* that insert but before the marker can duplicate a payload, but the
|
|
3707
|
+
* revisioned platform contract makes that replay harmless.
|
|
3708
|
+
*/
|
|
3709
|
+
recoverTerminalCosts(): Promise<{
|
|
3710
|
+
examined: number;
|
|
3711
|
+
queued: number;
|
|
3712
|
+
complete: boolean;
|
|
3713
|
+
}>;
|
|
3714
|
+
/** Report the latest declared-cost state only when no revenue event carried it. */
|
|
3715
|
+
private reportJobCost;
|
|
3650
3716
|
/**
|
|
3651
3717
|
* Report a completed paid job's revenue (internal-review, re-keyed by internal-review).
|
|
3652
3718
|
* Fire-and-forget — the `RevenueReporter` owns persistence and retry.
|
|
@@ -4435,6 +4501,12 @@ interface SDKServerOpts {
|
|
|
4435
4501
|
* tests and advanced integrations only.
|
|
4436
4502
|
*/
|
|
4437
4503
|
onJobCompleted?: JobManagerOpts["onJobCompleted"];
|
|
4504
|
+
/**
|
|
4505
|
+
* Advanced override for a declared cost on a terminal job that emitted no
|
|
4506
|
+
* revenue report (internal-review). Auto-wired to the reporter's durable
|
|
4507
|
+
* job-cost path; intended for tests and advanced integrations only.
|
|
4508
|
+
*/
|
|
4509
|
+
onJobCost?: JobManagerOpts["onJobCost"];
|
|
4438
4510
|
/**
|
|
4439
4511
|
* Advanced override: callback fired when the stale-job reaper force-fails a
|
|
4440
4512
|
* *paid* job (internal-review). Auto-wired to the `RevenueReporter`'s paid-job-death
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { C as Currency, Z as ZodLike, D as DVMConfig, a as DVMDescriptor } from './step-cache-
|
|
2
|
-
export { A as ApprovalContent, b as ArtifactContent, c as CancelContent, d as CanonicalEnvelope, e as CreateSignedRequestVerifierOpts, f as CreditConfig, g as CreditView, h as DEFAULT_CREDIT_MAX, i as DEFAULT_CREDIT_MIN, j as DEFAULT_CREDIT_TTL_SECONDS, k as DEFAULT_JOB_RETENTION_DAYS, l as DVMRouteContext, I as IncomingMessage, m as InputType, n as InvalidCurrencyError, K as KVStore, L as Logger, P as PaymentContent, o as PaymentMethod, p as PriceValue, q as ProgressContent, r as PromptOpts, Q as QuoteConfig, s as QuoteContext, t as QuoteResult, R as ResolvedCreditConfig, u as ResponseContent, S as SDKJobContext, v as SDKPaymentRequestOpts, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, y as SignedRequestAudience, z as SignedRequestDomain, B as SignedRequestError, E as SignedRequestFailure, F as SignedRequestReplayStore, G as SignedRequestSignOpts, H as SignedRequestStatementHeader,
|
|
3
|
-
export { C as CreateFxFetcherOpts, D as DEFAULT_FX_CURRENCIES, a as DEFAULT_FX_RATE_SOURCE, F as FxFetcher, b as FxRateSnapshot, c as FxRateUnavailableError, P as PlatformFxSource, d as createFxFetcher, f as fxRateFor, r as resolveFxSourceFromEnv } from './fx-
|
|
4
|
-
export { I as InvalidFxRateError, f as fiatToSatsCeil, a as formatFiat, b as formatUsd, r as roundUsd, s as satsToFiat } from './usd-
|
|
5
|
-
export { J as JobRecord, a as JobStatus, b as JobStore } from './job-store-
|
|
1
|
+
import { C as Currency, Z as ZodLike, D as DVMConfig, a as DVMDescriptor } from './step-cache-BLPZNizw.js';
|
|
2
|
+
export { A as ApprovalContent, b as ArtifactContent, c as CancelContent, d as CanonicalEnvelope, e as CreateSignedRequestVerifierOpts, f as CreditConfig, g as CreditView, h as DEFAULT_CREDIT_MAX, i as DEFAULT_CREDIT_MIN, j as DEFAULT_CREDIT_TTL_SECONDS, k as DEFAULT_JOB_RETENTION_DAYS, l as DVMRouteContext, I as IncomingMessage, m as InputType, n as InvalidCurrencyError, J as JobCost, K as KVStore, L as Logger, P as PaymentContent, o as PaymentMethod, p as PriceValue, q as ProgressContent, r as PromptOpts, Q as QuoteConfig, s as QuoteContext, t as QuoteResult, R as ResolvedCreditConfig, u as ResponseContent, S as SDKJobContext, v as SDKPaymentRequestOpts, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, y as SignedRequestAudience, z as SignedRequestDomain, B as SignedRequestError, E as SignedRequestFailure, F as SignedRequestReplayStore, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, U as UnsupportedCurrencyError, N as createSignedRequestVerifier, O as isZodSchema, T as signedRequestStatementHeader, V as validateCurrency } from './step-cache-BLPZNizw.js';
|
|
3
|
+
export { C as CreateFxFetcherOpts, D as DEFAULT_FX_CURRENCIES, a as DEFAULT_FX_RATE_SOURCE, F as FxFetcher, b as FxRateSnapshot, c as FxRateUnavailableError, P as PlatformFxSource, d as createFxFetcher, f as fxRateFor, r as resolveFxSourceFromEnv } from './fx-C6dl2LVI.js';
|
|
4
|
+
export { I as InvalidFxRateError, f as fiatToSatsCeil, a as formatFiat, b as formatUsd, r as roundUsd, s as satsToFiat } from './usd-BgOfZlk6.js';
|
|
5
|
+
export { J as JobRecord, a as JobStatus, b as JobStore } from './job-store-DHnW4Cg_.js';
|
|
6
6
|
export { P as PinnedFetch, S as SSRFError, a as SSRFGuardOpts, b as SSRFReason, c as SSRFResolver, d as assertSafeUrl, e as createPinnedFetch } from './ssrf-DbFkpDv0.js';
|
|
7
7
|
export { z } from 'zod';
|
|
8
8
|
import 'hono';
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { L as LightningTransactionListOptions, a as LightningTransactionSnapshot, b as LightningBackend, c as LightningPayment, d as LightningWalletInfo, C as CreatedInvoice, I as InvoiceStatus, M as MintAmountBounds, e as MintHealthCheckResult } from '../lightning-backend-
|
|
2
|
-
export { A as AttestationPayload, B as BuilderIdentityKeypair, f as CheckMintHealthOptions, g as LockPubkey, h as amountBoundsVerdict, i as assertNutSupport, j as buildAttestation, k as canSwap, l as checkMintHealth, m as generateIdentity, n as hashCapabilities, o as loadIdentitySecret, s as signAttestation, t as toLockPubkey, v as verifyAttestation, w as writeIdentity } from '../lightning-backend-
|
|
1
|
+
import { L as LightningTransactionListOptions, a as LightningTransactionSnapshot, b as LightningBackend, c as LightningPayment, d as LightningWalletInfo, C as CreatedInvoice, I as InvoiceStatus, M as MintAmountBounds, e as MintHealthCheckResult } from '../lightning-backend-Ci1nogk_.js';
|
|
2
|
+
export { A as AttestationPayload, B as BuilderIdentityKeypair, f as CheckMintHealthOptions, g as LockPubkey, h as amountBoundsVerdict, i as assertNutSupport, j as buildAttestation, k as canSwap, l as checkMintHealth, m as generateIdentity, n as hashCapabilities, o as loadIdentitySecret, s as signAttestation, t as toLockPubkey, v as verifyAttestation, w as writeIdentity } from '../lightning-backend-Ci1nogk_.js';
|
|
3
3
|
import { ProofLike, MeltQuoteBolt11Response, Proof, Wallet, SerializedDLEQ, MintQuoteBolt11Response, MintQuoteState, MintPreview, OutputDataLike, CounterSource, CounterRange } from '@cashu/cashu-ts';
|
|
4
4
|
export { g as getWallet } from '../wallet-CJC8lwxx.js';
|
|
5
|
-
import {
|
|
6
|
-
export {
|
|
5
|
+
import { W as JsonValue, z as SignedRequestDomain, H as SignedRequestStatementHeader, X as FundingReceipt, Y as JobReceipt$1, y as SignedRequestAudience, _ as PaymentRequired, $ as X402Version, a0 as MppxCredential, a1 as Message, a2 as MessageType, a3 as MppxChallenge, a4 as X402_BATCH_SETTLEMENT_SCHEME, a5 as X402_EXACT_SCHEME, a6 as ReceiptCredit, C as Currency, a7 as X402Wallet, L as Logger$1, K as KVStore, a8 as ResourceInfo } from '../step-cache-BLPZNizw.js';
|
|
6
|
+
export { a9 as BuildPaymentRequirementsOpts, aa as CapabilityDescriptor, ab as CashuMode, ac as CompleteContent, ad as DrainReceipt, ae as DrainReceiptEvent, af as ExactEvmPayload, ag as ExactEvmPayloadAuthorization, ah as FundingMethod, ai as MessageFrom, aj as PaymentPayload, ak as PaymentPayloadV1, al as PaymentPayloadV2, am as PaymentRequestContent, an as PaymentRequiredV2, ao as PaymentRequirements, ap as PaymentRequirementsV1, aq as PaymentRequirementsV2, ar as PromptContent, as as RAIL_REFUNDABLE, at as ReceiptOutcome, au as ReceiptPayment, av as SettleResponse, aw as StepCache, ax as StepRecord, ay as TextContent, az as UnsignedDrainReceipt, aA as UnsignedFundingReceipt, aB as UnsignedJobReceipt, aC as VerifyResponse, aD as WorkingContent, aE as X402Config, aF as X402ResponseBody, aG as X402SelfRelayRpcFailureReason, aH as X402_DEFAULT_NETWORK, aI as X402_V1_VERSION, aJ as X402_VERSION, aK as buildPaymentRequiredV2, aL as buildPaymentRequirements, aM as caip2ToX402Network, aN as canonicalRequestPath, aO as canonicaliseForSigning, aP as canonicalize, aQ as chainIdFromCaip2, aR as computeResultHash, aS as decodePayment, aT as decodePaymentRequiredHeader, aU as encodePayment, aV as encodePaymentRequiredHeader, aW as encodeSettleResponseHeader, aX as exactEvmAuthorization, aY as isArtifactMessage, aZ as isCancelMessage, a_ as isCompleteMessage, a$ as isDrainReceipt, b0 as isFundingReceipt, b1 as isPaymentRequestMessage, b2 as isPromptMessage, b3 as isSignedJobReceipt, b4 as isTextMessage, b5 as isWorkingMessage, b6 as paymentRequiredV2FromV1, b7 as signDrainReceipt, b8 as signFundingReceipt, b9 as signReceipt, ba as usdcContractByCaip2, bb as usdcContractFor, bc as usdcDomainNameFor, bd as usdcDomainVersionFor, be as verifyDrainReceipt, bf as verifyFundingReceipt, bg as verifyReceipt, bh as x402NetworkToCaip2 } from '../step-cache-BLPZNizw.js';
|
|
7
7
|
import { SimplePool } from 'nostr-tools/pool';
|
|
8
8
|
import { Session } from 'mppx/tempo';
|
|
9
9
|
import { Pool } from 'pg';
|
|
10
10
|
import { PaymentRequired as PaymentRequired$1 } from '@x402/core/types';
|
|
11
11
|
import { ClientChannelStorage, BatchSettlementClientContext, BatchSettlementEvmScheme } from '@x402/evm/batch-settlement/client';
|
|
12
|
-
export { e as FX_CACHE_TTL_MS, g as FX_RETRY_COUNT, w as warmFxSnapshot } from '../fx-
|
|
13
|
-
export { c as InvalidUsdPriceError, p as parseUsdPrice } from '../usd-
|
|
12
|
+
export { e as FX_CACHE_TTL_MS, g as FX_RETRY_COUNT, w as warmFxSnapshot } from '../fx-C6dl2LVI.js';
|
|
13
|
+
export { c as InvalidUsdPriceError, p as parseUsdPrice } from '../usd-BgOfZlk6.js';
|
|
14
14
|
import 'hono';
|
|
15
15
|
import 'mppx';
|
|
16
16
|
import '@x402/core/server';
|
|
@@ -5888,7 +5888,7 @@ interface SmartDenominationOptions {
|
|
|
5888
5888
|
declare function computeSmartDenominations(amountSats: number, opts?: SmartDenominationOptions): number[];
|
|
5889
5889
|
|
|
5890
5890
|
/** Current on-disk wallet schema version. Bumping requires a migration path. */
|
|
5891
|
-
declare const WALLET_VERSION:
|
|
5891
|
+
declare const WALLET_VERSION: 9;
|
|
5892
5892
|
/** Cap on the number of recent-spends entries persisted to the wallet. */
|
|
5893
5893
|
declare const RECENT_SPENDS_CAP = 10;
|
|
5894
5894
|
/**
|
|
@@ -6026,6 +6026,8 @@ interface PendingMint {
|
|
|
6026
6026
|
amount_sats: number;
|
|
6027
6027
|
/** ISO-8601 timestamp of the original `createMintQuote` call. */
|
|
6028
6028
|
requested_at: string;
|
|
6029
|
+
/** Quote expiry as unix seconds, when the mint supplied one. */
|
|
6030
|
+
expires_at?: number;
|
|
6029
6031
|
/** Pre-built blinded outputs, present only between `prepareMint` and `completeMint`. */
|
|
6030
6032
|
minting?: PendingMintMintingState;
|
|
6031
6033
|
}
|
|
@@ -6350,27 +6352,29 @@ interface AgentWallet {
|
|
|
6350
6352
|
}
|
|
6351
6353
|
/**
|
|
6352
6354
|
* Read `~/.dvm/wallet.json` and return the parsed wallet. Returns `null` if
|
|
6353
|
-
* the file does not exist. Migrates older wallets in-memory to
|
|
6354
|
-
* - v1 →
|
|
6355
|
+
* the file does not exist. Migrates older wallets in-memory to v9:
|
|
6356
|
+
* - v1 → v9: rejects populated proofs/pending_mints (the v1 shape predated
|
|
6355
6357
|
* the fund flow and is expected to be empty); fresh recent_spends,
|
|
6356
6358
|
* pending_submissions, nut13_counters; `mnemonic_fingerprint: null`.
|
|
6357
|
-
* - v2 →
|
|
6359
|
+
* - v2 → v9: preserves all v2 fields, adds empty recent_spends,
|
|
6358
6360
|
* pending_submissions, nut13_counters.
|
|
6359
|
-
* - v3 →
|
|
6361
|
+
* - v3 → v9: renames recovery_pubkey/recovery_privkey → lock_pubkey/lock_privkey;
|
|
6360
6362
|
* adds empty pending_submissions, nut13_counters.
|
|
6361
|
-
* - v4 →
|
|
6363
|
+
* - v4 → v9: adds empty pending_submissions (internal-review), nut13_counters
|
|
6362
6364
|
* (internal-review).
|
|
6363
|
-
* - v5 →
|
|
6365
|
+
* - v5 → v9: adds empty nut13_counters and a null mnemonic_fingerprint
|
|
6364
6366
|
* (internal-review). A v5 wallet inherits NUT-13 inactive — `getWallet` will
|
|
6365
6367
|
* stay in degraded mode until the user runs `dvm wallet restore
|
|
6366
6368
|
* <mnemonic>` to re-attach the sibling `~/.dvm/wallet.mnemonic`.
|
|
6367
|
-
* - v6 →
|
|
6369
|
+
* - v6 → v9: pass-through for the v7 step (internal-review). Existing proofs are
|
|
6368
6370
|
* free-balance, so `reserved_for` and `t_expire` remain unset;
|
|
6369
6371
|
* `dvm wallet reserve` populates them on new pre-fund proofs.
|
|
6370
|
-
* - v7 →
|
|
6372
|
+
* - v7 → v9: adds empty pending_melts (internal-review). No wallet predating the
|
|
6371
6373
|
* cash-out verb can have a melt in flight, so an empty list is exact.
|
|
6374
|
+
* - v8 → v9: preserves pending mints without `expires_at`; the recovery sweep
|
|
6375
|
+
* applies its bounded legacy fallback to those entries.
|
|
6372
6376
|
* Throws `DvmError("wallet_unknown_version", ...)` for files written by a
|
|
6373
|
-
* newer CLI so we never silently corrupt a future schema by treating it as
|
|
6377
|
+
* newer CLI so we never silently corrupt a future schema by treating it as v9.
|
|
6374
6378
|
*/
|
|
6375
6379
|
declare function loadAgentWallet(): AgentWallet | null;
|
|
6376
6380
|
/**
|
|
@@ -9257,6 +9261,10 @@ interface MeltSweepOptions {
|
|
|
9257
9261
|
abandonAfterMs?: number;
|
|
9258
9262
|
/** Override `getWallet`. */
|
|
9259
9263
|
getWalletForMint?: (mintUrl: string) => Promise<Wallet>;
|
|
9264
|
+
/** Maximum time spent retrying one transient quote-status read. Default 10 seconds. */
|
|
9265
|
+
quoteRetryTimeoutMs?: number;
|
|
9266
|
+
/** Sleep override for quote-status retry tests. */
|
|
9267
|
+
sleep?: (ms: number) => Promise<void>;
|
|
9260
9268
|
}
|
|
9261
9269
|
/**
|
|
9262
9270
|
* Reconcile every entry in `wallet.pending_melts[]` against its mint and
|
|
@@ -9557,10 +9565,14 @@ interface SweepResult {
|
|
|
9557
9565
|
interface SweepOptions {
|
|
9558
9566
|
/** Override `Date.now`. */
|
|
9559
9567
|
now?: () => number;
|
|
9560
|
-
/** Override
|
|
9568
|
+
/** Override the bounded fallback for legacy entries without a quote expiry. */
|
|
9561
9569
|
expirationMs?: number;
|
|
9562
9570
|
/** Override `getWallet`. */
|
|
9563
9571
|
getWalletForMint?: (mintUrl: string) => Promise<Wallet>;
|
|
9572
|
+
/** Maximum time spent retrying one transient quote-status read. Default 10 seconds. */
|
|
9573
|
+
quoteRetryTimeoutMs?: number;
|
|
9574
|
+
/** Sleep override for quote-status retry tests. */
|
|
9575
|
+
sleep?: (ms: number) => Promise<void>;
|
|
9564
9576
|
}
|
|
9565
9577
|
/**
|
|
9566
9578
|
* Reconcile every entry in `wallet.pending_mints[]` against its mint and
|