@dvmkit/sdk 0.6.0-rc.1 → 0.7.0-rc.2

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 (74) hide show
  1. package/README.md +2 -0
  2. package/dist/{chunk-PLG4XER6.js → chunk-26W6GPCD.js} +48 -6
  3. package/dist/{chunk-FI4CST2D.js → chunk-2OM2QPBE.js} +6 -8
  4. package/dist/{chunk-IWQHUSMO.js → chunk-62FI3NJF.js} +78 -2
  5. package/dist/{chunk-VHNPVGSA.js → chunk-6STC5TCP.js} +3 -3
  6. package/dist/{chunk-N5RZ5HVB.js → chunk-72V5DTEC.js} +2 -2
  7. package/dist/chunk-A262WVYX.js +6 -0
  8. package/dist/{chunk-HHBDBMEO.js → chunk-A6CXKAQV.js} +186 -93
  9. package/dist/{chunk-QR2EF2NI.js → chunk-AQ7OX5NX.js} +2 -2
  10. package/dist/{chunk-RLTSCKRI.js → chunk-BPYMEMQX.js} +50 -3
  11. package/dist/{chunk-BYCEKO65.js → chunk-CLIAFTUR.js} +102 -13
  12. package/dist/{chunk-GAOAYHZA.js → chunk-DNG4KGSC.js} +3 -3
  13. package/dist/{chunk-Z4ZT5LNT.js → chunk-GSLS4464.js} +3 -3
  14. package/dist/{chunk-7ZUKL4IV.js → chunk-H5FVVEEN.js} +17 -6
  15. package/dist/{chunk-IXR5RFK7.js → chunk-HCE4MPZ5.js} +1 -1
  16. package/dist/{chunk-FYRR2UEZ.js → chunk-I555L2WK.js} +1 -1
  17. package/dist/{chunk-EQLA4FFY.js → chunk-IIZQNDQU.js} +3 -3
  18. package/dist/{chunk-FUJ36YDV.js → chunk-KXWROQGK.js} +24 -1
  19. package/dist/{chunk-ETXDTUJO.js → chunk-LAKP6FUI.js} +55 -0
  20. package/dist/{chunk-X7EZ5CLI.js → chunk-MON76YBJ.js} +3 -3
  21. package/dist/chunk-OFSOLHRX.js +120 -0
  22. package/dist/{chunk-IV6Q7NRW.js → chunk-RAGX6VG7.js} +2 -2
  23. package/dist/{chunk-KA6VN5FK.js → chunk-RXPHMS4C.js} +3 -3
  24. package/dist/{chunk-JH3SX3LY.js → chunk-SPYEJXI7.js} +6 -6
  25. package/dist/{chunk-P6QON7ER.js → chunk-TRNMTTPX.js} +1 -1
  26. package/dist/{chunk-RCM3P2HE.js → chunk-UKD3R2KU.js} +55 -4
  27. package/dist/chunk-USL7ZEXN.js +17 -0
  28. package/dist/{chunk-OQA7IHI4.js → chunk-VB5OLOZH.js} +403 -235
  29. package/dist/{content-retention-BTGSQRfP.d.ts → content-retention-CbnouEnh.d.ts} +1 -1
  30. package/dist/{credit-ledger-MI2H7NEC.js → credit-ledger-7Z7LOCTN.js} +4 -5
  31. package/dist/{credit-menu-BAsrRu3z.d.ts → credit-menu-BO8yJppy.d.ts} +4 -4
  32. package/dist/{fx-BgDmyTdd.d.ts → fx-DSOZQ2z7.d.ts} +1 -1
  33. package/dist/index.d.ts +5 -5
  34. package/dist/index.js +236 -16
  35. package/dist/internal/caller.d.ts +4495 -7305
  36. package/dist/internal/caller.js +4415 -8122
  37. package/dist/internal/index.js +1 -1
  38. package/dist/internal/server.d.ts +7 -7
  39. package/dist/internal/server.js +27 -32
  40. package/dist/{job-store-BVeF5_Jq.d.ts → job-store-BJRlmq2Q.d.ts} +1 -1
  41. package/dist/{lightning-backend-40fIzz1W.d.ts → lightning-backend-f16-fsYK.d.ts} +4 -2
  42. package/dist/memory-credit-ledger-3WOS74UH.js +11 -0
  43. package/dist/{mpp-setup-RF5FXGGV.js → mpp-setup-XB4KATMU.js} +2 -2
  44. package/dist/{payout-reporter-3Y2U55ZX.js → payout-reporter-WT7XYW42.js} +2 -2
  45. package/dist/{postgres-consumed-credential-store-BUVCAPLS.js → postgres-consumed-credential-store-W7UP33AH.js} +3 -3
  46. package/dist/{postgres-job-store-VHLQBJZC.js → postgres-job-store-3KGUGFRD.js} +2 -2
  47. package/dist/{postgres-replay-store-ARZSQ45X.js → postgres-replay-store-CVNJJOQG.js} +2 -2
  48. package/dist/{pricing-XT2IAPNE.js → pricing-QAVZUTZR.js} +12 -12
  49. package/dist/{revenue-reporter-MAERPYGK.js → revenue-reporter-7UR3W2SD.js} +2 -2
  50. package/dist/server/index.d.ts +10 -10
  51. package/dist/server/index.js +46 -53
  52. package/dist/{step-cache-CPdH1hei.d.ts → step-cache-CJFiZU3n.d.ts} +1 -1
  53. package/dist/{tempo-charge-store-Q3D7KYMH.js → tempo-charge-store-GA6CED6O.js} +2 -2
  54. package/dist/{tempo-session-store-ZRNCOX7P.js → tempo-session-store-WZWQRITB.js} +3 -3
  55. package/dist/testing/index.d.ts +3 -3
  56. package/dist/testing/index.js +6 -7
  57. package/dist/{usd-AWlrwlM5.d.ts → usd-DmHHg0_4.d.ts} +1 -1
  58. package/dist/{x402-R6HPBY5D.js → x402-ZU4GML7Z.js} +9 -30
  59. package/package.json +3 -2
  60. package/dist/chunk-66HGCPBU.js +0 -25
  61. package/dist/chunk-AT6V3SY7.js +0 -102
  62. package/dist/chunk-B2IROPQF.js +0 -1844
  63. package/dist/chunk-CZULM42S.js +0 -143
  64. package/dist/chunk-GFY5FRX3.js +0 -218
  65. package/dist/chunk-HCLVYZUZ.js +0 -244
  66. package/dist/chunk-LE74UEV7.js +0 -1071
  67. package/dist/chunk-LIRAHP7B.js +0 -53
  68. package/dist/chunk-MZRJR2CW.js +0 -776
  69. package/dist/chunk-OFVV37XC.js +0 -57
  70. package/dist/chunk-PAIM66YA.js +0 -347
  71. package/dist/chunk-UOCZXO2Z.js +0 -1663
  72. package/dist/memory-credit-ledger-W2BAUYJP.js +0 -12
  73. package/dist/tempo-lifecycle-ZBBLFBMH.js +0 -15
  74. package/dist/tempo-wallet-B5XXV3YH.js +0 -40
