@dvmkit/sdk 0.1.5-rc.8 → 0.2.0-rc.9

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.
Files changed (56) hide show
  1. package/README.md +12 -0
  2. package/dist/{chunk-BIP6G74V.js → chunk-2ATUAUAO.js} +8 -8
  3. package/dist/{chunk-27V2ILSR.js → chunk-4A2RAKCW.js} +2 -2
  4. package/dist/{chunk-EVBK675R.js → chunk-6GRIKOFB.js} +28 -23
  5. package/dist/{chunk-CEOAHV2I.js → chunk-FDKRXOZO.js} +0 -5
  6. package/dist/{chunk-L4OYF4DQ.js → chunk-FT6HTUM4.js} +1 -1
  7. package/dist/{chunk-BTZY7VPH.js → chunk-GAIPXGM3.js} +1 -1
  8. package/dist/{chunk-U6M3ATSG.js → chunk-JDT5LCJC.js} +40 -6
  9. package/dist/{chunk-FROTD5XQ.js → chunk-JLXYOV4Y.js} +1 -2
  10. package/dist/{chunk-M7LHFJ5K.js → chunk-KMZXTBLA.js} +2 -2
  11. package/dist/{chunk-6BQM7TOW.js → chunk-L67WTZX2.js} +3 -7
  12. package/dist/{chunk-CGKZDODG.js → chunk-MG67KXU7.js} +0 -5
  13. package/dist/{chunk-JZWELPFH.js → chunk-MRAGS5VP.js} +1 -1
  14. package/dist/{chunk-2UUXIIOC.js → chunk-O2X2CCKH.js} +3 -3
  15. package/dist/{chunk-TQWGQCNV.js → chunk-OMIQMMME.js} +3 -3
  16. package/dist/{chunk-UB5FZ43T.js → chunk-PCUQZDZA.js} +475 -366
  17. package/dist/{chunk-KVEHHC7W.js → chunk-PHHAYRQV.js} +7 -9
  18. package/dist/{chunk-SSSZUVWM.js → chunk-QP53RWAD.js} +88 -38
  19. package/dist/{chunk-DMNLFNTW.js → chunk-QT4ONTST.js} +1 -1
  20. package/dist/{chunk-RW5LP57K.js → chunk-SDK6KDJN.js} +0 -1
  21. package/dist/{chunk-MLRCSJYX.js → chunk-V7EVFLAK.js} +87 -90
  22. package/dist/{chunk-E4EVGPDX.js → chunk-XQXJKJ3P.js} +0 -2
  23. package/dist/{credit-ledger-2DFQHNLB.js → credit-ledger-5ZEJRI46.js} +1 -1
  24. package/dist/{credit-menu-s5HmGCqx.d.ts → credit-menu-D4Gcdgc4.d.ts} +488 -644
  25. package/dist/{fx-D860pZvP.d.ts → fx-B0SLBe5x.d.ts} +38 -82
  26. package/dist/index.d.ts +11 -14
  27. package/dist/index.js +2 -2
  28. package/dist/internal/caller.d.ts +618 -1525
  29. package/dist/internal/caller.js +28 -60
  30. package/dist/internal/server.d.ts +36 -61
  31. package/dist/internal/server.js +11 -11
  32. package/dist/{job-store-BUGqvCfL.d.ts → job-store-B2uZvga4.d.ts} +70 -59
  33. package/dist/{lightning-backend-BozcevPZ.d.ts → lightning-backend-CQBnQgsT.d.ts} +19 -27
  34. package/dist/{memory-credit-ledger-MNUOTQO5.js → memory-credit-ledger-ZOH6C3N4.js} +2 -2
  35. package/dist/{mpp-setup-4FJD6ZHV.js → mpp-setup-IOJBF7DB.js} +1 -1
  36. package/dist/{payout-reporter-RG6XNGPI.js → payout-reporter-5PIRYFVQ.js} +1 -1
  37. package/dist/{postgres-consumed-credential-store-VHBT4KEA.js → postgres-consumed-credential-store-ISRHBMOU.js} +1 -1
  38. package/dist/{postgres-job-store-3RAXMNSY.js → postgres-job-store-OGQ6IT4U.js} +1 -1
  39. package/dist/{postgres-kv-store-JFBDP5IP.js → postgres-kv-store-D5E2EZ24.js} +1 -1
  40. package/dist/{postgres-replay-store-UJXRT6VO.js → postgres-replay-store-IZFLTTAC.js} +1 -1
  41. package/dist/{pricing-4CEB34RM.js → pricing-MU5GNUJZ.js} +1 -1
  42. package/dist/{processed-payment-store-HAA4SFNK.js → processed-payment-store-FIDI3RNH.js} +1 -1
  43. package/dist/{revenue-reporter-ASZ7SHHH.js → revenue-reporter-NNCNRY4C.js} +1 -1
  44. package/dist/server/index.d.ts +53 -59
  45. package/dist/server/index.js +38 -37
  46. package/dist/{ssrf-DbFkpDv0.d.ts → ssrf-dMooihtY.d.ts} +1 -2
  47. package/dist/{step-cache-5dljDqrQ.d.ts → step-cache-CXg7ziML.d.ts} +389 -551
  48. package/dist/{tempo-charge-store-RIFTALZK.js → tempo-charge-store-76TDAF34.js} +1 -1
  49. package/dist/{tempo-lifecycle-DFIXQ54Q.js → tempo-lifecycle-DXM7QXJQ.js} +3 -3
  50. package/dist/{tempo-wallet-4QKSV65O.js → tempo-wallet-O67H5M4N.js} +2 -2
  51. package/dist/testing/index.d.ts +5 -15
  52. package/dist/testing/index.js +4 -11
  53. package/dist/{usd-DoRuAckA.d.ts → usd-BNDg1715.d.ts} +14 -16
  54. package/dist/{wallet-CJC8lwxx.d.ts → wallet-Dwjs5n_M.d.ts} +1 -1
  55. package/dist/{x402-5H27DCBE.js → x402-7S2EFINY.js} +2 -2
  56. package/package.json +2 -1
