@dvmkit/sdk 0.1.5-rc.9 → 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.
- package/README.md +12 -0
- package/dist/{chunk-BIP6G74V.js → chunk-2ATUAUAO.js} +8 -8
- package/dist/{chunk-27V2ILSR.js → chunk-4A2RAKCW.js} +2 -2
- package/dist/{chunk-EVBK675R.js → chunk-6GRIKOFB.js} +28 -23
- package/dist/{chunk-CEOAHV2I.js → chunk-FDKRXOZO.js} +0 -5
- package/dist/{chunk-L4OYF4DQ.js → chunk-FT6HTUM4.js} +1 -1
- package/dist/{chunk-BTZY7VPH.js → chunk-GAIPXGM3.js} +1 -1
- package/dist/{chunk-U6M3ATSG.js → chunk-JDT5LCJC.js} +40 -6
- package/dist/{chunk-FROTD5XQ.js → chunk-JLXYOV4Y.js} +1 -2
- package/dist/{chunk-M7LHFJ5K.js → chunk-KMZXTBLA.js} +2 -2
- package/dist/{chunk-6BQM7TOW.js → chunk-L67WTZX2.js} +3 -7
- package/dist/{chunk-CGKZDODG.js → chunk-MG67KXU7.js} +0 -5
- package/dist/{chunk-JZWELPFH.js → chunk-MRAGS5VP.js} +1 -1
- package/dist/{chunk-2UUXIIOC.js → chunk-O2X2CCKH.js} +3 -3
- package/dist/{chunk-TQWGQCNV.js → chunk-OMIQMMME.js} +3 -3
- package/dist/{chunk-5PBOA25N.js → chunk-PCUQZDZA.js} +436 -355
- package/dist/{chunk-KVEHHC7W.js → chunk-PHHAYRQV.js} +7 -9
- package/dist/{chunk-SSSZUVWM.js → chunk-QP53RWAD.js} +88 -38
- package/dist/{chunk-DMNLFNTW.js → chunk-QT4ONTST.js} +1 -1
- package/dist/{chunk-RW5LP57K.js → chunk-SDK6KDJN.js} +0 -1
- package/dist/{chunk-MLRCSJYX.js → chunk-V7EVFLAK.js} +87 -90
- package/dist/{chunk-E4EVGPDX.js → chunk-XQXJKJ3P.js} +0 -2
- package/dist/{credit-ledger-2DFQHNLB.js → credit-ledger-5ZEJRI46.js} +1 -1
- package/dist/{credit-menu-enwMbn55.d.ts → credit-menu-D4Gcdgc4.d.ts} +487 -643
- package/dist/{fx-D860pZvP.d.ts → fx-B0SLBe5x.d.ts} +38 -82
- package/dist/index.d.ts +11 -14
- package/dist/index.js +2 -2
- package/dist/internal/caller.d.ts +618 -1525
- package/dist/internal/caller.js +28 -60
- package/dist/internal/server.d.ts +36 -61
- package/dist/internal/server.js +11 -11
- package/dist/{job-store-BUGqvCfL.d.ts → job-store-B2uZvga4.d.ts} +70 -59
- package/dist/{lightning-backend-BozcevPZ.d.ts → lightning-backend-CQBnQgsT.d.ts} +19 -27
- package/dist/{memory-credit-ledger-MNUOTQO5.js → memory-credit-ledger-ZOH6C3N4.js} +2 -2
- package/dist/{mpp-setup-4FJD6ZHV.js → mpp-setup-IOJBF7DB.js} +1 -1
- package/dist/{payout-reporter-RG6XNGPI.js → payout-reporter-5PIRYFVQ.js} +1 -1
- package/dist/{postgres-consumed-credential-store-VHBT4KEA.js → postgres-consumed-credential-store-ISRHBMOU.js} +1 -1
- package/dist/{postgres-job-store-3RAXMNSY.js → postgres-job-store-OGQ6IT4U.js} +1 -1
- package/dist/{postgres-kv-store-JFBDP5IP.js → postgres-kv-store-D5E2EZ24.js} +1 -1
- package/dist/{postgres-replay-store-UJXRT6VO.js → postgres-replay-store-IZFLTTAC.js} +1 -1
- package/dist/{pricing-4CEB34RM.js → pricing-MU5GNUJZ.js} +1 -1
- package/dist/{processed-payment-store-HAA4SFNK.js → processed-payment-store-FIDI3RNH.js} +1 -1
- package/dist/{revenue-reporter-ASZ7SHHH.js → revenue-reporter-NNCNRY4C.js} +1 -1
- package/dist/server/index.d.ts +53 -59
- package/dist/server/index.js +38 -37
- package/dist/{ssrf-DbFkpDv0.d.ts → ssrf-dMooihtY.d.ts} +1 -2
- package/dist/{step-cache-5dljDqrQ.d.ts → step-cache-CXg7ziML.d.ts} +389 -551
- package/dist/{tempo-charge-store-RIFTALZK.js → tempo-charge-store-76TDAF34.js} +1 -1
- package/dist/{tempo-lifecycle-DFIXQ54Q.js → tempo-lifecycle-DXM7QXJQ.js} +3 -3
- package/dist/{tempo-wallet-4QKSV65O.js → tempo-wallet-O67H5M4N.js} +2 -2
- package/dist/testing/index.d.ts +5 -15
- package/dist/testing/index.js +4 -11
- package/dist/{usd-DoRuAckA.d.ts → usd-BNDg1715.d.ts} +14 -16
- package/dist/{wallet-CJC8lwxx.d.ts → wallet-Dwjs5n_M.d.ts} +1 -1
- package/dist/{x402-5H27DCBE.js → x402-7S2EFINY.js} +2 -2
- package/package.json +2 -1
package/dist/server/index.d.ts
CHANGED
|
@@ -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-
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
10
|
-
export { a as JobStatus, b as JobStore, h as isStreamableJobStore } from '../job-store-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
133
|
-
* countersign every reclaim event with it
|
|
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
|
|
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
|
|
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 (
|
|
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
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
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
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* - **drain** — reclaim the unspent balance (
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
238
|
-
*
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
|
534
|
-
*
|
|
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}
|
|
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}
|
|
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
|
|
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>;
|
package/dist/server/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PostgresReplayStore
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-FT6HTUM4.js";
|
|
4
4
|
import {
|
|
5
5
|
PostgresJobStore
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-QP53RWAD.js";
|
|
7
7
|
import {
|
|
8
8
|
PostgresKVStore
|
|
9
|
-
} from "../chunk-
|
|
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-
|
|
24
|
+
} from "../chunk-FDKRXOZO.js";
|
|
25
25
|
import {
|
|
26
26
|
MemoryKVStore
|
|
27
|
-
} from "../chunk-
|
|
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-
|
|
81
|
+
} from "../chunk-PCUQZDZA.js";
|
|
82
82
|
import {
|
|
83
83
|
MemoryProcessedPaymentStore,
|
|
84
84
|
PostgresProcessedPaymentStore,
|
|
85
85
|
ProcessedPaymentReplayError
|
|
86
|
-
} from "../chunk-
|
|
86
|
+
} from "../chunk-QT4ONTST.js";
|
|
87
87
|
import "../chunk-BQ2NMWKE.js";
|
|
88
88
|
import {
|
|
89
89
|
MemoryCreditLedger
|
|
90
|
-
} from "../chunk-
|
|
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-
|
|
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-
|
|
124
|
+
} from "../chunk-XQXJKJ3P.js";
|
|
125
125
|
import "../chunk-66HGCPBU.js";
|
|
126
126
|
import "../chunk-FUJ36YDV.js";
|
|
127
|
-
import "../chunk-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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-
|
|
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-
|
|
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
|
|
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.
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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()
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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.
|