@@ -1,20 +1,28 @@
1
1
  import {
2
- MemoryProcessedPaymentStore,
3
- PostgresProcessedPaymentStore,
4
- ProcessedPaymentReplayError
5
- } from "./chunk-XRLKGCAW.js";
2
+ TEMPO_MODERATO_CHAIN_ID,
3
+ TEMPO_MODERATO_RPC,
4
+ advertisedMethods,
5
+ challengeMeta,
6
+ installHostedTempoChargeGuard,
7
+ installHostedTempoCloseGuard,
8
+ isTempoInsufficientFundsError,
9
+ resolveTempoNetwork
10
+ } from "./chunk-HCE4MPZ5.js";
6
11
  import {
7
12
  createX402FacilitatorAuthHeaders,
8
13
  createX402FacilitatorClient,
14
+ paymentFailureStage,
9
15
  settleWithFacilitator,
10
- verifyWithFacilitator
11
- } from "./chunk-PLG4XER6.js";
16
+ verifyWithFacilitator,
17
+ withPaymentDiagnostics,
18
+ withPaymentStage
19
+ } from "./chunk-26W6GPCD.js";
12
20
  import {
13
21
  MemoryCreditLedger
14
- } from "./chunk-FYRR2UEZ.js";
22
+ } from "./chunk-I555L2WK.js";
15
23
  import {
16
24
  PostgresJobStore
17
- } from "./chunk-EQLA4FFY.js";
25
+ } from "./chunk-IIZQNDQU.js";
18
26
  import {
19
27
  parseStoreValue
20
28
  } from "./chunk-YG7G4DPZ.js";