@@ -1,21 +1,21 @@
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-5dljDqrQ.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-5dljDqrQ.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-CXg7ziML.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 JobTerminalReportPayload, cz as PostgresX402ChannelStorage, cA as ReplayStoreBackend, cB as RevenueSkippedNoRailPayload, cC as RevenueSkippedNoRailReason, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, cD as Secp256k1AuthOpts, y as SignedRequestAudience, B as SignedRequestError, E as SignedRequestFailure, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, cE as X402ChannelStorageOpts, cF as X402RelayLockHolder, cG as X402RelaySubmissionLock, cH as X402RelaySubmissionLockError, cI as allocateDrawValue, cJ as clientCompatibilityAttributes, cK as clientCompatibilityMiddleware, cL as clientUpgradeRequired, N as createSignedRequestVerifier, cM as parseClientCapabilities, cN as parseClientCompatibility, cO as parseDvmClient, cP as parseProtocolVersion, cQ as requireClientCompatibility, cR as secp256k1Auth, cS as signedRequestInput, T as signedRequestStatementHeader } from '../step-cache-CXg7ziML.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, ap as DVMServeResult } from '../credit-menu-s5HmGCqx.js';
5
- export { aq as BuildCreditMenuArgs, ar as BuilderIdentity, as as CREDIT_ENVELOPE_KEYS, C as ConsumedCredentialStore, at as CreateX402BatchSettlementServerOpts, au as CreditEnvelope, av as CreditEnvelopeError, aw as CreditFundCommitment, ax as CreditTerms, ay as DEFAULT_INVOICE_TTL_SECONDS, az as DVMHost, aA as JobManager, aB as JobManagerOpts, aC as LightningReceiveConfig, aD as MIN_INVOICE_TTL_SECONDS, aE as MemoryConsumedCredentialStore, aF as MemoryConsumedCredentialStoreOpts, aG as MemoryProcessedPaymentStore, aH as MemoryX402ExactSettlementStore, aI as MountOpts, aJ as OwnerDisplay, aK as PaidJobCompletion, aL as PaymentMode, aM as PlatformReporterOpts, aN as PostgresProcessedPaymentStore, aO as PostgresX402ExactSettlementStore, aP as PriceFiat, aQ as ProcessedPaymentQuerier, aR as ProcessedPaymentRail, aS as ProcessedPaymentRecord, aT as ProcessedPaymentReplayError, aU as ProcessedPaymentStore, aV as X402BatchAcceptance, aW as X402BatchFunding, aX as X402BatchRefusal, aY as X402BatchSettlementServer, aZ as X402ExactAcceptance, a_ as X402ExactIntentConflictError, a$ as X402ExactSettlementAttempt, b0 as X402ExactSettlementChainEvidence, b1 as X402ExactSettlementEffect, b2 as X402ExactSettlementEvidenceMissingError, b3 as X402ExactSettlementEvidenceReader, b4 as X402ExactSettlementIntent, b5 as X402ExactSettlementNotReadyError, b6 as X402ExactSettlementServer, b7 as X402ExactSettlementServerOpts, b8 as X402ExactSettlementStatus, b9 as X402ExactSettlementStore, ba as X402SettlementChainEvidence, bb as X402SettlementEvidenceReader, bc as X402SettlementSubmissionError, bd as X402_BATCH_AUTO_SETTLEMENT, be as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bf as X402_BATCH_SETTLEMENT_NETWORK, bg as attachCreditMenu, bh as buildCreditMenu, bi as createDVMHost, bj as createX402BatchSettlementServer, bk as creditEnvelopeIgnoreFields, bl as drawSettlementRef, bm as extractCreditEnvelope, bn as fundingCommitment, bo as selectPrimaryCredit, bp as stripCreditEnvelope, bq as toCreditView } from '../credit-menu-s5HmGCqx.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, ap as DVMServeResult } from '../credit-menu-D4Gcdgc4.js';
5
+ export { aq as BuildCreditMenuArgs, ar as BuilderIdentity, as as CREDIT_ENVELOPE_KEYS, C as ConsumedCredentialStore, at as CreateX402BatchSettlementServerOpts, au as CreditEnvelope, av as CreditEnvelopeError, aw as CreditFundCommitment, ax as CreditTerms, ay as DEFAULT_INVOICE_TTL_SECONDS, az as DVMHost, aA as JobManager, aB as JobManagerOpts, aC as LightningReceiveConfig, aD as MIN_INVOICE_TTL_SECONDS, aE as MemoryConsumedCredentialStore, aF as MemoryConsumedCredentialStoreOpts, aG as MemoryProcessedPaymentStore, aH as MemoryX402ExactSettlementStore, aI as MountOpts, aJ as OwnerDisplay, aK as PaidJobCompletion, aL as PaymentMode, aM as PlatformReporterOpts, aN as PostgresProcessedPaymentStore, aO as PostgresX402ExactSettlementStore, aP as PriceFiat, aQ as ProcessedPaymentQuerier, aR as ProcessedPaymentRail, aS as ProcessedPaymentRecord, aT as ProcessedPaymentReplayError, aU as ProcessedPaymentStore, aV as X402BatchAcceptance, aW as X402BatchFunding, aX as X402BatchRefusal, aY as X402BatchSettlementServer, aZ as X402ExactAcceptance, a_ as X402ExactIntentConflictError, a$ as X402ExactSettlementAttempt, b0 as X402ExactSettlementChainEvidence, b1 as X402ExactSettlementEffect, b2 as X402ExactSettlementEvidenceMissingError, b3 as X402ExactSettlementEvidenceReader, b4 as X402ExactSettlementIntent, b5 as X402ExactSettlementNotReadyError, b6 as X402ExactSettlementServer, b7 as X402ExactSettlementServerOpts, b8 as X402ExactSettlementStatus, b9 as X402ExactSettlementStore, ba as X402SettlementChainEvidence, bb as X402SettlementEvidenceReader, bc as X402SettlementSubmissionError, bd as X402_BATCH_AUTO_SETTLEMENT, be as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bf as X402_BATCH_SETTLEMENT_NETWORK, bg as attachCreditMenu, bh as buildCreditMenu, bi as createDVMHost, bj as createX402BatchSettlementServer, bk as creditEnvelopeIgnoreFields, bl as drawSettlementRef, bm as extractCreditEnvelope, bn as fundingCommitment, bo as selectPrimaryCredit, bp as stripCreditEnvelope, bq as toCreditView } from '../credit-menu-D4Gcdgc4.js';
6
6
  import { Context } from 'hono';
7
7
  import { z } from 'zod';
8
- import { F as FxFetcher } from '../fx-D860pZvP.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-BUGqvCfL.js';
10
- export { a as JobStatus, b as JobStore, h as isStreamableJobStore } from '../job-store-BUGqvCfL.js';
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';
8
+ import { F as FxFetcher } from '../fx-B0SLBe5x.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-B2uZvga4.js';
10
+ export { a as JobStatus, b as JobStore, h as isStreamableJobStore } from '../job-store-B2uZvga4.js';
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-dMooihtY.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
17
  import '@cashu/cashu-ts';
18
- import '../lightning-backend-BozcevPZ.js';
18
+ import '../lightning-backend-CQBnQgsT.js';
19
19
 
