@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.
@@ -206,7 +206,7 @@ import {
206
206
  sha256hex,
207
207
  validateX402Env,
208
208
  withNwcPool
209
- } from "../chunk-EPNDZ5DH.js";
209
+ } from "../chunk-EDDYHZ6W.js";
210
210
  import {
211
211
  MemoryKVStore
212
212
  } from "../chunk-RW5LP57K.js";
@@ -285,7 +285,7 @@ import {
285
285
  withWalletLock,
286
286
  writeAgentMnemonic,
287
287
  writeIdentity
288
- } from "../chunk-2K7E3N2D.js";
288
+ } from "../chunk-VRQDX5P4.js";
289
289
  import {
290
290
  X402_BATCH_SETTLEMENT_SCHEME,
291
291
  X402_DEFAULT_FACILITATOR,
@@ -394,7 +394,7 @@ import {
394
394
  randomTraceId,
395
395
  setEmitter,
396
396
  withTraceContext
397
- } from "../chunk-YDIYXGYL.js";
397
+ } from "../chunk-E4EVGPDX.js";
398
398
  import "../chunk-66HGCPBU.js";
399
399
  import {
400
400
  redactUrl,
@@ -2469,6 +2469,80 @@ function normalizeCap(raw2) {
2469
2469
 
2470
2470
  // src/lib/wallet-agent/fund.ts
2471
2471
  import { MintQuoteState } from "@cashu/cashu-ts";
2472
+
2473
+ // src/lib/wallet-agent/mint-quote-retry.ts
2474
+ var MINT_QUOTE_RETRY_BASE_DELAY_MS = 2e3;
2475
+ var MINT_QUOTE_RETRY_MAX_DELAY_MS = 6e4;
2476
+ var MINT_QUOTE_RETRY_DECAY_FACTOR = 4;
2477
+ function createMintQuoteRetryState() {
2478
+ return { backoffMs: 0 };
2479
+ }
2480
+ async function retryMintQuoteOperation(operation, opts) {
2481
+ const now = opts.now ?? (() => Date.now());
2482
+ const sleep2 = opts.sleep ?? defaultSleep;
2483
+ const state = opts.state ?? createMintQuoteRetryState();
2484
+ for (; ; ) {
2485
+ try {
2486
+ return await operation();
2487
+ } catch (err) {
2488
+ const cause = classifyMintQuoteError(err);
2489
+ if (cause === void 0) throw err;
2490
+ const failedAt = now();
2491
+ if (state.lastRetryAt !== void 0 && failedAt - state.lastRetryAt >= state.backoffMs * MINT_QUOTE_RETRY_DECAY_FACTOR) {
2492
+ state.backoffMs = 0;
2493
+ }
2494
+ const grownDelay = Math.min(
2495
+ Math.max(state.backoffMs * 2, MINT_QUOTE_RETRY_BASE_DELAY_MS),
2496
+ MINT_QUOTE_RETRY_MAX_DELAY_MS
2497
+ );
2498
+ const retryAfterMs = mintRetryAfterMs(err);
2499
+ const delayMs = Math.min(
2500
+ Math.max(retryAfterMs ?? grownDelay, MINT_QUOTE_RETRY_BASE_DELAY_MS),
2501
+ MINT_QUOTE_RETRY_MAX_DELAY_MS
2502
+ );
2503
+ const remainingMs = Math.max(0, opts.deadlineMs - failedAt);
2504
+ state.backoffMs = delayMs;
2505
+ if (remainingMs > 0) {
2506
+ await sleep2(Math.min(delayMs, remainingMs));
2507
+ state.lastRetryAt = now();
2508
+ }
2509
+ if (now() >= opts.deadlineMs) {
2510
+ throw mintQuoteUnavailableError(opts.quoteId, cause, delayMs);
2511
+ }
2512
+ }
2513
+ }
2514
+ }
2515
+ function classifyMintQuoteError(err) {
2516
+ if (typeof err !== "object" || err === null) return void 0;
2517
+ const { name, status, code } = err;
2518
+ if (name === "RateLimitError" || status === 429) return "rate_limited";
2519
+ if (typeof status === "number" && status >= 500) return "mint_server_error";
2520
+ if (name === "NetworkError" || code === "cashu_mint_unreachable") return "mint_unreachable";
2521
+ return void 0;
2522
+ }
2523
+ function mintRetryAfterMs(err) {
2524
+ if (typeof err !== "object" || err === null) return void 0;
2525
+ const value = err.retryAfterMs;
2526
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
2527
+ }
2528
+ function mintQuoteUnavailableError(quoteId, cause, retryAfterMs) {
2529
+ return new DvmError(
2530
+ "mint_quote_poll_unavailable",
2531
+ `The mint did not answer status checks for quote ${quoteId} before the wait ended.`,
2532
+ "The quote may still settle. Reconcile the existing quote later instead of starting another payment.",
2533
+ {
2534
+ quote_id: quoteId,
2535
+ cause,
2536
+ retryable: true,
2537
+ retry_after_ms: retryAfterMs
2538
+ }
2539
+ );
2540
+ }
2541
+ function defaultSleep(ms) {
2542
+ return new Promise((resolve) => setTimeout(resolve, ms));
2543
+ }
2544
+
2545
+ // src/lib/wallet-agent/fund.ts
2472
2546
  var DEFAULT_POLL_INTERVAL_MS = 2e3;
2473
2547
  var DEFAULT_TIMEOUT_SEC = 600;
2474
2548
  async function fundAgentWallet(amountSats, opts) {
@@ -2494,7 +2568,8 @@ async function fundAgentWallet(amountSats, opts) {
2494
2568
  mint: opts.mintUrl,
2495
2569
  quote_id: quote.quote,
2496
2570
  amount_sats: sats,
2497
- requested_at: (/* @__PURE__ */ new Date()).toISOString()
2571
+ requested_at: (/* @__PURE__ */ new Date()).toISOString(),
2572
+ ...quote.expiry === null ? {} : { expires_at: quote.expiry }
2498
2573
  };
2499
2574
  await withWalletLock(() => {
2500
2575
  const fresh = loadAgentWallet() ?? initial;
@@ -2605,23 +2680,35 @@ function maxKeysetDenomination(cashuWallet) {
2605
2680
  }
2606
2681
  async function pollUntilPaidOrTimeout(cashuWallet, quoteId, opts) {
2607
2682
  const now = opts.now ?? (() => Date.now());
2608
- const sleep2 = opts.sleep ?? defaultSleep;
2683
+ const sleep2 = opts.sleep ?? defaultSleep2;
2609
2684
  const intervalMs = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
2610
2685
  const timeoutMs = opts.timeoutMs ?? fundTimeoutMs();
2611
2686
  const start = now();
2687
+ const deadline = start + timeoutMs;
2688
+ const retryState = createMintQuoteRetryState();
2612
2689
  let lastState = MintQuoteState.UNPAID;
2613
- while (now() - start < timeoutMs) {
2614
- const checked = await cashuWallet.checkMintQuoteBolt11(quoteId);
2690
+ while (now() < deadline) {
2691
+ const checked = await retryMintQuoteOperation(
2692
+ () => cashuWallet.checkMintQuoteBolt11(quoteId),
2693
+ {
2694
+ deadlineMs: deadline,
2695
+ quoteId,
2696
+ state: retryState,
2697
+ now,
2698
+ sleep: sleep2
2699
+ }
2700
+ );
2615
2701
  lastState = checked.state;
2616
2702
  if (opts.onPoll) opts.onPoll(lastState, now() - start);
2617
2703
  if (lastState === MintQuoteState.PAID || lastState === MintQuoteState.ISSUED) {
2618
2704
  return lastState;
2619
2705
  }
2620
- await sleep2(intervalMs);
2706
+ const remainingMs = deadline - now();
2707
+ if (remainingMs > 0) await sleep2(Math.min(intervalMs, remainingMs));
2621
2708
  }
2622
2709
  return lastState;
2623
2710
  }
2624
- function defaultSleep(ms) {
2711
+ function defaultSleep2(ms) {
2625
2712
  return new Promise((resolve) => setTimeout(resolve, ms));
2626
2713
  }
2627
2714
 
@@ -2908,6 +2995,7 @@ async function receiveToAgentWallet(token, opts = {}) {
2908
2995
 
2909
2996
  // src/lib/wallet-agent/recovery.ts
2910
2997
  import { MintQuoteState as MintQuoteState2 } from "@cashu/cashu-ts";
2998
+ var DEFAULT_SWEEP_QUOTE_RETRY_TIMEOUT_MS = 1e4;
2911
2999
  async function sweepPendingMints(opts = {}) {
2912
3000
  const wallet = loadAgentWallet();
2913
3001
  if (!wallet || wallet.pending_mints.length === 0) {
@@ -2916,9 +3004,14 @@ async function sweepPendingMints(opts = {}) {
2916
3004
  const now = opts.now ?? (() => Date.now());
2917
3005
  const expirationMs = opts.expirationMs ?? fundTimeoutMs();
2918
3006
  const getWalletForMint = opts.getWalletForMint ?? getWallet;
3007
+ const quoteRetryTimeoutMs = opts.quoteRetryTimeoutMs ?? DEFAULT_SWEEP_QUOTE_RETRY_TIMEOUT_MS;
2919
3008
  const outcomes = [];
2920
3009
  for (const entry of wallet.pending_mints) {
2921
- const outcome = await processEntry(wallet, entry, now(), expirationMs, getWalletForMint);
3010
+ const outcome = await processEntry(wallet, entry, now(), expirationMs, getWalletForMint, {
3011
+ now,
3012
+ sleep: opts.sleep,
3013
+ timeoutMs: quoteRetryTimeoutMs
3014
+ });
2922
3015
  outcomes.push(outcome);
2923
3016
  }
2924
3017
  if (outcomes.some(
@@ -2941,21 +3034,27 @@ async function sweepPendingMints(opts = {}) {
2941
3034
  errors: outcomes.filter((o) => o.kind === "error").map((o) => ({ quote_id: o.entry.quote_id, error: o.error }))
2942
3035
  };
2943
3036
  }
2944
- async function processEntry(wallet, entry, nowMs, expirationMs, getWalletForMint) {
3037
+ async function processEntry(wallet, entry, nowMs, expirationMs, getWalletForMint, retry) {
2945
3038
  let cashuWallet;
2946
- try {
2947
- cashuWallet = await getWalletForMint(entry.mint);
2948
- } catch (err) {
2949
- return { kind: "error", entry, error: errorMessage2(err) };
2950
- }
2951
- let state;
2952
3039
  let quoteResponse;
2953
3040
  try {
2954
- quoteResponse = await cashuWallet.checkMintQuoteBolt11(entry.quote_id);
2955
- state = quoteResponse.state;
3041
+ ({ cashuWallet, quoteResponse } = await retryMintQuoteOperation(
3042
+ async () => {
3043
+ const candidate = await getWalletForMint(entry.mint);
3044
+ const quote = await candidate.checkMintQuoteBolt11(entry.quote_id);
3045
+ return { cashuWallet: candidate, quoteResponse: quote };
3046
+ },
3047
+ {
3048
+ deadlineMs: retry.now() + retry.timeoutMs,
3049
+ quoteId: entry.quote_id,
3050
+ now: retry.now,
3051
+ sleep: retry.sleep
3052
+ }
3053
+ ));
2956
3054
  } catch (err) {
2957
3055
  return { kind: "error", entry, error: errorMessage2(err) };
2958
3056
  }
3057
+ const state = quoteResponse.state;
2959
3058
  if (state === MintQuoteState2.ISSUED) {
2960
3059
  if (!entry.minting) {
2961
3060
  return { kind: "already_issued", entry };
@@ -3009,6 +3108,13 @@ async function processEntry(wallet, entry, nowMs, expirationMs, getWalletForMint
3009
3108
  return { kind: "error", entry, error: errorMessage2(err) };
3010
3109
  }
3011
3110
  }
3111
+ const quoteExpiry = entry.expires_at;
3112
+ if (quoteExpiry !== void 0 && Number.isFinite(quoteExpiry)) {
3113
+ if (nowMs > quoteExpiry * 1e3) {
3114
+ return { kind: "expired", entry };
3115
+ }
3116
+ return { kind: "still_pending", entry };
3117
+ }
3012
3118
  const requestedAtMs = Date.parse(entry.requested_at);
3013
3119
  const ageMs2 = Number.isFinite(requestedAtMs) ? nowMs - requestedAtMs : Infinity;
3014
3120
  if (ageMs2 > expirationMs) {
@@ -3038,6 +3144,7 @@ function errorMessage2(err) {
3038
3144
  }
3039
3145
 
3040
3146
  // src/lib/wallet-agent/recovery-melt.ts
3147
+ var DEFAULT_SWEEP_QUOTE_RETRY_TIMEOUT_MS2 = 1e4;
3041
3148
  async function sweepPendingMelts(opts = {}) {
3042
3149
  const wallet = loadAgentWallet();
3043
3150
  if (!wallet || wallet.pending_melts.length === 0) {
@@ -3046,9 +3153,16 @@ async function sweepPendingMelts(opts = {}) {
3046
3153
  const now = opts.now ?? (() => Date.now());
3047
3154
  const abandonAfterMs = opts.abandonAfterMs ?? meltInFlightTimeoutSeconds() * 1e3;
3048
3155
  const getWalletForMint = opts.getWalletForMint ?? getWallet;
3156
+ const quoteRetryTimeoutMs = opts.quoteRetryTimeoutMs ?? DEFAULT_SWEEP_QUOTE_RETRY_TIMEOUT_MS2;
3049
3157
  const outcomes = [];
3050
3158
  for (const entry of wallet.pending_melts) {
3051
- outcomes.push(await processEntry2(wallet, entry, now(), abandonAfterMs, getWalletForMint));
3159
+ outcomes.push(
3160
+ await processEntry2(wallet, entry, now(), abandonAfterMs, getWalletForMint, {
3161
+ now,
3162
+ sleep: opts.sleep,
3163
+ timeoutMs: quoteRetryTimeoutMs
3164
+ })
3165
+ );
3052
3166
  }
3053
3167
  if (outcomes.some((o) => o.kind === "settled" || o.kind === "reverted")) {
3054
3168
  await withWalletLock(() => {
@@ -3066,17 +3180,23 @@ async function sweepPendingMelts(opts = {}) {
3066
3180
  errors: outcomes.filter((o) => o.kind === "error").map((o) => ({ quote_id: o.entry.quote_id, error: o.error }))
3067
3181
  };
3068
3182
  }
3069
- async function processEntry2(wallet, entry, nowMs, abandonAfterMs, getWalletForMint) {
3183
+ async function processEntry2(wallet, entry, nowMs, abandonAfterMs, getWalletForMint, retry) {
3070
3184
  let cashuWallet;
3071
- try {
3072
- cashuWallet = await getWalletForMint(entry.mint);
3073
- } catch (err) {
3074
- return { kind: "error", entry, error: errorMessage3(err) };
3075
- }
3076
3185
  let state;
3077
3186
  try {
3078
- const quote = await cashuWallet.checkMeltQuoteBolt11(entry.quote_id);
3079
- state = quote.state;
3187
+ ({ cashuWallet, state } = await retryMintQuoteOperation(
3188
+ async () => {
3189
+ const candidate = await getWalletForMint(entry.mint);
3190
+ const quote = await candidate.checkMeltQuoteBolt11(entry.quote_id);
3191
+ return { cashuWallet: candidate, state: quote.state };
3192
+ },
3193
+ {
3194
+ deadlineMs: retry.now() + retry.timeoutMs,
3195
+ quoteId: entry.quote_id,
3196
+ now: retry.now,
3197
+ sleep: retry.sleep
3198
+ }
3199
+ ));
3080
3200
  } catch (err) {
3081
3201
  return { kind: "error", entry, error: errorMessage3(err) };
3082
3202
  }
@@ -5415,7 +5535,8 @@ async function reserveAgentWallet(amountSats, opts) {
5415
5535
  mint: opts.mintUrl,
5416
5536
  quote_id: quote.quote,
5417
5537
  amount_sats: sats,
5418
- requested_at: (/* @__PURE__ */ new Date()).toISOString()
5538
+ requested_at: (/* @__PURE__ */ new Date()).toISOString(),
5539
+ ...quote.expiry === null ? {} : { expires_at: quote.expiry }
5419
5540
  };
5420
5541
  await withWalletLock(() => {
5421
5542
  const fresh = loadAgentWallet() ?? initial;
@@ -1,23 +1,23 @@
1
1
  import { FacilitatorConfig } from '@x402/core/server';
2
- import { ai as PaymentPayload, ao as PaymentRequirementsV1, ap as PaymentRequirementsV2, aD as X402Config, au as SettleResponse, aB as VerifyResponse, bh as X402ExactVersionSupport, bi as X402Receipt, bj as TransactionalPayoutHook, bk as CashuMeltCompleted } from '../step-cache-3cT4Shk0.js';
3
- export { bl as CreditDepositPayload, bm as CreditDrainPayload, bn as FundingLot, bo as LotDebit, bp as LotDepletion, bq as MppxServer, br as NON_CHANNEL_BITCOIN_RAILS, bs as NonChannelBitcoinRail, bt as PayoutReporter, bu as PostgresTempoSessionStore, bv as RevenueReporter, bw as SIGNED_ENVELOPE_FIELDS, bx as SIGNED_ENVELOPE_TYPES, by as X402TrackedChannel, bz as _testing, bA as createDefaultReplayStore, bB as depleteLots, bC as fifoOrder, bD as inKindDrawMsats, bE as isInKindDepletion, bF as isNonChannelBitcoinRail, bG as lotOwedSats, bH as netOwedSats, bI as wrapMppx } from '../step-cache-3cT4Shk0.js';
2
+ import { aj as PaymentPayload, ap as PaymentRequirementsV1, aq as PaymentRequirementsV2, aE as X402Config, av as SettleResponse, aC as VerifyResponse, bi as X402ExactVersionSupport, bj as X402Receipt, bk as TransactionalPayoutHook, bl as CashuMeltCompleted } from '../step-cache-BLPZNizw.js';
3
+ export { bm as CreditDepositPayload, bn as CreditDrainPayload, bo as FundingLot, bp as LotDebit, bq as LotDepletion, br as MppxServer, bs as NON_CHANNEL_BITCOIN_RAILS, bt as NonChannelBitcoinRail, bu as PayoutReporter, bv as PostgresTempoSessionStore, bw as RevenueReporter, bx as SIGNED_ENVELOPE_FIELDS, by as SIGNED_ENVELOPE_TYPES, bz as X402TrackedChannel, bA as _testing, bB as createDefaultReplayStore, bC as depleteLots, bD as fifoOrder, bE as inKindDrawMsats, bF as isInKindDepletion, bG as isNonChannelBitcoinRail, bH as lotOwedSats, bI as netOwedSats, bJ as wrapMppx } from '../step-cache-BLPZNizw.js';
4
4
  import { Hono } from 'hono';
5
5
  import { Env, BlankSchema } from 'hono/types';
6
6
  import { Pool } from 'pg';
7
7
  export { Pool } from 'pg';
8
8
  import { g as getWallet } from '../wallet-CJC8lwxx.js';
9
- import { A as AccumulatorPool, a as AccumulatorQuerier, C as ConsumedCredentialStore } from '../credit-menu-C7zAJElJ.js';
10
- export { b as AppEnv, c as CreditFundingReport, F as FiatDenomination, d as FiatDenominationFailure, e as FundOnlyRequest, I as IncomingPaymentOpts, J as JobCancelledError, M as MintHealthTracker, P as PAYMENT_PROOF_KEYS, f as PaymentErrorCode, g as PaymentErrorDetail, h as PaymentInfo, R as ReporterBannerOpts, i as ResolvedFx, j as RevenueBootCheckOpts, S as SDKServerOpts, k as ServerJob, l as ShortPayForfeit, T as TempoChannelReport, m as TempoObserverHealth, n as TempoSessionChannelMismatchError, U as UpfrontPaymentOpts, V as VerifiedIncomingPayment, o as VerifyIncomingSnapshot, X as X402BatchChannelObservation, p as X402FacilitatorHealth, q as X402SettlementEvidenceOutcome, r as X402SettlementRepair, s as X402SettlementRepairRefusal, t as X402SettlementRepaired, u as X402WedgedSettlement, v as X402WedgedSettlementPage, w as X402_BATCH_SETTLEMENT_MAINNET_NETWORK, x as abortJob, y as applyPaymentInfoToJob, z as assertRevenueReporterReady, B as buildPaymentErrorResponse, D as clearAccumulatorForDvm, E as createDVMServer, G as creditDepositPayload, H as derivedFundCreditId, K as devModeSkipsPaymentVerification, L as fromJobRecord, N as fundedMicroFor, O as hasPaymentProof, Q as hashLockKey, W as implicitCreditId, Y as initWalletAccumulatorTable, Z as insertAccumulatorRows, _ as isDerivedCreditId, $ as isTerminal, a0 as isYieldMessage, a1 as issueUpfrontChallenges, a2 as msatsToFiatMicro, a3 as paymentErrorBody, a4 as pinAskFiat, a5 as priceFiatMicro, a6 as processIncomingPayment, a7 as providerMessage, a8 as repairX402ExactSettlementEffect, a9 as resolveFxSnapshot, aa as resolvePriceFiat, ab as revenueReporterBannerState, ac as toCreditTerms, ad as toJobRecord, ae as unknownRouteNotFound, af as verifyIncomingPayment, ag as verifyTempoSessionManagementCredential, ah as verifyUpfrontPayment, ai as x402RequiredUsdcMicro, aj as x402SettledShare } from '../credit-menu-C7zAJElJ.js';
11
- import { g as LockPubkey } from '../lightning-backend-C04nH94l.js';
12
- export { t as lockPubkeyStoreToLockPubkey } from '../lightning-backend-C04nH94l.js';
13
- export { O as OutgoingMessage, S as StaleJobReapable, i as isStaleJobReapable } from '../job-store-Bn23V3QU.js';
9
+ import { A as AccumulatorPool, a as AccumulatorQuerier, C as ConsumedCredentialStore } from '../credit-menu-C1ezIFlJ.js';
10
+ export { b as AppEnv, c as CreditFundingReport, F as FiatDenomination, d as FiatDenominationFailure, e as FundOnlyRequest, I as IncomingPaymentOpts, J as JobCancelledError, M as MintHealthTracker, P as PAYMENT_PROOF_KEYS, f as PaymentErrorCode, g as PaymentErrorDetail, h as PaymentInfo, R as ReporterBannerOpts, i as ResolvedFx, j as RevenueBootCheckOpts, S as SDKServerOpts, k as ServerJob, l as ShortPayForfeit, T as TempoChannelReport, m as TempoObserverHealth, n as TempoSessionChannelMismatchError, U as UpfrontPaymentOpts, V as VerifiedIncomingPayment, o as VerifyIncomingSnapshot, X as X402BatchChannelObservation, p as X402FacilitatorHealth, q as X402SettlementEvidenceOutcome, r as X402SettlementRepair, s as X402SettlementRepairRefusal, t as X402SettlementRepaired, u as X402WedgedSettlement, v as X402WedgedSettlementPage, w as X402_BATCH_SETTLEMENT_MAINNET_NETWORK, x as abortJob, y as applyPaymentInfoToJob, z as assertRevenueReporterReady, B as buildPaymentErrorResponse, D as clearAccumulatorForDvm, E as createDVMServer, G as creditDepositPayload, H as derivedFundCreditId, K as devModeSkipsPaymentVerification, L as fromJobRecord, N as fundedMicroFor, O as hasPaymentProof, Q as hashLockKey, W as implicitCreditId, Y as initWalletAccumulatorTable, Z as insertAccumulatorRows, _ as isDerivedCreditId, $ as isTerminal, a0 as isYieldMessage, a1 as issueUpfrontChallenges, a2 as msatsToFiatMicro, a3 as paymentErrorBody, a4 as pinAskFiat, a5 as priceFiatMicro, a6 as processIncomingPayment, a7 as providerMessage, a8 as repairX402ExactSettlementEffect, a9 as resolveFxSnapshot, aa as resolvePriceFiat, ab as revenueReporterBannerState, ac as toCreditTerms, ad as toJobRecord, ae as unknownRouteNotFound, af as verifyIncomingPayment, ag as verifyTempoSessionManagementCredential, ah as verifyUpfrontPayment, ai as x402RequiredUsdcMicro, aj as x402SettledShare } from '../credit-menu-C1ezIFlJ.js';
11
+ import { g as LockPubkey } from '../lightning-backend-Ci1nogk_.js';
12
+ export { t as lockPubkeyStoreToLockPubkey } from '../lightning-backend-Ci1nogk_.js';
13
+ export { O as OutgoingMessage, S as StaleJobReapable, i as isStaleJobReapable } from '../job-store-DHnW4Cg_.js';
14
14
  import { Store } from 'mppx';
15
15
  import { z } from 'zod';
16
16
  import '@x402/evm/batch-settlement/server';
17
17
  import 'viem';
18
18
  import '@x402/core/types';
19
19
  import '@cashu/cashu-ts';
20
- import '../fx-BF_SG2i0.js';
20
+ import '../fx-C6dl2LVI.js';
21
21
 
22
22
  /** POST a verify request to the configured facilitator. */
23
23
  declare function verifyWithFacilitator(payload: PaymentPayload, requirements: PaymentRequirementsV1 | PaymentRequirementsV2, config?: Pick<X402Config, "facilitator" | "facilitatorAuth">, createAuthHeaders?: FacilitatorConfig["createAuthHeaders"] | undefined): Promise<VerifyResponse>;
@@ -6,7 +6,7 @@ import {
6
6
  } from "../chunk-BIFLRKMO.js";
7
7
  import {
8
8
  RevenueReporter
9
- } from "../chunk-NFRM5QYP.js";
9
+ } from "../chunk-EVBK675R.js";
10
10
  import {
11
11
  PayoutReporter
12
12
  } from "../chunk-6BQM7TOW.js";
@@ -65,7 +65,7 @@ import {
65
65
  verifyUpfrontPayment,
66
66
  x402RequiredUsdcMicro,
67
67
  x402SettledShare
68
- } from "../chunk-3ZHMQCYP.js";
68
+ } from "../chunk-QK3VJNCK.js";
69
69
  import "../chunk-DMNLFNTW.js";
70
70
  import {
71
71
  settleWithFacilitator,
@@ -88,15 +88,15 @@ import {
88
88
  isYieldMessage,
89
89
  providerMessage,
90
90
  toJobRecord
91
- } from "../chunk-4B56DEEV.js";
91
+ } from "../chunk-U6M3ATSG.js";
92
92
  import {
93
93
  toLockPubkey
94
- } from "../chunk-2K7E3N2D.js";
94
+ } from "../chunk-VRQDX5P4.js";
95
95
  import "../chunk-Z4BNLUZF.js";
96
96
  import "../chunk-5URG56JJ.js";
97
97
  import "../chunk-MKI6OVW4.js";
98
98
  import "../chunk-KXZUCCEY.js";
99
- import "../chunk-YDIYXGYL.js";
99
+ import "../chunk-E4EVGPDX.js";
100
100
  import "../chunk-66HGCPBU.js";
101
101
  import "../chunk-FUJ36YDV.js";
102
102
  import "../chunk-27V2ILSR.js";
@@ -1,5 +1,5 @@
1
1
  import { ProofLike } from '@cashu/cashu-ts';
2
- import { a0 as Message, ag as FundingMethod, W as FundingReceipt, bN as CreditSnapshot, X as JobReceipt, aw as StepRecord, a1 as MessageType } from './step-cache-3cT4Shk0.js';
2
+ import { a1 as Message, ah as FundingMethod, X as FundingReceipt, bO as CreditSnapshot, Y as JobReceipt, ax as StepRecord, a2 as MessageType } from './step-cache-BLPZNizw.js';
3
3
 
4
4
  /** Job status values that can be persisted. */
5
5
  type JobStatus = "processing" | "completed" | "failed" | "awaiting-input" | "cancelled" | "working";
@@ -81,6 +81,21 @@ interface JobRecord {
81
81
  nativeAsset?: "sats" | "usdc" | "usdc.e" | "usd-cents";
82
82
  /** Cashu flow discriminator written into `revenue_events.metadata.cashu_flow` (internal-review). */
83
83
  cashuFlow?: "p2pk_accumulator";
84
+ /**
85
+ * What this job cost the **builder** to serve, in 1e-6 of
86
+ * {@link JobRecord.costCurrency} (internal-review). Mirror of
87
+ * `ServerJob.costAmountMicro`; see that field. Absent means unreported,
88
+ * which the platform treats differently from a declared zero.
89
+ */
90
+ costAmountMicro?: number;
91
+ /** Currency {@link JobRecord.costAmountMicro} is 1e-6 of (lowercase ISO-4217). */
92
+ costCurrency?: string;
93
+ /**
94
+ * Number of `ctx.cost()` declarations incorporated into the current cost
95
+ * state. Lets the platform deterministically replace a stale persisted
96
+ * prefix with the handler owner's later cumulative value.
97
+ */
98
+ costRevision?: number;
84
99
  /**
85
100
  * Credit the upfront payment funded/drew (internal-review). The terminal funnel
86
101
  * settles the draw on success and releases it on failure/cancel, and the
@@ -1,4 +1,4 @@
1
- import { V as JsonValue } from './step-cache-3cT4Shk0.js';
1
+ import { W as JsonValue } from './step-cache-BLPZNizw.js';
2
2
 
3
3
  declare const lockPubkeyBrand: unique symbol;
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  PostgresJobStore
3
- } from "./chunk-LLXV32HA.js";
3
+ } from "./chunk-SSSZUVWM.js";
4
4
  import "./chunk-S3XAHZQY.js";
5
5
  export {
6
6
  PostgresJobStore
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RevenueReporter
3
- } from "./chunk-NFRM5QYP.js";
3
+ } from "./chunk-EVBK675R.js";
4
4
  import "./chunk-S3XAHZQY.js";
5
5
  export {
6
6
  RevenueReporter
@@ -1,20 +1,20 @@
1
- import { aa as CashuMode, bJ as CreditDrainEnqueue, R as ResolvedCreditConfig, bK as DVMAuthScheme, z as SignedRequestDomain, bL as CreditLedgerLike, bM as X402RefundSettlementGate, bN as CreditSnapshot, bO as DrawResult, bP as X402SettlementStatus, bQ as X402UnresolvedRefund, bR as GrownDrawResult, bS as DrawResolution, bT as FundingRecord, W as FundingReceipt, bU as CreditInvoiceRecord, bV as InvoiceSettlement, bW as BlockedInvoiceCursor, bX as InvoiceReconciliation, bY as InvoiceWriteOff, bZ as DrawRecord, b_ as StalePendingDrawCursor, b$ as TempoCreditLossEvidence, c0 as CreditLedgerQuerier, c1 as TempoCreditLoss, c2 as X402CreditLossEvidence, c3 as X402CreditLoss, c4 as DrainMethod, c5 as DrainRequestResult, c6 as BitcoinDepositLiability, bn as FundingLot, c7 as CreditDrainRecord, c8 as ChannelDrainCursor, c9 as DrainWriteOff, ca as DrainReleaseResult, cb as DrainFulfilment, cc as DrainTransitionResult, X as JobReceipt, a0 as Message, K as KVStore, F as SignedRequestReplayStore, Z as ZodLike, a as DVMDescriptor } from '../step-cache-3cT4Shk0.js';
2
- export { cd as CLIENT_COMPATIBILITY_HEADERS, d as CanonicalEnvelope, ce as ClientCompatibility, cf as ClientCompatibilityEnv, cg as ClientCompatibilityGate, ch as ClientCompatibilityRequirement, ci as ClientSemVer, e as CreateSignedRequestVerifierOpts, cj as CreditFundingBasis, ck as CreditInvoiceStatus, cl as CreditLedger, cm as CreditLedgerError, cn as CreditLedgerErrorCode, co as CreditLedgerErrorDetails, cp as CreditLedgerPool, cq as CreditStatus, cr as DRAIN_DELIVERY_RESERVE_SATS, cs as DVM_PROTOCOL_VERSION, ct as DrainConflictReason, cu as DrawRailValue, cv as DrawStatus, cw as PostgresX402ChannelStorage, cx as ReplayStoreBackend, cy as RevenueSkippedNoRailPayload, cz as RevenueSkippedNoRailReason, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, cA as Secp256k1AuthOpts, y as SignedRequestAudience, B as SignedRequestError, E as SignedRequestFailure, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, J as SignedRequestVerifier, cB as X402ChannelStorageOpts, cC as X402RelayLockHolder, cD as X402RelaySubmissionLock, cE as X402RelaySubmissionLockError, cF as allocateDrawValue, cG as clientCompatibilityAttributes, cH as clientCompatibilityMiddleware, cI as clientUpgradeRequired, M as createSignedRequestVerifier, cJ as parseClientCapabilities, cK as parseClientCompatibility, cL as parseDvmClient, cM as parseProtocolVersion, cN as requireClientCompatibility, cO as secp256k1Auth, cP as signedRequestInput, O as signedRequestStatementHeader } from '../step-cache-3cT4Shk0.js';
1
+ import { ab as CashuMode, bK as CreditDrainEnqueue, R as ResolvedCreditConfig, bL as DVMAuthScheme, z as SignedRequestDomain, bM as CreditLedgerLike, bN as X402RefundSettlementGate, bO as CreditSnapshot, bP as DrawResult, bQ as X402SettlementStatus, bR as X402UnresolvedRefund, bS as GrownDrawResult, bT as DrawResolution, bU as FundingRecord, X as FundingReceipt, bV as CreditInvoiceRecord, bW as InvoiceSettlement, bX as BlockedInvoiceCursor, bY as InvoiceReconciliation, bZ as InvoiceWriteOff, b_ as DrawRecord, b$ as StalePendingDrawCursor, c0 as TempoCreditLossEvidence, c1 as CreditLedgerQuerier, c2 as TempoCreditLoss, c3 as X402CreditLossEvidence, c4 as X402CreditLoss, c5 as DrainMethod, c6 as DrainRequestResult, c7 as BitcoinDepositLiability, bo as FundingLot, c8 as CreditDrainRecord, c9 as ChannelDrainCursor, ca as DrainWriteOff, cb as DrainReleaseResult, cc as DrainFulfilment, cd as DrainTransitionResult, Y as JobReceipt, a1 as Message, K as KVStore, F as SignedRequestReplayStore, Z as ZodLike, a as DVMDescriptor } from '../step-cache-BLPZNizw.js';
2
+ export { ce as CLIENT_COMPATIBILITY_HEADERS, d as CanonicalEnvelope, cf as ClientCompatibility, cg as ClientCompatibilityEnv, ch as ClientCompatibilityGate, ci as ClientCompatibilityRequirement, cj as ClientSemVer, e as CreateSignedRequestVerifierOpts, ck as CreditFundingBasis, cl as CreditInvoiceStatus, cm as CreditLedger, cn as CreditLedgerError, co as CreditLedgerErrorCode, cp as CreditLedgerErrorDetails, cq as CreditLedgerPool, cr as CreditStatus, cs as DRAIN_DELIVERY_RESERVE_SATS, ct as DVM_PROTOCOL_VERSION, cu as DrainConflictReason, cv as DrawRailValue, cw as DrawStatus, cx as JobCostReportPayload, cy as PostgresX402ChannelStorage, cz as ReplayStoreBackend, cA as RevenueSkippedNoRailPayload, cB as RevenueSkippedNoRailReason, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, cC as Secp256k1AuthOpts, y as SignedRequestAudience, B as SignedRequestError, E as SignedRequestFailure, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, cD as X402ChannelStorageOpts, cE as X402RelayLockHolder, cF as X402RelaySubmissionLock, cG as X402RelaySubmissionLockError, cH as allocateDrawValue, cI as clientCompatibilityAttributes, cJ as clientCompatibilityMiddleware, cK as clientUpgradeRequired, N as createSignedRequestVerifier, cL as parseClientCapabilities, cM as parseClientCompatibility, cN as parseDvmClient, cO as parseProtocolVersion, cP as requireClientCompatibility, cQ as secp256k1Auth, cR as signedRequestInput, T as signedRequestStatementHeader } from '../step-cache-BLPZNizw.js';
3
3
  import { Pool } from 'pg';
4
- import { ak as CreditMenu, b as AppEnv, U as UpfrontPaymentOpts, h as PaymentInfo, al as ReceiptIssuer, am as LightningReceive, an as TempoSettlementReadiness, ao as DVMHostOpts } from '../credit-menu-C7zAJElJ.js';
5
- export { ap as BuildCreditMenuArgs, aq as BuilderIdentity, ar as CREDIT_ENVELOPE_KEYS, C as ConsumedCredentialStore, as as CreateX402BatchSettlementServerOpts, at as CreditEnvelope, au as CreditEnvelopeError, av as CreditFundCommitment, aw as CreditTerms, ax as DEFAULT_INVOICE_TTL_SECONDS, ay as DVMHost, az as JobManager, aA as JobManagerOpts, aB as LightningReceiveConfig, aC as MIN_INVOICE_TTL_SECONDS, aD as MemoryConsumedCredentialStore, aE as MemoryConsumedCredentialStoreOpts, aF as MemoryProcessedPaymentStore, aG as MemoryX402ExactSettlementStore, aH as MountOpts, aI as OwnerDisplay, aJ as PlatformReporterOpts, aK as PostgresProcessedPaymentStore, aL as PostgresX402ExactSettlementStore, aM as PriceFiat, aN as ProcessedPaymentQuerier, aO as ProcessedPaymentRail, aP as ProcessedPaymentRecord, aQ as ProcessedPaymentReplayError, aR as ProcessedPaymentStore, aS as X402BatchAcceptance, aT as X402BatchFunding, aU as X402BatchRefusal, aV as X402BatchSettlementServer, aW as X402ExactAcceptance, aX as X402ExactIntentConflictError, aY as X402ExactSettlementAttempt, aZ as X402ExactSettlementChainEvidence, a_ as X402ExactSettlementEffect, a$ as X402ExactSettlementEvidenceMissingError, b0 as X402ExactSettlementEvidenceReader, b1 as X402ExactSettlementIntent, b2 as X402ExactSettlementNotReadyError, b3 as X402ExactSettlementServer, b4 as X402ExactSettlementServerOpts, b5 as X402ExactSettlementStatus, b6 as X402ExactSettlementStore, b7 as X402SettlementChainEvidence, b8 as X402SettlementEvidenceReader, b9 as X402SettlementSubmissionError, ba as X402_BATCH_AUTO_SETTLEMENT, bb as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bc as X402_BATCH_SETTLEMENT_NETWORK, bd as attachCreditMenu, be as buildCreditMenu, bf as createDVMHost, bg as createX402BatchSettlementServer, bh as creditEnvelopeIgnoreFields, bi as drawSettlementRef, bj as extractCreditEnvelope, bk as fundingCommitment, bl as selectPrimaryCredit, bm as stripCreditEnvelope, bn as toCreditView } from '../credit-menu-C7zAJElJ.js';
4
+ import { ak as CreditMenu, b as AppEnv, U as UpfrontPaymentOpts, h as PaymentInfo, al as ReceiptIssuer, am as LightningReceive, an as TempoSettlementReadiness, ao as DVMHostOpts } from '../credit-menu-C1ezIFlJ.js';
5
+ export { ap as BuildCreditMenuArgs, aq as BuilderIdentity, ar as CREDIT_ENVELOPE_KEYS, C as ConsumedCredentialStore, as as CreateX402BatchSettlementServerOpts, at as CreditEnvelope, au as CreditEnvelopeError, av as CreditFundCommitment, aw as CreditTerms, ax as DEFAULT_INVOICE_TTL_SECONDS, ay as DVMHost, az as JobManager, aA as JobManagerOpts, aB as LightningReceiveConfig, aC as MIN_INVOICE_TTL_SECONDS, aD as MemoryConsumedCredentialStore, aE as MemoryConsumedCredentialStoreOpts, aF as MemoryProcessedPaymentStore, aG as MemoryX402ExactSettlementStore, aH as MountOpts, aI as OwnerDisplay, aJ as PlatformReporterOpts, aK as PostgresProcessedPaymentStore, aL as PostgresX402ExactSettlementStore, aM as PriceFiat, aN as ProcessedPaymentQuerier, aO as ProcessedPaymentRail, aP as ProcessedPaymentRecord, aQ as ProcessedPaymentReplayError, aR as ProcessedPaymentStore, aS as X402BatchAcceptance, aT as X402BatchFunding, aU as X402BatchRefusal, aV as X402BatchSettlementServer, aW as X402ExactAcceptance, aX as X402ExactIntentConflictError, aY as X402ExactSettlementAttempt, aZ as X402ExactSettlementChainEvidence, a_ as X402ExactSettlementEffect, a$ as X402ExactSettlementEvidenceMissingError, b0 as X402ExactSettlementEvidenceReader, b1 as X402ExactSettlementIntent, b2 as X402ExactSettlementNotReadyError, b3 as X402ExactSettlementServer, b4 as X402ExactSettlementServerOpts, b5 as X402ExactSettlementStatus, b6 as X402ExactSettlementStore, b7 as X402SettlementChainEvidence, b8 as X402SettlementEvidenceReader, b9 as X402SettlementSubmissionError, ba as X402_BATCH_AUTO_SETTLEMENT, bb as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bc as X402_BATCH_SETTLEMENT_NETWORK, bd as attachCreditMenu, be as buildCreditMenu, bf as createDVMHost, bg as createX402BatchSettlementServer, bh as creditEnvelopeIgnoreFields, bi as drawSettlementRef, bj as extractCreditEnvelope, bk as fundingCommitment, bl as selectPrimaryCredit, bm as stripCreditEnvelope, bn as toCreditView } from '../credit-menu-C1ezIFlJ.js';
6
6
  import { Context } from 'hono';
7
7
  import { z } from 'zod';
8
- import { F as FxFetcher } from '../fx-BF_SG2i0.js';
9
- import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-Bn23V3QU.js';
10
- export { a as JobStatus, b as JobStore, h as isStreamableJobStore } from '../job-store-Bn23V3QU.js';
8
+ import { F as FxFetcher } from '../fx-C6dl2LVI.js';
9
+ import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-DHnW4Cg_.js';
10
+ export { a as JobStatus, b as JobStore, h as isStreamableJobStore } from '../job-store-DHnW4Cg_.js';
11
11
  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';
12
12
  import 'mppx';
13
13
  import '@x402/core/server';
14
14
  import '@x402/evm/batch-settlement/server';
15
15
  import 'viem';
16
16
  import '@x402/core/types';
17
- import '../lightning-backend-C04nH94l.js';
17
+ import '../lightning-backend-Ci1nogk_.js';
18
18
  import '@cashu/cashu-ts';
19
19
 
20
20
  /** Lifetime of a per-call implicit credit before the ledger refuses new draws. */
@@ -450,6 +450,20 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
450
450
  private acquireRequestIdClaim;
451
451
  releaseRequestIdClaim(claim: RequestIdClaim): Promise<void>;
452
452
  save(record: JobRecord): Promise<void>;
453
+ /** Persist a job while retaining its mount identity for cost-report recovery. */
454
+ saveForDvm(record: JobRecord, dvmId: string): Promise<void>;
455
+ private saveRecord;
456
+ /**
457
+ * Read terminal zero-revenue jobs whose latest declared-cost revision has
458
+ * not yet reached the durable reporter outbox.
459
+ */
460
+ listUnreportedTerminalCosts(args: {
461
+ dvmId: string;
462
+ limit: number;
463
+ afterJobId?: string;
464
+ }): Promise<JobRecord[]>;
465
+ /** Mark one revision only after its report has reached durable enqueue. */
466
+ markTerminalCostReported(jobId: string, costRevision: number): Promise<boolean>;
453
467
  delete(id: string): Promise<void>;
454
468
  listJobsForRetention(args: {
455
469
  lastActivityBeforeMs: number;
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-L4OYF4DQ.js";
4
4
  import {
5
5
  PostgresJobStore
6
- } from "../chunk-LLXV32HA.js";
6
+ } from "../chunk-SSSZUVWM.js";
7
7
  import {
8
8
  PostgresKVStore
9
9
  } from "../chunk-FROTD5XQ.js";
@@ -22,7 +22,7 @@ import {
22
22
  parseNwcUri,
23
23
  validateX402Env,
24
24
  withNwcPool
25
- } from "../chunk-EPNDZ5DH.js";
25
+ } from "../chunk-EDDYHZ6W.js";
26
26
  import {
27
27
  MemoryKVStore
28
28
  } from "../chunk-RW5LP57K.js";
@@ -77,7 +77,7 @@ import {
77
77
  stripProtocolEnvelope,
78
78
  toCreditView,
79
79
  unknownRouteNotFound
80
- } from "../chunk-3ZHMQCYP.js";
80
+ } from "../chunk-QK3VJNCK.js";
81
81
  import {
82
82
  MemoryProcessedPaymentStore,
83
83
  PostgresProcessedPaymentStore,
@@ -95,11 +95,11 @@ import {
95
95
  } from "../chunk-H2MEFVH6.js";
96
96
  import {
97
97
  isStreamableJobStore
98
- } from "../chunk-4B56DEEV.js";
98
+ } from "../chunk-U6M3ATSG.js";
99
99
  import {
100
100
  generateEphemeralReceiptKey,
101
101
  receiptPubkeyFromSecret
102
- } from "../chunk-2K7E3N2D.js";
102
+ } from "../chunk-VRQDX5P4.js";
103
103
  import {
104
104
  X402_DEFAULT_FACILITATOR,
105
105
  X402_DEFAULT_NETWORK,
@@ -119,7 +119,7 @@ import {
119
119
  } from "../chunk-KXZUCCEY.js";
120
120
  import {
121
121
  initLoggers
122
- } from "../chunk-YDIYXGYL.js";
122
+ } from "../chunk-E4EVGPDX.js";
123
123
  import "../chunk-66HGCPBU.js";
124
124
  import "../chunk-FUJ36YDV.js";
125
125
  import "../chunk-27V2ILSR.js";
@@ -1130,7 +1130,7 @@ function createDVMHost(opts = {}) {
1130
1130
  });
1131
1131
  applyRetryToPool(pool, "dvm-host");
1132
1132
  pgPool = pool;
1133
- const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-TAONYLIF.js");
1133
+ const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-3RAXMNSY.js");
1134
1134
  const pgJobStore = new PostgresJobStore2(pool);
1135
1135
  pendingInits.push(pgJobStore.init(), pgJobStore.initStreaming());
1136
1136
  jobStore = pgJobStore;