@@ -25,7 +33,7 @@ import {
25
33
  humanizeZodIssues,
26
34
  signedRequestInput,
27
35
  zodIssuesOf
28
- } from "./chunk-N5RZ5HVB.js";
36
+ } from "./chunk-72V5DTEC.js";
29
37
  import {
30
38
  MemoryJobStore,
31
39
  UNCAPPABLE_ASK_TOTAL,
@@ -34,7 +42,7 @@ import {
34
42
  isJobRetentionStore,
35
43
  isReceiptIssuingStore,
36
44
  isStreamableJobStore
37
- } from "./chunk-IV6Q7NRW.js";
45
+ } from "./chunk-RAGX6VG7.js";
38
46
  import {
39
47
  ContentHoldError,
40
48
  JobCancelledError,
@@ -53,23 +61,26 @@ import {
53
61
  ADMIN_AUTH_CLOCK_SKEW_SECONDS,
54
62
  ADMIN_AUTH_NONCE_TTL_SECONDS,
55
63
  ADMIN_STATE_UNAVAILABLE,
64
+ IMPLICIT_CREDIT_TTL_MS,
56
65
  TEMPO_SESSION_UPDATED_REASON,
57
66
  X402_BATCH_CHANNEL_ABI,
58
67
  attestedDvmIdentity,
59
68
  buildAdminChallenge,
60
69
  checkMintHealth,
70
+ computeResultHash,
61
71
  createMonotonicClock,
72
+ formatStaleness,
62
73
  getWallet,
63
74
  isPublicRequestId,
64
- isTestMintUrl,
65
75
  isX402SettlementReconciliationReason,
66
- normaliseMintUrl,
67
76
  parseTraceparent,
68
77
  receiptPubkeyFromSecret,
78
+ signDrainReceipt,
79
+ signFundingReceipt,
80
+ signReceipt,
69
81
  toLockPubkey,
70
- verifyCashuToken,
71
82
  verifyChallenge
72
- } from "./chunk-OQA7IHI4.js";
83
+ } from "./chunk-VB5OLOZH.js";
73
84
  import {
74
85
  X402_BATCH_SETTLEMENT_SCHEME,
75
86
  X402_DEFAULT_FACILITATOR,
@@ -82,38 +93,26 @@ import {
82
93
  encodePaymentRequiredHeader,
83
94
  encodeSettleResponseHeader,
84
95
  exactEvmAuthorization,
85
- paymentRequiredV2FromV1,
86
- x402NetworkToCaip2
87
- } from "./chunk-IWQHUSMO.js";
88
- import {
89
- IMPLICIT_CREDIT_TTL_MS,
90
- computeResultHash,
91
- formatStaleness,
92
96
  msatsToUsd,
93
97
  msatsToUsdc,
94
- signDrainReceipt,
95
- signFundingReceipt,
96
- signReceipt,
97
- usdcToMsats
98
- } from "./chunk-PAIM66YA.js";
99
- import {
100
- resolveRpcOverride
101
- } from "./chunk-CZULM42S.js";
98
+ paymentRequiredV2FromV1,
99
+ resolveRpcOverride,
100
+ usdcToMsats,
101
+ x402NetworkToCaip2
102
+ } from "./chunk-62FI3NJF.js";
102
103
  import {
103
104
  RAIL_REFUNDABLE,
104
105
  canonicalRequestPath,
106
+ canonicalize,
105
107
  isZodSchema
106
- } from "./chunk-RCM3P2HE.js";
107
- import {
108
- canonicalize
109
- } from "./chunk-OFVV37XC.js";
108
+ } from "./chunk-UKD3R2KU.js";
110
109
  import {
111
110
  createConsoleLogger,
112
111
  loggers,
113
112
  pinDimension,
114
113
  withSpan,
115
114
  withTraceContext
116
- } from "./chunk-QR2EF2NI.js";
115
+ } from "./chunk-AQ7OX5NX.js";
117
116
  import {
118
117
  StepCache
119
118
  } from "./chunk-BQJIFRAZ.js";
@@ -122,16 +121,14 @@ import {
122
121
  InvalidCurrencyError,
123
122
  UnsupportedCurrencyError,
124
123
  createFxFetcher,
125
- fxRateFor,
126
- resolveFxSourceFromEnv,
127
- validateCurrency
128
- } from "./chunk-BYCEKO65.js";
129
- import {
130
124
  fiatToSatsCeil,
125
+ fxRateFor,
131
126
  parseUsdPrice,
127
+ resolveFxSourceFromEnv,
132
128
  roundUsd,
133
- satsToFiat
134
- } from "./chunk-AT6V3SY7.js";
129
+ satsToFiat,
130
+ validateCurrency
131
+ } from "./chunk-CLIAFTUR.js";
135
132
  import {
136
133
  CreditLedger,
137
134
  CreditLedgerError,
@@ -147,30 +144,26 @@ import {
147
144
  isNonChannelBitcoinRail,
148
145
  netOwedSats,
149
146
  x402SettlementPending
150
- } from "./chunk-JH3SX3LY.js";
151
- import {
152
- withSdkInitLock
153
- } from "./chunk-COYKJRMM.js";
147
+ } from "./chunk-SPYEJXI7.js";
154
148
  import {
155
149
  withPostgresRecoveryContext
156
- } from "./chunk-P6QON7ER.js";
150
+ } from "./chunk-TRNMTTPX.js";
157
151
  import {
152
+ DvmError,
158
153
  x402NetworkByCaip2
159
- } from "./chunk-RLTSCKRI.js";
160
- import {
161
- TEMPO_MODERATO_CHAIN_ID,
162
- TEMPO_MODERATO_RPC,
163
- advertisedMethods,
164
- challengeMeta,
165
- installHostedTempoChargeGuard,
166
- installHostedTempoCloseGuard,
167
- isTempoInsufficientFundsError,
168
- resolveTempoNetwork
169
- } from "./chunk-IXR5RFK7.js";
154
+ } from "./chunk-BPYMEMQX.js";
170
155
  import {
171
156
  createDiagnosticCapabilityAuthority,
172
157
  diagnosticConsole
173
- } from "./chunk-ETXDTUJO.js";
158
+ } from "./chunk-LAKP6FUI.js";
159
+ import {
160
+ MemoryProcessedPaymentStore,
161
+ PostgresProcessedPaymentStore,
162
+ ProcessedPaymentReplayError
163
+ } from "./chunk-XRLKGCAW.js";
164
+ import {
165
+ withSdkInitLock
166
+ } from "./chunk-COYKJRMM.js";
174
167
 
175
168
  // src/sdk/server/lock-pubkey-store.ts