20
20
  /** Lifetime of a per-call implicit credit before the ledger refuses new draws. */
21
21
  declare const IMPLICIT_CREDIT_TTL_MS: number;
@@ -34,7 +34,7 @@ interface ResolvedCashuOpts {
34
34
  * variables, initializing DB tables when their prerequisites are met.
35
35
  * Extracted from serve() so DVMs that call createDVMServer directly (cast,
36
36
  * scrape) can wire Cashu and the builder admin surface without using the
37
- * serve() wrapper (internal-review).
37
+ * serve() wrapper.
38
38
  *
39
39
  * @param pool - existing Postgres pool to reuse; pass undefined when no DB is available
40
40
  * @param cashuModeHint - programmatic override for cashu mode (serve()'s opts.cashuMode)
@@ -43,7 +43,7 @@ declare function resolveCashuOptsFromEnv(env: Record<string, string>, pool?: Poo
43
43
 
44
44
  /**
45
45
  * What a terminal drain transition needs in order to book its platform drain
46
- * report (internal-review). Every field is optional because a DVM can legitimately
46
+ * report. Every field is optional because a DVM can legitimately
47
47
  * run without platform reporting — a `dvmctl dev` server, a self-hosted
48
48
  * builder, a test host — and a drain must still be fulfillable there.
49
49
  */
@@ -57,7 +57,7 @@ interface DrainReportWiring {
57
57
  }
58
58
 
59
59
  /**
60
- * Signed body of a `POST /v1/credit` request (internal-review). The op discriminator
60
+ * Signed body of a `POST /v1/credit` request. The op discriminator
61
61
  * lives **inside** the signed bytes, so a network attacker can't rewrite a
62
62
  * `balance` read into a `drain`.
63
63
  *
@@ -115,28 +115,28 @@ interface CreditRouteDeps {
115
115
  /** Per-DVM + per-request rail wiring, shared with `/v1/job` (see `railVerifyOpts`). */
116
116
  railOpts: (c: Context<AppEnv>) => Promise<UpfrontPaymentOpts>;
117
117
  /**
118
- * Book a committed top-up as a platform deposit (internal-review). A fund-only
118
+ * Book a committed top-up as a platform deposit. A fund-only
119
119
  * top-up moves real money onto a credit whose draws will each book revenue
120
120
  * later, so skipping this would report the spending without the money that
121
121
  * backed it — the DVM's outstanding liability would go negative.
122
122
  */
123
123
  onDeposit: (funding: NonNullable<PaymentInfo["funding"]>) => void;
124
124
  /**
125
- * Platform drain-report wiring (internal-review), used by the cashu pickup — the
125
+ * Platform drain-report wiring, used by the cashu pickup — the
126
126
  * one terminal drain transition that lands on this caller-facing route.
127
127
  * Empty on a DVM with no platform reporting, which changes nothing about
128
128
  * the reclaim itself.
129
129
  */
130
130
  drainReport: DrainReportWiring;
131
131
  /**
132
- * Receipt signer, when this DVM has a receipt key (internal-review). Drain ops
133
- * countersign every reclaim event with it (internal-review); absent, drains still
132
+ * Receipt signer, when this DVM has a receipt key. Drain ops
133
+ * countersign every reclaim event with it; absent, drains still
134
134
  * work — the ledger stays authoritative, the caller just gets no portable
135
135
  * evidence artifact.
136
136
  */
137
137
  receiptIssuer: ReceiptIssuer | undefined;
138
138
  /**
139
- * The Lightning receive leg, when this DVM configured one (internal-review).
139
+ * The Lightning receive leg, when this DVM configured one.
140
140
  * Absent ⇒ `method: "lightning"` is refused with `lightning_unavailable`
141
141
  * and the funding menu never advertised it in the first place.
142
142
  *
@@ -148,7 +148,7 @@ interface CreditRouteDeps {
148
148
  } | undefined;
149
149
  /**
150
150
  * Apply any Lightning invoice this caller has paid since the last check, and
151
- * book the deposit for each one that credits (internal-review). A no-op when the
151
+ * book the deposit for each one that credits. A no-op when the
152
152
  * rail isn't configured. Runs before the read ops so a balance reflects a
153
153
  * top-up that settled out of band, and behind the fund poll so a sibling
154
154
  * invoice on the same credit is swept with it.
@@ -159,22 +159,22 @@ interface CreditRouteDeps {
159
159
  }
160
160
  /**
161
161
  * `POST /v1/credit` — the caller-facing surface of the credits settlement
162
- * layer (internal-review, spec §4/§7). Three ops on one signed, replay-protected
162
+ * layer (the funding-menu and signed-operation contract). Three ops on one signed, replay-protected
163
163
  * envelope, mirroring `/v1/job`'s auth discipline exactly:
164
164
  *
165
165
  * - **fund** — a top-up with no job attached. The rail artifact rides the same
166
- * headers as `/v1/job` (`X-Cashu` + `X-Cashu-Request-Id`, `X-PAYMENT`,
167
- * `Authorization: Payment …`) and a missing or bad one comes back as the
168
- * same 402 envelope, which is what lets a caller's existing resumable-submit
169
- * machinery drive a top-up with no new client code.
166
+ * headers as `/v1/job` (`X-Cashu` + `X-Cashu-Request-Id`, `X-PAYMENT`,
167
+ * `Authorization: Payment …`) and a missing or bad one comes back as the
168
+ * same 402 envelope, which is what lets a caller's existing resumable-submit
169
+ * machinery drive a top-up with no new client code.
170
170
  * - **balance** — what do I hold here, including expired credits (their value
171
- * is still the caller's; spec §5), plus the funding menu, so the same read
172
- * also answers what may be added (internal-review).
173
- * - **drain** — reclaim the unspent balance (internal-review, spec §5 tier 3). One
174
- * op is both the request and the poll/pickup: the first call debits the
175
- * available balance into a `pending` liability; re-polling the same
176
- * `drain_id` returns the current state, delivers the parked Cashu token
177
- * when the builder's batch job has parked it, and is idempotent throughout.
171
+ * is still the caller's), plus the funding menu, so the same read
172
+ * also answers what may be added.
173
+ * - **drain** — reclaim the unspent balance (the reclaim contract). One
174
+ * op is both the request and the poll/pickup: the first call debits the
175
+ * available balance into a `pending` liability; re-polling the same
176
+ * `drain_id` returns the current state, delivers the parked Cashu token
177
+ * when the builder's batch job has parked it, and is idempotent throughout.
178
178
  */
179
179
  declare function handleCreditRequest(c: Context<AppEnv>, deps: CreditRouteDeps): Promise<Response>;
180
180
 
@@ -200,14 +200,14 @@ type InitLockPool = Pick<Pool, "connect"> & {
200
200
  * creator: two sessions running the same `CREATE TABLE IF NOT EXISTS` at once
201
201
  * can raise `duplicate key value violates unique constraint
202
202
  * "pg_type_typname_nsp_index"` (23505) in the loser, which at SDK boot is an
203
- * unhandled throw that kills the machine (internal-review).
203
+ * unhandled throw that kills the machine.
204
204
  *
205
205
  * Deliberately distinct from `PLATFORM_INIT_ADVISORY_LOCK` (17320917) — a
206
206
  * DVM's own database is not the platform database — and from the first-party
207
207
  * DVMs' own keys (cast 17320918, scrape 17320926, scribe 24700919). **A new
208
208
  * SDK store reuses this key rather than inventing a second one**: one key means
209
209
  * there is only ever one lock order, so the per-store lock-order inversion that
210
- * deadlocked internal-review can't recur.
210
+ * deadlocked can't recur.
211
211
  */
212
212
  declare const SDK_INIT_ADVISORY_LOCK = 17320927;
213
213
  /**
@@ -216,8 +216,7 @@ declare const SDK_INIT_ADVISORY_LOCK = 17320927;
216
216
  *
217
217
  * Overlapping callers on the same pool share **one** acquisition: the first
218
218
  * connects and locks, concurrent and nested callers join the held lock, and
219
- * the last one out unlocks and releases the client. That keeps internal-review's
220
- * deliberately-parallel store-init batch parallel — six `init()`s racing each
219
+ * the last one out unlocks and releases the client. That keeps * deliberately-parallel store-init batch parallel — six `init()`s racing each
221
220
  * other would otherwise queue behind one another — and keeps the uncontended
222
221
  * cost at one extra round trip per boot phase rather than one per store.
223
222
  * Sharing is safe for the DDL, which is what this lock is for: it excludes
@@ -234,11 +233,8 @@ declare const SDK_INIT_ADVISORY_LOCK = 17320927;
234
233
  * including throws: an SDK boot that died holding this lock would block every
235
234
  * sibling until its connection closed.
236
235
  *
237
- * The guarded DDL runs on the pool's *other* connections, so the pool must
238
- * allow at least two — `pg`'s default `max` is 10 and the host never narrows
239
- * it, but a builder-supplied `Pool({ max: 1 })` would starve boot. That one
240
- * deadlocks with no error and reads as a dead database, so it is refused up
241
- * front instead.
236
+ * Guarded DDL needs a second connection while the advisory-lock client stays
237
+ * pinned. Pools with `max < 2` would starve boot and are rejected.
242
238
  */
243
239
  declare function withSdkInitLock<T>(db: InitLockPool, fn: () => Promise<T>): Promise<T>;
244
240
 
@@ -248,14 +244,14 @@ declare function withSdkInitLock<T>(db: InitLockPool, fn: () => Promise<T>): Pro
248
244
  * `MemoryJobStore` precedent. Same semantics as the Postgres `CreditLedger`
249
245
  * (two-phase draws, replay-before-expiry, `draw_conflict`, gap-free
250
246
  * `ledger_seq`), minus durability and cross-machine safety: per-process only,
251
- * so production DVMs must use the Postgres ledger (spec §2 condition 2).
247
+ * so production DVMs must use the Postgres ledger (the durable-ledger requirement).
252
248
  * Every mutating verb is synchronous between awaits, so operations are
253
249
  * atomic in-process; the `tx` handles are accepted and ignored.
254
250
  */
255
251
  declare class MemoryCreditLedger implements CreditLedgerLike {
256
252
  /**
257
253
  * Per-process and lost on restart, so a DVM backed by this ledger never
258
- * advertises the funding menu outside devMode (internal-review) — funding on one
254
+ * advertises the funding menu outside devMode — funding on one
259
255
  * machine and drawing on another would `credit_not_found`.
260
256
  */
261
257
  readonly durable = false;
@@ -267,13 +263,13 @@ declare class MemoryCreditLedger implements CreditLedgerLike {
267
263
  private x402Settlements?;
268
264
  /** Internal disposable transaction snapshot. The caller must serialize every ledger access. */
269
265
  forkForTransaction(): MemoryCreditLedger;
270
- /** See {@link CreditLedger.useX402SettlementGate} — same contract (internal-review). */
266
+ /** See {@link CreditLedger.useX402SettlementGate} — same contract. */
271
267
  useX402SettlementGate(gate: X402RefundSettlementGate): void;
272
268
  fund(args: Parameters<CreditLedgerLike["fund"]>[0]): Promise<CreditSnapshot>;
273
269
  draw(args: Parameters<CreditLedgerLike["draw"]>[0]): Promise<DrawResult>;
274
- /** See {@link CreditLedger.blockingX402Refund} — same contract (internal-review). */
270
+ /** See {@link CreditLedger.blockingX402Refund} — same contract. */
275
271
  blockingX402Refund(channelId: string | null | undefined, statuses: X402SettlementStatus[]): Promise<X402UnresolvedRefund | undefined>;
276
- /** The unresolved x402 refund that must stop an effect on `creditId` (internal-review). */
272
+ /** The unresolved x402 refund that must stop an effect on `creditId`. */
277
273
  private blockingRefundForCredit;
278
274
  growDraw(args: Parameters<CreditLedgerLike["growDraw"]>[0]): Promise<GrownDrawResult>;
279
275
  settle(args: Parameters<CreditLedgerLike["settle"]>[0]): Promise<DrawResolution>;
@@ -320,7 +316,7 @@ declare class MemoryCreditLedger implements CreditLedgerLike {
320
316
  private findByPaymentHash;
321
317
  private fundSync;
322
318
  private drawSync;
323
- /** Mid-job top-up growth (internal-review) — see `CreditLedger.growDraw` for the semantics. */
319
+ /** Mid-job top-up growth — see `CreditLedger.growDraw` for the semantics. */
324
320
  private growDrawSync;
325
321
  get(creditId: string, opts?: {
326
322
  nowMs?: number;
@@ -340,7 +336,7 @@ declare class MemoryCreditLedger implements CreditLedgerLike {
340
336
  limit: number;
341
337
  after?: StalePendingDrawCursor;
342
338
  }): Promise<DrawRecord[]>;
343
- /** Settled draws' native value for the credit an x402 channel funded (internal-review). */
339
+ /** Settled draws' native value for the credit an x402 channel funded. */
344
340
  earnedNativeForX402Channel(channelId: string): Promise<number | undefined>;
345
341
  getCreditByX402Channel(channelId: string): Promise<CreditSnapshot | undefined>;
346
342
  terminalizeTempoCredits(evidence: TempoCreditLossEvidence, _tx?: CreditLedgerQuerier): Promise<TempoCreditLoss[]>;
@@ -435,11 +431,10 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
435
431
  constructor(pool: Pool);
436
432
  /** Run the CREATE TABLE migration. Call once at startup. */
437
433
  init(): Promise<void>;
438
- /** The boot DDL itself — always runs under {@link withSdkInitLock} (internal-review). */
439
434
  private createTables;
440
435
  get(id: string): Promise<JobRecord | undefined>;
441
436
  /**
442
- * internal-review. Indexed by `idx_jobs_payment_tx_hash`. `paymentTxHash` is unique
437
+ * Indexed by `idx_jobs_payment_tx_hash`. `paymentTxHash` is unique
443
438
  * per settlement in practice — the accumulator's
444
439
  * `UNIQUE(dvm_id, request_id, proof_secret)` is what makes a second job under
445
440
  * the same request id impossible — but order by `created_at` so a
@@ -455,6 +450,10 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
455
450
  /** Persist a job while retaining its mount identity for cost-report recovery. */
456
451
  saveForDvm(record: JobRecord, dvmId: string): Promise<void>;
457
452
  private saveRecord;
453
+ /** Advance only after the reporter durably enqueued or deduplicated the event. */
454
+ markTerminalReported(jobId: string): Promise<void>;
455
+ /** Bounded crash recovery for terminal events not yet queued. */
456
+ listUnreportedTerminalReports(dvmId: string, capabilities: string[] | null, afterJobId?: string): Promise<JobRecord[]>;
458
457
  /**
459
458
  * Read terminal zero-revenue jobs whose latest declared-cost revision has
460
459
  * not yet reached the durable reporter outbox.
@@ -520,7 +519,7 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
520
519
  private terminateJob;
521
520
  private fetchCountersTx;
522
521
  /**
523
- * The credit binding on the job row, read inside Tx C (internal-review). Used on the
522
+ * The credit binding on the job row, read inside Tx C. Used on the
524
523
  * paths that don't get it from a `RETURNING` — the `alreadyVerified` skip and
525
524
  * a non-payment inbound.
526
525
  */
@@ -530,17 +529,14 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
530
529
  /**
531
530
  * Postgres-backed KVStore. Requires the `pg` package as a peer dependency.
532
531
  *
533
- * Expired rows are filtered on read but never deleted. A periodic cleanup
534
- * mechanism (e.g. `DELETE FROM kv_store WHERE expires_at IS NOT NULL AND
535
- * expires_at < now()`) should be added before production use to prevent
536
- * unbounded table growth.
532
+ * Expired rows are filtered on read and list, but never deleted; callers
533
+ * must arrange their own cleanup to bound physical storage.
537
534
  */
538
535
  declare class PostgresKVStore implements KVStore {
539
536
  private pool;
540
537
  constructor(pool: Pool);
541
538
  /** Run the CREATE TABLE migration. Call once at startup. */
542
539
  init(): Promise<void>;
543
- /** The boot DDL itself — always runs under {@link withSdkInitLock} (internal-review). */
544
540
  private createTables;
545
541
  get<T = unknown>(key: string): Promise<T | undefined>;
546
542
  set(key: string, value: unknown, opts?: {
@@ -550,7 +546,6 @@ declare class PostgresKVStore implements KVStore {
550
546
  list(prefix?: string): Promise<string[]>;
551
547
  }
552
548
 
553
- /** Options for `PostgresReplayStore`. */
554
549
  interface PostgresReplayStoreOpts {
555
550
  /** Table name. Defaults to `"signed_request_replays"`. Must match `/^[a-zA-Z_][a-zA-Z0-9_]*$/`. */
556
551
  tableName?: string;
@@ -587,7 +582,7 @@ declare class PostgresReplayStore implements SignedRequestReplayStore {
587
582
  constructor(pool: Pool, opts?: PostgresReplayStoreOpts);
588
583
  /** Run the CREATE TABLE migration. Idempotent — safe to call repeatedly. */
589
584
  init(): Promise<void>;
590
- /** The boot DDL itself — always runs under {@link withSdkInitLock} (internal-review). */
585
+ /** The boot DDL itself — always runs under {@link withSdkInitLock}. */
591
586
  private createTables;
592
587
  checkAndRecord(pubkey: string, timestamp: number, nonce: string, now: number): Promise<boolean>;
593
588
  private gcSweep;
@@ -601,11 +596,10 @@ declare function protocolEnvelopeIgnoreFields(schema: unknown): readonly string[
601
596
  declare function stripProtocolEnvelope(schema: unknown, data: unknown): unknown;
602
597
  /** Read and validate the optional recovery id from a signed request body. */
603
598
  declare function requestIdFromEnvelope(data: unknown): string | undefined;
604
- /** True when the request body carries a request id field but its value is invalid. */
605
599
  declare function hasInvalidRequestId(data: unknown): boolean;
606
600
 
607
601
  /**
608
- * Convenience one-liner over {@link createDVMHost} (internal-review). For
602
+ * Convenience one-liner over {@link createDVMHost}. For
609
603
  * single-DVM hosts, `serve(dvm, opts)` is equivalent to
610
604
  * `createDVMHost(opts).mount(dvm).serve()`. Multi-DVM hosts go through
611
605
  * `createDVMHost` directly so each mount can carry its own prefix.
@@ -613,7 +607,7 @@ declare function hasInvalidRequestId(data: unknown): boolean;
613
607
  * This is **shorthand-over-host**, not a parallel code path — every wiring
614
608
  * step (Cashu/MPP/x402 envelope resolution, platform reporter, db, fx) flows
615
609
  * through `createDVMHost`. First-party DVMs that use `serve(...)` are NOT
616
- * exposed to the wiring-drift bug class fixed in internal-review/485/511, which was
610
+ * exposed to the wiring-drift bug class fixed in 485/511, which was
617
611
  * about bypassing the host entirely. There is no migration to do.
618
612
  */
619
613
  declare function serve<State, InputSchema extends ZodLike | undefined = undefined>(descriptor: DVMDescriptor<State, InputSchema>, opts?: DVMHostOpts): Promise<DVMServeResult>;
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  PostgresReplayStore
3
- } from "../chunk-L4OYF4DQ.js";
3
+ } from "../chunk-FT6HTUM4.js";
4
4
  import {
5
5
  PostgresJobStore
6
- } from "../chunk-SSSZUVWM.js";
6
+ } from "../chunk-QP53RWAD.js";
7
7
  import {
8
8
  PostgresKVStore
9
- } from "../chunk-FROTD5XQ.js";
9
+ } from "../chunk-JLXYOV4Y.js";
10
10
  import {
11
11
  SSRFError,
12
12
  assertSafeUrl,
@@ -21,10 +21,10 @@ import {
21
21
  parseNwcUri,
22
22
  validateX402Env,
23
23
  withNwcPool
24
- } from "../chunk-CEOAHV2I.js";
24
+ } from "../chunk-FDKRXOZO.js";
25
25
  import {
26
26
  MemoryKVStore
27
- } from "../chunk-RW5LP57K.js";
27
+ } from "../chunk-SDK6KDJN.js";
28
28
  import {
29
29
  AccumulatorReplayError,
30
30
  CLIENT_COMPATIBILITY_HEADERS,
@@ -78,16 +78,16 @@ import {
78
78
  stripProtocolEnvelope,
79
79
  toCreditView,
80
80
  unknownRouteNotFound
81
- } from "../chunk-UB5FZ43T.js";
81
+ } from "../chunk-PCUQZDZA.js";
82
82
  import {
83
83
  MemoryProcessedPaymentStore,
84
84
  PostgresProcessedPaymentStore,
85
85
  ProcessedPaymentReplayError
86
- } from "../chunk-DMNLFNTW.js";
86
+ } from "../chunk-QT4ONTST.js";
87
87
  import "../chunk-BQ2NMWKE.js";
88
88
  import {
89
89
  MemoryCreditLedger
90
- } from "../chunk-KVEHHC7W.js";
90
+ } from "../chunk-PHHAYRQV.js";
91
91
  import {
92
92
  SignedRequestError,
93
93
  createDefaultReplayStore,
@@ -96,7 +96,7 @@ import {
96
96
  } from "../chunk-H2MEFVH6.js";
97
97
  import {
98
98
  isStreamableJobStore
99
- } from "../chunk-U6M3ATSG.js";
99
+ } from "../chunk-JDT5LCJC.js";
100
100
  import {
101
101
  generateEphemeralReceiptKey,
102
102
  isTestMintUrl,
@@ -121,10 +121,10 @@ import {
121
121
  } from "../chunk-KXZUCCEY.js";
122
122
  import {
123
123
  initLoggers
124
- } from "../chunk-E4EVGPDX.js";
124
+ } from "../chunk-XQXJKJ3P.js";
125
125
  import "../chunk-66HGCPBU.js";
126
126
  import "../chunk-FUJ36YDV.js";
127
- import "../chunk-27V2ILSR.js";
127
+ import "../chunk-4A2RAKCW.js";
128
128
  import "../chunk-AT6V3SY7.js";
129
129
  import {
130
130
  CreditLedger,
@@ -133,7 +133,7 @@ import {
133
133
  PostgresX402ChannelStorage,
134
134
  X402RelaySubmissionLockError,
135
135
  allocateDrawValue
136
- } from "../chunk-MLRCSJYX.js";
136
+ } from "../chunk-V7EVFLAK.js";
137
137
  import {
138
138
  SDK_INIT_ADVISORY_LOCK,
139
139
  withSdkInitLock
@@ -147,7 +147,7 @@ import {
147
147
  TEMPO_SETTLEMENT_DEFAULT_LOW_BALANCE_MICRO,
148
148
  TempoSettlementReadiness,
149
149
  resolveTempoNetwork
150
- } from "../chunk-M7LHFJ5K.js";
150
+ } from "../chunk-KMZXTBLA.js";
151
151
 
152
152
  // src/sdk/server/cashu-env.ts
153
153
  async function resolveCashuOptsFromEnv(env, pool, cashuModeHint) {
@@ -543,7 +543,7 @@ var LightningReceive = class _LightningReceive {
543
543
  * Issue (or re-issue) the bolt11 funding `(creditId, fundId)`.
544
544
  *
545
545
  * The invoice is minted **for** the credit and amount named in the caller's
546
- * signed body — that binding is the internal-review condition-3 commitment on this
546
+ * signed body — that binding is the condition-3 commitment on this
547
547
  * rail, and it is why no artifact hash rides the request: there is no
548
548
  * caller-supplied artifact to hash. A re-poll returns the stored row rather
549
549
  * than minting again; a second bolt11 for one `fund_id` would leave two
@@ -584,7 +584,7 @@ var LightningReceive = class _LightningReceive {
584
584
  currency: args.currency,
585
585
  // Both amounts are pinned here and never recomputed at settle time: a
586
586
  // rate that moved between issuance and payment must not change what the
587
- // caller was quoted (the internal-review shape).
587
+ // caller was quoted (the shape).
588
588
  amountMicro: args.amountMicro,
589
589
  amountMsats: created.amountMsats || args.amountMsats,
590
590
  paymentHash: created.paymentHash,
@@ -593,7 +593,7 @@ var LightningReceive = class _LightningReceive {
593
593
  });
594
594
  }
595
595
  /**
596
- * Ask the wallet whether one payment hash is paid, and when (internal-review).
596
+ * Ask the wallet whether one payment hash is paid, and when.
597
597
  *
598
598
  * The operator's reconcile verb runs this before it credits anything. A
599
599
  * `blocked` row implies payment — {@link applyOne} returns above the block
@@ -683,7 +683,6 @@ var LightningReceive = class _LightningReceive {
683
683
  }
684
684
  return settled;
685
685
  }
686
- // ── Internal ───────────────────────────────────────────────────────────
687
686
  /**
688
687
  * One invoice's settlement check. Returns the applied settlement, or
689
688
  * `undefined` when nothing changed (still unpaid, or retired unpaid).
@@ -1181,7 +1180,7 @@ function createDVMHost(opts = {}) {
1181
1180
  const dbRequired = !opts.jobStore && !opts.devMode && !opts.pool;
1182
1181
  if (!databaseUrl && dbRequired) {
1183
1182
  throw new Error(
1184
- "createDVMHost requires a Postgres database. Pass `database` opt or set DATABASE_URL env. See public design rationale (internal-review)."
1183
+ "createDVMHost requires a Postgres database. Pass `database` opt or set DATABASE_URL env."
1185
1184
  );
1186
1185
  }
1187
1186
  let store = opts.store ?? new MemoryKVStore();
@@ -1200,13 +1199,13 @@ function createDVMHost(opts = {}) {
1200
1199
  });
1201
1200
  applyRetryToPool(pool, "dvm-host");
1202
1201
  pgPool = pool;
1203
- const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-3RAXMNSY.js");
1202
+ const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-OGQ6IT4U.js");
1204
1203
  const pgJobStore = new PostgresJobStore2(pool);
1205
1204
  pendingInits.push(pgJobStore.init(), pgJobStore.initStreaming());
1206
1205
  jobStore = pgJobStore;
1207
1206
  pgStreamStore = pgJobStore;
1208
1207
  if (!opts.store) {
1209
- const { PostgresKVStore: PostgresKVStore2 } = await import("../postgres-kv-store-JFBDP5IP.js");
1208
+ const { PostgresKVStore: PostgresKVStore2 } = await import("../postgres-kv-store-D5E2EZ24.js");
1210
1209
  const pgKvStore = new PostgresKVStore2(pool);
1211
1210
  pendingInits.push(pgKvStore.init());
1212
1211
  store = pgKvStore;
@@ -1238,7 +1237,7 @@ function createDVMHost(opts = {}) {
1238
1237
  if (testMints.length > 0) {
1239
1238
  if (!envFlag(envMaybe.DVMKIT_ALLOW_TEST_MINTS)) {
1240
1239
  throw new Error(
1241
- `[FATAL] Refusing to boot: platform-hosted DVM configured with test mint(s) [${testMints.join(", ")}]. A test/FakeWallet mint settles no real money \u2014 every payment would silently no-op and revenue would read $0. If this is intentional (dev stack, smoke test, or the staging fleet), set DVMKIT_ALLOW_TEST_MINTS=true. (internal-review)`
1240
+ `[FATAL] Refusing to boot: platform-hosted DVM configured with test mint(s) [${testMints.join(", ")}]. A test/FakeWallet mint settles no real money \u2014 every payment would silently no-op and revenue would read $0. If this is intentional (dev stack, smoke test, or the staging fleet), set DVMKIT_ALLOW_TEST_MINTS=true.`
1242
1241
  );
1243
1242
  }
1244
1243
  console.warn(
@@ -1246,7 +1245,7 @@ function createDVMHost(opts = {}) {
1246
1245
  level: "warn",
1247
1246
  event: "platform_hosted_test_mint_allowed",
1248
1247
  mints: testMints,
1249
- message: "Platform-hosted DVM booting with test mint(s) because DVMKIT_ALLOW_TEST_MINTS=true \u2014 payments settle no real money. (internal-review)"
1248
+ message: "Platform-hosted DVM booting with test mint(s) because DVMKIT_ALLOW_TEST_MINTS=true \u2014 payments settle no real money."
1250
1249
  })
1251
1250
  );
1252
1251
  }
@@ -1291,11 +1290,11 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1291
1290
  let tempoChargeBackend = "user-supplied";
1292
1291
  const mppTempoRecipient = envMaybe.DVMKIT_TEMPO_RECIPIENT;
1293
1292
  if (!mpp && mppTempoRecipient) {
1294
- const { createMppFromOpts, createDualKeyMppxFromOpts, parseMppMethodsAllowlist } = await import("../mpp-setup-4FJD6ZHV.js");
1293
+ const { createMppFromOpts, createDualKeyMppxFromOpts, parseMppMethodsAllowlist } = await import("../mpp-setup-IOJBF7DB.js");
1295
1294
  tempoChargeBackend = pgPool ? "postgres" : "memory";
1296
1295
  let tempoCharge;
1297
1296
  if (pgPool) {
1298
- const { PostgresTempoChargeStore } = await import("../tempo-charge-store-RIFTALZK.js");
1297
+ const { PostgresTempoChargeStore } = await import("../tempo-charge-store-76TDAF34.js");
1299
1298
  const chargeStore = new PostgresTempoChargeStore(pgPool);
1300
1299
  pendingInits.push(chargeStore.init());
1301
1300
  tempoCharge = { store: chargeStore };
@@ -1372,7 +1371,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1372
1371
  chain: selectedChain,
1373
1372
  // Trimmed, so a blank DVMKIT_TEMPO_RPC_URL falls back to the
1374
1373
  // chain's bundled endpoint rather than becoming the transport
1375
- // target (internal-review).
1374
+ // target.
1376
1375
  transport: http(tempoRpc)
1377
1376
  });
1378
1377
  },
@@ -1445,7 +1444,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1445
1444
  }
1446
1445
  }
1447
1446
  const fxSource = envMaybe.DVMKIT_FX_SOURCE;
1448
- const { createFxFetcher, resolveFxSourceFromEnv, warmFxSnapshot } = await import("../pricing-4CEB34RM.js");
1447
+ const { createFxFetcher, resolveFxSourceFromEnv, warmFxSnapshot } = await import("../pricing-MU5GNUJZ.js");
1449
1448
  const fxFetcher = opts.fx ?? createFxFetcher({ source: resolveFxSourceFromEnv(envMaybe) });
1450
1449
  const hostRailConfigured = (opts.paymentMethods?.length ?? 0) > 0 || (effectiveMints?.length ?? 0) > 0 || !!x402WithDualServe || !!mpp;
1451
1450
  if (mounts.some((entry) => mountNeedsFx(entry, hostRailConfigured))) warmFxSnapshot(fxFetcher);
@@ -1455,7 +1454,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1455
1454
  assertReceiptIdentity(envMaybe, opts.builder, receiptKey, cashuOpts.dvmId, opts.devMode);
1456
1455
  let sharedPgReplayStore;
1457
1456
  if (pgPool) {
1458
- const { PostgresReplayStore: PostgresReplayStore2 } = await import("../postgres-replay-store-UJXRT6VO.js");
1457
+ const { PostgresReplayStore: PostgresReplayStore2 } = await import("../postgres-replay-store-IZFLTTAC.js");
1459
1458
  const store2 = new PostgresReplayStore2(pgPool);
1460
1459
  pendingInits.push(store2.init());
1461
1460
  sharedPgReplayStore = store2;
@@ -1467,7 +1466,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1467
1466
  const backend = auth.resolveReplayStore ? auth.resolveReplayStore({ postgresStore: sharedPgReplayStore }) : "user-supplied";
1468
1467
  replayStoreSummaries.push({ mount: entry.descriptor.name, backend });
1469
1468
  if (backend === "memory" && !opts.devMode) {
1470
- const msg = `secp256k1Auth on "${entry.descriptor.name}" fell back to the in-memory replay store. Multi-machine deploys MUST use a cross-machine store (e.g. PostgresReplayStore) \u2014 each machine's per-process window otherwise lets an attacker replay a captured signed envelope once per machine via the load balancer. Set DATABASE_URL or pass \`replayStore\` to secp256k1Auth(). (internal-review)`;
1469
+ const msg = `secp256k1Auth on "${entry.descriptor.name}" fell back to the in-memory replay store. Multi-machine deploys MUST use a cross-machine store (e.g. PostgresReplayStore) \u2014 each machine's per-process window otherwise lets an attacker replay a captured signed envelope once per machine via the load balancer. Set DATABASE_URL or pass \`replayStore\` to secp256k1Auth().`;
1471
1470
  if (failFast) {
1472
1471
  throw new Error(`[FATAL] ${msg}`);
1473
1472
  }
@@ -1483,24 +1482,24 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1483
1482
  }
1484
1483
  let sharedPgConsumedStore;
1485
1484
  if (pgPool) {
1486
- const { PostgresConsumedCredentialStore } = await import("../postgres-consumed-credential-store-VHBT4KEA.js");
1485
+ const { PostgresConsumedCredentialStore } = await import("../postgres-consumed-credential-store-ISRHBMOU.js");
1487
1486
  const consumedStore = new PostgresConsumedCredentialStore(pgPool);
1488
1487
  pendingInits.push(consumedStore.init());
1489
1488
  sharedPgConsumedStore = consumedStore;
1490
1489
  }
1491
1490
  if (pgPool) {
1492
- const { CreditLedger: CreditLedger2 } = await import("../credit-ledger-2DFQHNLB.js");
1491
+ const { CreditLedger: CreditLedger2 } = await import("../credit-ledger-5ZEJRI46.js");
1493
1492
  const pgLedger = new CreditLedger2(pgPool, tempoSessionStore);
1494
1493
  pendingInits.push(pgLedger.init());
1495
1494
  creditLedger = pgLedger;
1496
- const { PostgresProcessedPaymentStore: PostgresProcessedPaymentStore2 } = await import("../processed-payment-store-HAA4SFNK.js");
1495
+ const { PostgresProcessedPaymentStore: PostgresProcessedPaymentStore2 } = await import("../processed-payment-store-FIDI3RNH.js");
1497
1496
  const pgProcessed = new PostgresProcessedPaymentStore2(pgPool);
1498
1497
  pendingInits.push(pgProcessed.init());
1499
1498
  processedPayments = pgProcessed;
1500
1499
  } else {
1501
- const { MemoryCreditLedger: MemoryCreditLedger2 } = await import("../memory-credit-ledger-MNUOTQO5.js");
1500
+ const { MemoryCreditLedger: MemoryCreditLedger2 } = await import("../memory-credit-ledger-ZOH6C3N4.js");
1502
1501
  creditLedger = disposableCashu?.ledger ?? new MemoryCreditLedger2();
1503
- const { MemoryProcessedPaymentStore: MemoryProcessedPaymentStore2 } = await import("../processed-payment-store-HAA4SFNK.js");
1502
+ const { MemoryProcessedPaymentStore: MemoryProcessedPaymentStore2 } = await import("../processed-payment-store-FIDI3RNH.js");
1504
1503
  processedPayments = new MemoryProcessedPaymentStore2();
1505
1504
  }
1506
1505
  await Promise.all(pendingInits);
@@ -1509,7 +1508,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1509
1508
  const checkStoreFallback = (label, event, active, backend, hazardHint) => {
1510
1509
  storeSummaries.push({ label, backend });
1511
1510
  if (active && backend === "memory" && !opts.devMode) {
1512
- const msg = `The ${label} store fell back to in-memory. Multi-machine deploys MUST use a cross-machine store (set DATABASE_URL) \u2014 each machine's per-process window otherwise lets an attacker ${hazardHint} once per machine via the load balancer. (internal-review)`;
1511
+ const msg = `The ${label} store fell back to in-memory. Multi-machine deploys MUST use a cross-machine store (set DATABASE_URL) \u2014 each machine's per-process window otherwise lets an attacker ${hazardHint} once per machine via the load balancer.`;
1513
1512
  if (failFast) {
1514
1513
  throw new Error(`[FATAL] ${msg}`);
1515
1514
  }
@@ -1691,8 +1690,9 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1691
1690
  replayStores: replayStoreSummaries,
1692
1691
  stores: storeSummaries
1693
1692
  });
1694
- return new Promise((resolvePromise) => {
1693
+ return new Promise((resolvePromise, rejectPromise) => {
1695
1694
  const server = honoServe({ fetch: app.fetch, port }, (info) => {
1695
+ server.off("error", rejectPromise);
1696
1696
  const url = `http://{authority}`.replace("{authority}", `localhost:${info.port}`);
1697
1697
  nodeServer = server;
1698
1698
  const portBindMs = Date.now() - bootStart;
@@ -1708,7 +1708,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1708
1708
  level: "dvm_boot_phase_timings",
1709
1709
  totalMsToPortBind: portBindMs,
1710
1710
  phaseMs: deltas
1711
- // internal-review removed the pre-`listen` `mint_wait` phase: mint health
1711
+ // removed the pre-`listen` `mint_wait` phase: mint health
1712
1712
  // is now validated by the runtime tracker after the port binds, so
1713
1713
  // `totalMsToPortBind` no longer carries the mint-probe tail.
1714
1714
  })
@@ -1722,6 +1722,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1722
1722
  }
1723
1723
  });
1724
1724
  });
1725
+ server.once("error", rejectPromise);
1725
1726
  });
1726
1727
  }
1727
1728
  async function serveFn(serveOpts) {
@@ -2071,7 +2072,7 @@ function secp256k1Auth(opts = {}) {
2071
2072
  replayStore: null,
2072
2073
  driftSeconds,
2073
2074
  now,
2074
- // internal-review: the caller signs over the credit envelope, so it has to be in
2075
+ // the caller signs over the credit envelope, so it has to be in
2075
2076
  // the canonical bytes — but it is protocol-level, not capability input, so
2076
2077
  // the builder's schema must not have to tolerate it. Resolved once per
2077
2078
  // schema, cached with the verifier below.
@@ -26,7 +26,6 @@ type SSRFResolver = (host: string) => Promise<{
26
26
  * baseline denylist; extra entries compose with (never replace) the defaults.
27
27
  */
28
28
  interface SSRFGuardOpts {
29
- /** Custom DNS resolver — typically a test stub. */
30
29
  resolver?: SSRFResolver;
31
30
  /** Additional exact hostnames to deny on top of the defaults (lowercased on input). */
32
31
  extraHostnamesExact?: Iterable<string>;
@@ -61,7 +60,7 @@ interface SSRFGuardOpts {
61
60
  * link-local IP ranges, the AWS / GCP metadata IP, Fly's `*.internal`
62
61
  * service-discovery names, and a small denylist of obviously-internal
63
62
  * hostnames. Defence-in-depth — full mitigation belongs at the egress firewall
64
- * and at fetch-time IP pinning (`createPinnedFetch`, internal-review).
63
+ * and at fetch-time IP pinning (`createPinnedFetch`).
65
64
  *
66
65
  * Throws `SSRFError` with a `reason` discriminator so callers can branch onto
67
66
  * their own typed error taxonomy.