176
169
  async function initLockPubkeyTable(db) {
@@ -3163,10 +3156,66 @@ function isRecord(value) {
3163
3156
  return !!value && typeof value === "object" && !Array.isArray(value);
3164
3157
  }
3165
3158
 
3159
+ // src/sdk/server/payment-diagnostics.ts
3160
+ import { Errors } from "mppx";
3161
+ function paymentFailureFields(error) {
3162
+ let category = "unknown";
3163
+ try {
3164
+ if (error instanceof ProcessedPaymentReplayError) category = "replay_detected";
3165
+ else if (error instanceof CreditLedgerError) category = "ledger_refused";
3166
+ else if (error instanceof Errors.InvalidChallengeError) category = "invalid_challenge";
3167
+ else if (error instanceof Errors.MalformedCredentialError || error instanceof Errors.InvalidPayloadError) category = "malformed_credential";
3168
+ else if (error instanceof Errors.PaymentExpiredError) category = "payment_expired";
3169
+ else if (error instanceof Errors.VerificationFailedError) category = "verification_failed";
3170
+ else if (error instanceof Errors.PaymentInsufficientError || error instanceof Errors.InsufficientBalanceError) category = "insufficient_funds";
3171
+ else if (error instanceof Errors.InvalidSignatureError) category = "invalid_signature";
3172
+ else if (error instanceof Errors.PaymentMethodUnsupportedError) category = "unsupported_method";
3173
+ } catch {
3174
+ }
3175
+ return { failure_category: category, failure_stage: paymentFailureStage(error) };
3176
+ }
3177
+
3166
3178
  // src/sdk/server/payment.ts
3167
3179
  import { randomBytes, randomUUID as randomUUID2 } from "crypto";
3168
3180
  import { Challenge } from "mppx";
3169
3181
 
3182
+ // src/lib/cashu/verify.ts
3183
+ import { getTokenMetadata } from "@cashu/cashu-ts";
3184
+ function verifyCashuToken(token, acceptedMints) {
3185
+ let mint, unit, totalMsats;
3186
+ try {
3187
+ const meta = getTokenMetadata(token);
3188
+ mint = meta.mint;
3189
+ unit = meta.unit;
3190
+ totalMsats = meta.amount.toNumber() * 1e3;
3191
+ } catch {
3192
+ throw new DvmError(
3193
+ "cashu_invalid_token",
3194
+ "The Cashu token could not be decoded.",
3195
+ "Ensure the token is a valid cashuA... or cashuB... string."
3196
+ );
3197
+ }
3198
+ const normalised = acceptedMints.map(normaliseMintUrl);
3199
+ if (!normalised.includes(normaliseMintUrl(mint))) {
3200
+ throw new DvmError(
3201
+ "cashu_mint_not_accepted",
3202
+ `Mint ${mint} is not accepted by this provider.`,
3203
+ `Accepted mints: ${acceptedMints.join(", ")}`
3204
+ );
3205
+ }
3206
+ return { mint, totalMsats, unit };
3207
+ }
3208
+ function normaliseMintUrl(url) {
3209
+ try {
3210
+ const u = new URL(url);
3211
+ u.hostname = u.hostname.toLowerCase();
3212
+ u.pathname = u.pathname.replace(/\/+/g, "/").replace(/\/+$/, "") || "/";
3213
+ return u.toString().replace(/\/$/, "");
3214
+ } catch {
3215
+ return url.toLowerCase().replace(/\/+$/, "");
3216
+ }
3217
+ }
3218
+
3170
3219
  // src/sdk/server/mpp-units.ts
3171
3220
  function decimalsFor(methodName) {
3172
3221
  switch (methodName) {
@@ -3221,6 +3270,22 @@ function methodNativeAmountToDecimal(amount, methodName) {
3221
3270
  return `${nativeAmount2 / scale}.${(nativeAmount2 % scale).toString().padStart(decimals, "0")}`;
3222
3271
  }
3223
3272
 
3273
+ // src/lib/mints.ts
3274
+ function isTestMintUrl(url) {
3275
+ let host;
3276
+ try {
3277
+ host = new URL(url).hostname.toLowerCase();
3278
+ } catch {
3279
+ return false;
3280
+ }
3281
+ if (host.startsWith("[") && host.endsWith("]")) host = host.slice(1, -1);
3282
+ if (LOOPBACK_HOSTS.has(host)) return true;
3283
+ if (host.endsWith(".localhost")) return true;
3284
+ return TEST_MINT_HOSTS.has(host);
3285
+ }
3286
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0", "::1"]);
3287
+ var TEST_MINT_HOSTS = /* @__PURE__ */ new Set(["testnut.cashu.space", "dvmkit-testmint.fly.dev"]);
3288
+
3224
3289
  // src/sdk/server/wallet-accumulator-receive.ts
3225
3290
  import {
3226
3291
  Amount as Amount2,
@@ -3470,6 +3535,9 @@ async function issueUpfrontChallenges(mpp, requiredMsats, resourcePath, btcUsdRa
3470
3535
  );
3471
3536
  }
3472
3537
  async function verifyUpfrontPayment(opts) {
3538
+ return withPaymentDiagnostics(() => verifyUpfrontPaymentInScope(opts));
3539
+ }
3540
+ async function verifyUpfrontPaymentInScope(opts) {
3473
3541
  const {
3474
3542
  cashuToken,
3475
3543
  requiredMsats,
@@ -3735,7 +3803,10 @@ async function verifyUpfrontPayment(opts) {
3735
3803
  );
3736
3804
  } catch (err) {
3737
3805
  const mapped = mapLedgerCommitError(err, x402Requirements);
3738
- if (mapped) return mapped;
3806
+ if (mapped) {
3807
+ logCredentialRejected("x402", "upfront", err);
3808
+ return mapped;
3809
+ }
3739
3810
  logCredentialRejected("x402", "upfront", err);
3740
3811
  return {
3741
3812
  paidMsats: 0,
@@ -3796,15 +3867,15 @@ async function verifyUpfrontPayment(opts) {
3796
3867
  x402Requirements
3797
3868
  });
3798
3869
  }
3799
- const { verifyX402Payment } = await import("./x402-R6HPBY5D.js");
3800
- const receipt = await verifyX402Payment(
3870
+ const { verifyX402Payment } = await import("./x402-ZU4GML7Z.js");
3871
+ const receipt = await withPaymentStage("verifier_broadcast", () => verifyX402Payment(
3801
3872
  x402Payment,
3802
3873
  x402Config,
3803
3874
  requiredUsdcMicro,
3804
3875
  x402Resource ?? "/v1/job",
3805
3876
  rate ?? 0,
3806
3877
  x402ExactVersions
3807
- );
3878
+ ));
3808
3879
  if (receipt.verified) {
3809
3880
  const settledUsdcMicro = receipt.amountUsdcMicro;
3810
3881
  const paidMsats = settledUsdcMicro === void 0 ? receipt.amountMsats : x402SettledShare(requiredMsats, Number(requiredUsdcMicro), settledUsdcMicro);
@@ -3848,7 +3919,10 @@ async function verifyUpfrontPayment(opts) {
3848
3919
  });
3849
3920
  } catch (err) {
3850
3921
  const mapped = mapLedgerCommitError(err, x402Requirements, true);
3851
- if (mapped) return mapped;
3922
+ if (mapped) {
3923
+ logCredentialRejected("x402", "upfront", err);
3924
+ return mapped;
3925
+ }
3852
3926
  throw err;
3853
3927
  }
3854
3928
  }
@@ -3965,7 +4039,7 @@ async function verifyUpfrontPayment(opts) {
3965
4039
  challenge_id: cred.challenge.id,
3966
4040
  amount: expectedAmount
3967
4041
  },
3968
- () => mpp.broadcastCredential(mppCredential, {
4042
+ () => withPaymentStage("verifier_broadcast", () => mpp.broadcastCredential(mppCredential, {
3969
4043
  request: { amount: expectedAmount },
3970
4044
  ...opts.hostingAdmissionId && {
3971
4045
  hostedPaymentIntent: {
@@ -3984,7 +4058,8 @@ async function verifyUpfrontPayment(opts) {
3984
4058
  path: resourcePath ?? "/v1/job",
3985
4059
  nonce: challengeMeta(cred.challenge)?.nonce ?? ""
3986
4060
  }
3987
- })
4061
+ })),
4062
+ { onError: paymentFailureFields }
3988
4063
  );
3989
4064
  tempoReceipt = receipt;
3990
4065
  return receipt;
@@ -4041,7 +4116,10 @@ async function verifyUpfrontPayment(opts) {
4041
4116
  credited = accepted.result;
4042
4117
  } catch (err) {
4043
4118
  const mapped = mapLedgerCommitError(err, x402Requirements, true);
4044
- if (mapped) return mapped;
4119
+ if (mapped) {
4120
+ logCredentialRejected("tempo", "upfront", err);
4121
+ return mapped;
4122
+ }
4045
4123
  throw err;
4046
4124
  }
4047
4125
  } else {
@@ -4072,7 +4150,7 @@ async function verifyUpfrontPayment(opts) {
4072
4150
  if (consumedCredentialStore) {
4073
4151
  const realm = mpp.realm;
4074
4152
  const id = cred.challenge.id;
4075
- if (await consumedCredentialStore.has(realm, id)) {
4153
+ if (await withPaymentStage("replay_store", () => consumedCredentialStore.has(realm, id))) {
4076
4154
  const mppChallenges = await issueUpfrontChallenges(
4077
4155
  mpp,
4078
4156
  requiredMsats,
@@ -4096,7 +4174,7 @@ async function verifyUpfrontPayment(opts) {
4096
4174
  };
4097
4175
  }
4098
4176
  if (!sessionBasis) {
4099
- await consumedCredentialStore.mark(realm, id, CONSUMED_CREDENTIAL_TTL_MS / 1e3);
4177
+ await withPaymentStage("replay_store", () => consumedCredentialStore.mark(realm, id, CONSUMED_CREDENTIAL_TTL_MS / 1e3));
4100
4178
  }
4101
4179
  }
4102
4180
  if (ledgerCtx) {
@@ -4111,16 +4189,19 @@ async function verifyUpfrontPayment(opts) {
4111
4189
  });
4112
4190
  } catch (err) {
4113
4191
  const mapped = mapLedgerCommitError(err, x402Requirements, true);
4114
- if (mapped) return mapped;
4192
+ if (mapped) {
4193
+ logCredentialRejected("tempo", "upfront", err);
4194
+ return mapped;
4195
+ }
4115
4196
  throw err;
4116
4197
  }
4117
4198
  }
4118
4199
  if (sessionBasis && consumedCredentialStore) {
4119
- await consumedCredentialStore.mark(
4200
+ await withPaymentStage("replay_store", () => consumedCredentialStore.mark(
4120
4201
  mpp.realm,
4121
4202
  cred.challenge.id,
4122
4203
  CONSUMED_CREDENTIAL_TTL_MS / 1e3
4123
- );
4204
+ ));
4124
4205
  }
4125
4206
  if (credited) {
4126
4207
  await mpp.completeHostedTempoCharge?.(cred.challenge.id).catch((error) => {
@@ -4689,6 +4770,9 @@ function buildPaymentErrorResponse(body, challenges, x402Requirements, status, x
4689
4770
  return new Response(JSON.stringify(mergedBody), { status: status ?? 402, headers });
4690
4771
  }
4691
4772
  async function verifyIncomingPayment(body, opts, snapshot) {
4773
+ return withPaymentDiagnostics(() => verifyIncomingPaymentInScope(body, opts, snapshot));
4774
+ }
4775
+ async function verifyIncomingPaymentInScope(body, opts, snapshot) {
4692
4776
  if (body.type !== "payment") return {};
4693
4777
  if (body.content.cashu_token) {
4694
4778
  if (opts.cashuMode === "p2pk-accumulator" && (opts.accumulatorDb || opts.disposableCashu) && opts.dvmId && opts.lockPubkeys && opts.lockPubkeys.length > 0) {
@@ -4771,15 +4855,15 @@ async function verifyIncomingPayment(body, opts, snapshot) {
4771
4855
  snapshot
4772
4856
  });
4773
4857
  }
4774
- const { verifyX402Payment } = await import("./x402-R6HPBY5D.js");
4775
- const receipt = await verifyX402Payment(
4858
+ const { verifyX402Payment } = await import("./x402-ZU4GML7Z.js");
4859
+ const receipt = await withPaymentStage("verifier_broadcast", () => verifyX402Payment(
4776
4860
  body.content.x402_payment,
4777
4861
  opts.x402Config,
4778
4862
  requiredUsdcMicro,
4779
4863
  opts.resourcePath ?? "/v1/job",
4780
4864
  rate,
4781
4865
  opts.x402ExactVersions
4782
- );
4866
+ ));
4783
4867
  if (!receipt.verified) {
4784
4868
  return {
4785
4869
  error: {
@@ -4828,6 +4912,7 @@ async function verifyIncomingPayment(body, opts, snapshot) {
4828
4912
  } catch (err) {
4829
4913
  const mapped = mapLedgerCommitError(err, void 0, true);
4830
4914
  if (mapped?.error) {
4915
+ logCredentialRejected("x402", "mid-job", err);
4831
4916
  return { error: { body: mapped.error.body, status: mapped.error.status } };
4832
4917
  }
4833
4918
  throw err;
@@ -4935,13 +5020,14 @@ async function verifyIncomingPayment(body, opts, snapshot) {
4935
5020
  challenge_id: credential.challenge.id,
4936
5021
  amount: expectedAmount
4937
5022
  },
4938
- () => mppServer.broadcastCredential(credential, {
5023
+ () => withPaymentStage("verifier_broadcast", () => mppServer.broadcastCredential(credential, {
4939
5024
  request: { amount: expectedAmount },
4940
5025
  ...opts.hostingPaymentSeq !== void 0 && {
4941
5026
  hostedPaymentIntent: { jobId: opts.jobId, paymentSeq: opts.hostingPaymentSeq }
4942
5027
  },
4943
5028
  ...expectedMeta && { meta: expectedMeta }
4944
- })
5029
+ })),
5030
+ { onError: paymentFailureFields }
4945
5031
  );
4946
5032
  let credited;
4947
5033
  if (ledgerCtx) {
@@ -4950,6 +5036,7 @@ async function verifyIncomingPayment(body, opts, snapshot) {
4950
5036
  } catch (err) {
4951
5037
  const mapped = mapLedgerCommitError(err, void 0, true);
4952
5038
  if (mapped?.error) {
5039
+ logCredentialRejected("tempo", "mid-job", err);
4953
5040
  return { error: { body: mapped.error.body, status: mapped.error.status } };
4954
5041
  }
4955
5042
  throw err;
@@ -5144,6 +5231,9 @@ function applyPaymentInfoToJob(job, info) {
5144
5231
  creditPendingPayment(job);
5145
5232
  }
5146
5233
  async function processIncomingPayment(job, body, opts) {
5234
+ return withPaymentDiagnostics(() => processIncomingPaymentInScope(job, body, opts));
5235
+ }
5236
+ async function processIncomingPaymentInScope(job, body, opts) {
5147
5237
  if (body.type !== "payment") return null;
5148
5238
  if (body.content.cashu_token) {
5149
5239
  if (opts.cashuMode === "p2pk-accumulator" && (opts.accumulatorDb || opts.disposableCashu) && opts.dvmId && opts.lockPubkeys && opts.lockPubkeys.length > 0) {
@@ -5196,15 +5286,15 @@ async function processIncomingPayment(job, body, opts) {
5196
5286
  try {
5197
5287
  const requiredMsats = job.pendingPaymentMsats ?? 0;
5198
5288
  const requiredUsdcMicro = job.pendingX402AmountUsdcMicro !== void 0 ? BigInt(job.pendingX402AmountUsdcMicro) : BigInt(msatsToUsdc(requiredMsats, rate));
5199
- const { verifyX402Payment } = await import("./x402-R6HPBY5D.js");
5200
- const receipt = await verifyX402Payment(
5289
+ const { verifyX402Payment } = await import("./x402-ZU4GML7Z.js");
5290
+ const receipt = await withPaymentStage("verifier_broadcast", () => verifyX402Payment(
5201
5291
  body.content.x402_payment,
5202
5292
  opts.x402Config,
5203
5293
  requiredUsdcMicro,
5204
5294
  opts.resourcePath ?? "/v1/job",
5205
5295
  rate,
5206
5296
  opts.x402ExactVersions
5207
- );
5297
+ ));
5208
5298
  if (receipt.verified) {
5209
5299
  if (job.pendingX402Nonce !== void 0) {
5210
5300
  const incomingNonce = decodePayment(body.content.x402_payment).payload.authorization.nonce;
@@ -5271,13 +5361,14 @@ async function processIncomingPayment(job, body, opts) {
5271
5361
  challenge_id: credential.challenge.id,
5272
5362
  amount: expectedAmount
5273
5363
  },
5274
- () => mppHandle.broadcastCredential(credential, {
5364
+ () => withPaymentStage("verifier_broadcast", () => mppHandle.broadcastCredential(credential, {
5275
5365
  request: { amount: expectedAmount },
5276
5366
  ...opts.hostingPaymentSeq !== void 0 && {
5277
5367
  hostedPaymentIntent: { jobId: opts.jobId, paymentSeq: opts.hostingPaymentSeq }
5278
5368
  },
5279
5369
  ...expectedMeta && { meta: expectedMeta }
5280
- })
5370
+ })),
5371
+ { onError: paymentFailureFields }
5281
5372
  );
5282
5373
  if (!job.pendingMppChallengeIds?.includes(credential.challenge.id)) {
5283
5374
  return {
@@ -5645,8 +5736,7 @@ async function resolveTopUpLedgerContext(opts, snapshot, binding) {
5645
5736
  if (!denomination.ok) {
5646
5737
  logSkip("denomination_unavailable", {
5647
5738
  currency,
5648
- cause: denomination.reason,
5649
- ...denomination.detail !== void 0 && { detail: denomination.detail }
5739
+ cause: denomination.reason
5650
5740
  });
5651
5741
  return void 0;
5652
5742
  }
@@ -5795,6 +5885,9 @@ function withDrawBasis(info, ctx, committed) {
5795
5885
  };
5796
5886
  }
5797
5887
  async function fundAndDraw(ctx, funding, tx) {
5888
+ return withPaymentStage("funding_ledger", () => fundAndDrawInScope(ctx, funding, tx));
5889
+ }
5890
+ async function fundAndDrawInScope(ctx, funding, tx) {
5798
5891
  const env = ctx.creditEnvelope;
5799
5892
  const fundedMicro = funding.fundedMicro ?? fundedMicroFor(ctx.priceFiat, funding.paidMsats, ctx.requiredMsats);
5800
5893
  const shortMidJob = ctx.midJob === true && funding.paidMsats < ctx.requiredMsats;
@@ -6221,7 +6314,7 @@ async function commitMarkedFunding(ctx, funding, outerTx) {
6221
6314
  const env = ctx.creditEnvelope;
6222
6315
  const creditId = ctx.fundOnly?.creditId ?? ctx.topUp?.creditId ?? env?.creditId ?? implicitCreditId(funding.rail, funding.paymentId);
6223
6316
  const drawId = ctx.fundOnly?.fundId ?? ctx.topUp?.drawId ?? env?.drawId ?? funding.paymentId;
6224
- await store.record({
6317
+ await withPaymentStage("replay_store", () => store.record({
6225
6318
  dvmId: ctx.dvmId,
6226
6319
  rail: funding.rail,
6227
6320
  paymentId: funding.paymentId,
@@ -6229,10 +6322,10 @@ async function commitMarkedFunding(ctx, funding, outerTx) {
6229
6322
  drawId,
6230
6323
  jobId: ctx.jobId,
6231
6324
  tx
6232
- });
6325
+ }));
6233
6326
  return fundAndDraw(ctx, funding, tx);
6234
6327
  };
6235
- return outerTx ? commit(outerTx) : store.withTx(commit);
6328
+ return outerTx ? commit(outerTx) : withPaymentStage("replay_store", () => store.withTx(commit));
6236
6329
  }
6237
6330
  async function commitMppFunding(ctx, credential, funding) {
6238
6331
  const session = mppSessionBasis(credential);
@@ -6594,15 +6687,14 @@ function x402NotOfferedResult(currency) {
6594
6687
  error: x402NotOfferedPaymentError(currency)
6595
6688
  };
6596
6689
  }
6597
- function logCredentialRejected(rail, phase, _err) {
6690
+ function logCredentialRejected(rail, phase, err) {
6598
6691
  diagnosticConsole.warn(
6599
6692
  {
6600
6693
  level: "warn",
6601
6694
  event: `${rail}_credential_rejected`,
6602
6695
  phase,
6603
6696
  rail,
6604
- error_name: void 0,
6605
- error_message: void 0
6697
+ ...paymentFailureFields(err)
6606
6698
  }
6607
6699
  );
6608
6700
  }
@@ -16526,7 +16618,7 @@ import {
16526
16618
  Amount as Amount3,
16527
16619
  CheckStateEnum as CheckStateEnum3,
16528
16620
  getP2PKExpectedWitnessPubkeys as getP2PKExpectedWitnessPubkeys2,
16529
- getTokenMetadata
16621
+ getTokenMetadata as getTokenMetadata2
16530
16622
  } from "@cashu/cashu-ts";
16531
16623
  function installAdminCreditRoutes(app, opts) {
16532
16624
  app.get("/admin/credit/pending-drains", (c) => handlePendingDrains(c, opts));
@@ -16887,7 +16979,7 @@ async function handleParkDrain(c, opts) {
16887
16979
  }
16888
16980
  let parsed;
16889
16981
  try {
16890
- const meta = getTokenMetadata(token);
16982
+ const meta = getTokenMetadata2(token);
16891
16983
  parsed = {
16892
16984
  mint: meta.mint,
16893
16985
  faceSats: Amount3.from(meta.amount).toNumber(),
@@ -19424,7 +19516,7 @@ async function createDVMServer(descriptor, opts) {
19424
19516
  }
19425
19517
  }
19426
19518
  if (!opts.onJobCompleted && platformToken && platformUrl && dvmId && opts.db) {
19427
- const { RevenueReporter } = await import("./revenue-reporter-MAERPYGK.js");
19519
+ const { RevenueReporter } = await import("./revenue-reporter-7UR3W2SD.js");
19428
19520
  const reporter = new RevenueReporter(
19429
19521
  opts.db,
19430
19522
  platformUrl,
@@ -19434,7 +19526,7 @@ async function createDVMServer(descriptor, opts) {
19434
19526
  revenueReporter = reporter;
19435
19527
  await reporter.init();
19436
19528
  reporter.startRetryLoop();
19437
- const { MemoryX402BatchStore, PayoutReporter } = await import("./payout-reporter-3Y2U55ZX.js");
19529
+ const { MemoryX402BatchStore, PayoutReporter } = await import("./payout-reporter-WT7XYW42.js");
19438
19530
  payoutReporter = new PayoutReporter({
19439
19531
  dvmId,
19440
19532
  db: opts.db,
@@ -22850,6 +22942,7 @@ export {
22850
22942
  derivedFundCreditId,
22851
22943
  drawSettlementRef,
22852
22944
  rateUnavailablePaymentError,
22945
+ isTestMintUrl,
22853
22946
  X402_BATCH_SETTLEMENT_NETWORK,
22854
22947
  X402_BATCH_SETTLEMENT_MAINNET_NETWORK,
22855
22948
  X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  initCallerLoggers
3
- } from "./chunk-66HGCPBU.js";
3
+ } from "./chunk-KXWROQGK.js";
4
4
  import {
5
5
  bindDiagnosticCapabilityAuthority,
6
6
  bindDiagnosticIdentityAuthority,
@@ -8,7 +8,7 @@ import {
8
8
  extendDiagnosticIdentityAuthority,
9
9
  projectDiagnosticFields,
10
10
  projectSpanRow
11
- } from "./chunk-ETXDTUJO.js";
11
+ } from "./chunk-LAKP6FUI.js";
12
12
 
13
13
  // src/sdk/logger.ts
14
14
  function createConsoleLogger(_jobId) {
@@ -1,6 +1,49 @@
1
- import {
2
- DvmError
3
- } from "./chunk-LIRAHP7B.js";
1
+ // src/lib/errors.ts
2
+ var DvmError = class extends Error {
3
+ constructor(code, message, hint, data, display, proseSources) {
4
+ super(message);
5
+ this.code = code;
6
+ this.hint = hint;
7
+ this.data = data;
8
+ this.display = display;
9
+ this.proseSources = proseSources;
10
+ this.name = "DvmError";
11
+ }
12
+ code;
13
+ hint;
14
+ data;
15
+ display;
16
+ proseSources;
17
+ };
18
+ function providerProseSources(...sources) {
19
+ const provenance = {};
20
+ for (const source of sources) {
21
+ if (!source) continue;
22
+ for (const field of ["message", "hint", "display"]) {
23
+ if (typeof source[field] === "string") provenance[field] = "provider";
24
+ }
25
+ }
26
+ return Object.keys(provenance).length > 0 ? provenance : void 0;
27
+ }
28
+ function isAbortError(err) {
29
+ return err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError");
30
+ }
31
+ function transportErrorCode(err) {
32
+ let current = err;
33
+ const seen = /* @__PURE__ */ new Set();
34
+ for (let depth = 0; depth < 5 && isErrorLike(current) && !seen.has(current); depth++) {
35
+ seen.add(current);
36
+ const code = current.code;
37
+ if (typeof code === "string" && /^(?:E[A-Z0-9_]{1,63}|UND_ERR_[A-Z0-9_]{1,63})$/.test(code)) {
38
+ return code;
39
+ }
40
+ current = current.cause;
41
+ }
42
+ return void 0;
43
+ }
44
+ function isErrorLike(value) {
45
+ return (typeof value === "object" || typeof value === "function") && value !== null;
46
+ }
4
47
 
5
48
  // src/lib/x402/networks.ts
6
49
  var X402_NETWORKS = [
@@ -99,6 +142,10 @@ var BY_CAIP2 = new Map(X402_NETWORKS.map((n) => [n.caip2, n]));
99
142
  var BY_SLUG = new Map(X402_NETWORKS.map((n) => [n.slug, n]));
100
143
 
101
144
  export {
145
+ DvmError,
146
+ providerProseSources,
147
+ isAbortError,
148
+ transportErrorCode,
102
149
  X402_NETWORKS,
103
150
  x402NetworkByCaip2,
104
151
  x402NetworkBySlug,