@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.
- package/README.md +2 -0
- package/dist/{chunk-PLG4XER6.js → chunk-26W6GPCD.js} +48 -6
- package/dist/{chunk-FI4CST2D.js → chunk-2OM2QPBE.js} +6 -8
- package/dist/{chunk-IWQHUSMO.js → chunk-62FI3NJF.js} +78 -2
- package/dist/{chunk-VHNPVGSA.js → chunk-6STC5TCP.js} +3 -3
- package/dist/{chunk-N5RZ5HVB.js → chunk-72V5DTEC.js} +2 -2
- package/dist/chunk-A262WVYX.js +6 -0
- package/dist/{chunk-HHBDBMEO.js → chunk-A6CXKAQV.js} +186 -93
- package/dist/{chunk-QR2EF2NI.js → chunk-AQ7OX5NX.js} +2 -2
- package/dist/{chunk-RLTSCKRI.js → chunk-BPYMEMQX.js} +50 -3
- package/dist/{chunk-BYCEKO65.js → chunk-CLIAFTUR.js} +102 -13
- package/dist/{chunk-GAOAYHZA.js → chunk-DNG4KGSC.js} +3 -3
- package/dist/{chunk-Z4ZT5LNT.js → chunk-GSLS4464.js} +3 -3
- package/dist/{chunk-7ZUKL4IV.js → chunk-H5FVVEEN.js} +17 -6
- package/dist/{chunk-IXR5RFK7.js → chunk-HCE4MPZ5.js} +1 -1
- package/dist/{chunk-FYRR2UEZ.js → chunk-I555L2WK.js} +1 -1
- package/dist/{chunk-EQLA4FFY.js → chunk-IIZQNDQU.js} +3 -3
- package/dist/{chunk-FUJ36YDV.js → chunk-KXWROQGK.js} +24 -1
- package/dist/{chunk-ETXDTUJO.js → chunk-LAKP6FUI.js} +55 -0
- package/dist/{chunk-X7EZ5CLI.js → chunk-MON76YBJ.js} +3 -3
- package/dist/chunk-OFSOLHRX.js +120 -0
- package/dist/{chunk-IV6Q7NRW.js → chunk-RAGX6VG7.js} +2 -2
- package/dist/{chunk-KA6VN5FK.js → chunk-RXPHMS4C.js} +3 -3
- package/dist/{chunk-JH3SX3LY.js → chunk-SPYEJXI7.js} +6 -6
- package/dist/{chunk-P6QON7ER.js → chunk-TRNMTTPX.js} +1 -1
- package/dist/{chunk-RCM3P2HE.js → chunk-UKD3R2KU.js} +55 -4
- package/dist/chunk-USL7ZEXN.js +17 -0
- package/dist/{chunk-OQA7IHI4.js → chunk-VB5OLOZH.js} +403 -235
- package/dist/{content-retention-BTGSQRfP.d.ts → content-retention-CbnouEnh.d.ts} +1 -1
- package/dist/{credit-ledger-MI2H7NEC.js → credit-ledger-7Z7LOCTN.js} +4 -5
- package/dist/{credit-menu-BAsrRu3z.d.ts → credit-menu-BO8yJppy.d.ts} +4 -4
- package/dist/{fx-BgDmyTdd.d.ts → fx-DSOZQ2z7.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +236 -16
- package/dist/internal/caller.d.ts +4495 -7305
- package/dist/internal/caller.js +4415 -8122
- package/dist/internal/index.js +1 -1
- package/dist/internal/server.d.ts +7 -7
- package/dist/internal/server.js +27 -32
- package/dist/{job-store-BVeF5_Jq.d.ts → job-store-BJRlmq2Q.d.ts} +1 -1
- package/dist/{lightning-backend-40fIzz1W.d.ts → lightning-backend-f16-fsYK.d.ts} +4 -2
- package/dist/memory-credit-ledger-3WOS74UH.js +11 -0
- package/dist/{mpp-setup-RF5FXGGV.js → mpp-setup-XB4KATMU.js} +2 -2
- package/dist/{payout-reporter-3Y2U55ZX.js → payout-reporter-WT7XYW42.js} +2 -2
- package/dist/{postgres-consumed-credential-store-BUVCAPLS.js → postgres-consumed-credential-store-W7UP33AH.js} +3 -3
- package/dist/{postgres-job-store-VHLQBJZC.js → postgres-job-store-3KGUGFRD.js} +2 -2
- package/dist/{postgres-replay-store-ARZSQ45X.js → postgres-replay-store-CVNJJOQG.js} +2 -2
- package/dist/{pricing-XT2IAPNE.js → pricing-QAVZUTZR.js} +12 -12
- package/dist/{revenue-reporter-MAERPYGK.js → revenue-reporter-7UR3W2SD.js} +2 -2
- package/dist/server/index.d.ts +10 -10
- package/dist/server/index.js +46 -53
- package/dist/{step-cache-CPdH1hei.d.ts → step-cache-CJFiZU3n.d.ts} +1 -1
- package/dist/{tempo-charge-store-Q3D7KYMH.js → tempo-charge-store-GA6CED6O.js} +2 -2
- package/dist/{tempo-session-store-ZRNCOX7P.js → tempo-session-store-WZWQRITB.js} +3 -3
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +6 -7
- package/dist/{usd-AWlrwlM5.d.ts → usd-DmHHg0_4.d.ts} +1 -1
- package/dist/{x402-R6HPBY5D.js → x402-ZU4GML7Z.js} +9 -30
- package/package.json +3 -2
- package/dist/chunk-66HGCPBU.js +0 -25
- package/dist/chunk-AT6V3SY7.js +0 -102
- package/dist/chunk-B2IROPQF.js +0 -1844
- package/dist/chunk-CZULM42S.js +0 -143
- package/dist/chunk-GFY5FRX3.js +0 -218
- package/dist/chunk-HCLVYZUZ.js +0 -244
- package/dist/chunk-LE74UEV7.js +0 -1071
- package/dist/chunk-LIRAHP7B.js +0 -53
- package/dist/chunk-MZRJR2CW.js +0 -776
- package/dist/chunk-OFVV37XC.js +0 -57
- package/dist/chunk-PAIM66YA.js +0 -347
- package/dist/chunk-UOCZXO2Z.js +0 -1663
- package/dist/memory-credit-ledger-W2BAUYJP.js +0 -12
- package/dist/tempo-lifecycle-ZBBLFBMH.js +0 -15
- package/dist/tempo-wallet-B5XXV3YH.js +0 -40
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
diagnosticConsole
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LAKP6FUI.js";
|
|
4
4
|
|
|
5
5
|
// src/sdk/pricing/currency.ts
|
|
6
6
|
var InvalidCurrencyError = class extends Error {
|
|
@@ -35,6 +35,98 @@ function validateCurrency(raw) {
|
|
|
35
35
|
return raw;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
// src/sdk/pricing/usd.ts
|
|
39
|
+
var InvalidFxRateError = class extends Error {
|
|
40
|
+
code = "invalid_fx_rate";
|
|
41
|
+
ratePerBtc;
|
|
42
|
+
constructor(ratePerBtc) {
|
|
43
|
+
super(
|
|
44
|
+
`invalid fx rate ${String(ratePerBtc)} \u2014 expected a finite positive number of fiat per BTC`
|
|
45
|
+
);
|
|
46
|
+
this.ratePerBtc = ratePerBtc;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function fiatToSatsCeil(amount, ratePerBtc) {
|
|
50
|
+
if (!Number.isFinite(ratePerBtc) || ratePerBtc <= 0) {
|
|
51
|
+
throw new InvalidFxRateError(ratePerBtc);
|
|
52
|
+
}
|
|
53
|
+
if (!Number.isFinite(amount) || amount < 0) return 0;
|
|
54
|
+
return Math.ceil(amount * 1e8 / ratePerBtc);
|
|
55
|
+
}
|
|
56
|
+
function satsToFiat(sats, ratePerBtc) {
|
|
57
|
+
if (!Number.isFinite(ratePerBtc) || ratePerBtc <= 0) {
|
|
58
|
+
throw new InvalidFxRateError(ratePerBtc);
|
|
59
|
+
}
|
|
60
|
+
return sats / 1e8 * ratePerBtc;
|
|
61
|
+
}
|
|
62
|
+
var InvalidUsdPriceError = class extends Error {
|
|
63
|
+
constructor(field, value, detail) {
|
|
64
|
+
super(`${field}: ${detail}`);
|
|
65
|
+
this.field = field;
|
|
66
|
+
this.value = value;
|
|
67
|
+
this.name = "InvalidUsdPriceError";
|
|
68
|
+
}
|
|
69
|
+
field;
|
|
70
|
+
value;
|
|
71
|
+
code = "invalid_usd_price";
|
|
72
|
+
};
|
|
73
|
+
function parseUsdPrice(value, field) {
|
|
74
|
+
if (!USD_PRICE_RE.test(value)) {
|
|
75
|
+
throw new InvalidUsdPriceError(
|
|
76
|
+
field,
|
|
77
|
+
value,
|
|
78
|
+
`${JSON.stringify(value)} is not a USD price literal. Use a "$X.XX" string, e.g. "$0.05".`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const usd = parseFloat(value.slice(1));
|
|
82
|
+
if (!Number.isFinite(usd) || usd < MIN_USD_PRICE) {
|
|
83
|
+
throw new InvalidUsdPriceError(
|
|
84
|
+
field,
|
|
85
|
+
value,
|
|
86
|
+
`${JSON.stringify(value)} is below ${MIN_USD_PRICE_LITERAL}, the smallest price the wire can carry \u2014 every price surface rounds to four decimals, so this would advertise as $0 and then charge anyway. Charge at least ${MIN_USD_PRICE_LITERAL}, or omit the price for a free capability.`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
if (roundUsd(usd) !== usd) {
|
|
90
|
+
throw new InvalidUsdPriceError(
|
|
91
|
+
field,
|
|
92
|
+
value,
|
|
93
|
+
`${JSON.stringify(value)} carries more than four decimal places. Every price surface rounds to four, so this would advertise ${formatUsd(roundUsd(usd))} and charge something else. Use at most four decimals.`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
if (!Number.isSafeInteger(Math.round(usd * 1e6))) {
|
|
97
|
+
throw new InvalidUsdPriceError(
|
|
98
|
+
field,
|
|
99
|
+
value,
|
|
100
|
+
`${JSON.stringify(value)} is too large to denominate. Use an amount under $9,007,199,254.`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return usd;
|
|
104
|
+
}
|
|
105
|
+
function roundUsd(usd) {
|
|
106
|
+
return Math.round(usd * 1e4) / 1e4;
|
|
107
|
+
}
|
|
108
|
+
function formatUsd(usd) {
|
|
109
|
+
if (usd === 0) return "$0.00";
|
|
110
|
+
if (usd >= 0.01) return `$${usd.toFixed(2)}`;
|
|
111
|
+
return `$${usd.toFixed(4)}`;
|
|
112
|
+
}
|
|
113
|
+
function formatFiat(amount, currency) {
|
|
114
|
+
const code = currency.toUpperCase();
|
|
115
|
+
const symbol = FIAT_SYMBOLS[currency] ?? "";
|
|
116
|
+
const digits = currency === "jpy" ? 0 : amount >= 0.01 || amount === 0 ? 2 : 4;
|
|
117
|
+
const body = `${amount.toFixed(digits)} ${code}`;
|
|
118
|
+
return symbol ? `${symbol}${body}` : body;
|
|
119
|
+
}
|
|
120
|
+
var USD_PRICE_RE = /^\$\d+(\.\d+)?$/;
|
|
121
|
+
var MIN_USD_PRICE = 1e-4;
|
|
122
|
+
var MIN_USD_PRICE_LITERAL = '"$0.0001"';
|
|
123
|
+
var FIAT_SYMBOLS = {
|
|
124
|
+
usd: "$",
|
|
125
|
+
eur: "\u20AC",
|
|
126
|
+
gbp: "\xA3",
|
|
127
|
+
jpy: "\xA5"
|
|
128
|
+
};
|
|
129
|
+
|
|
38
130
|
// src/sdk/pricing/fx.ts
|
|
39
131
|
var DEFAULT_FX_CURRENCIES = ["usd", "eur", "gbp", "jpy"];
|
|
40
132
|
var DEFAULT_FX_RATE_SOURCE = `https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=${DEFAULT_FX_CURRENCIES.join(",")}`;
|
|
@@ -268,20 +360,18 @@ function resolveFxSourceFromEnv(env) {
|
|
|
268
360
|
return raw;
|
|
269
361
|
}
|
|
270
362
|
|
|
271
|
-
// src/sdk/pricing/upfront.ts
|
|
272
|
-
function buildUpfront(input) {
|
|
273
|
-
const currency = validateCurrency(input.currency);
|
|
274
|
-
const amount = input.amount;
|
|
275
|
-
if (!Number.isFinite(amount) || amount < 0) {
|
|
276
|
-
throw new Error(`invalid upfront amount: ${String(amount)} (must be a non-negative number)`);
|
|
277
|
-
}
|
|
278
|
-
return { amount, currency };
|
|
279
|
-
}
|
|
280
|
-
|
|
281
363
|
export {
|
|
282
364
|
InvalidCurrencyError,
|
|
283
365
|
UnsupportedCurrencyError,
|
|
284
366
|
validateCurrency,
|
|
367
|
+
InvalidFxRateError,
|
|
368
|
+
fiatToSatsCeil,
|
|
369
|
+
satsToFiat,
|
|
370
|
+
InvalidUsdPriceError,
|
|
371
|
+
parseUsdPrice,
|
|
372
|
+
roundUsd,
|
|
373
|
+
formatUsd,
|
|
374
|
+
formatFiat,
|
|
285
375
|
DEFAULT_FX_CURRENCIES,
|
|
286
376
|
DEFAULT_FX_RATE_SOURCE,
|
|
287
377
|
FX_CACHE_TTL_MS,
|
|
@@ -290,6 +380,5 @@ export {
|
|
|
290
380
|
createFxFetcher,
|
|
291
381
|
warmFxSnapshot,
|
|
292
382
|
fxRateFor,
|
|
293
|
-
resolveFxSourceFromEnv
|
|
294
|
-
buildUpfront
|
|
383
|
+
resolveFxSourceFromEnv
|
|
295
384
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
diagnosticConsole
|
|
3
|
+
} from "./chunk-LAKP6FUI.js";
|
|
1
4
|
import {
|
|
2
5
|
withSdkInitLock
|
|
3
6
|
} from "./chunk-COYKJRMM.js";
|
|
4
|
-
import {
|
|
5
|
-
diagnosticConsole
|
|
6
|
-
} from "./chunk-ETXDTUJO.js";
|
|
7
7
|
|
|
8
8
|
// src/sdk/server/payout-reporter.ts
|
|
9
9
|
import { createHash, randomUUID } from "crypto";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
diagnosticConsole
|
|
3
|
+
} from "./chunk-LAKP6FUI.js";
|
|
1
4
|
import {
|
|
2
5
|
withSdkInitLock
|
|
3
6
|
} from "./chunk-COYKJRMM.js";
|
|
4
|
-
import {
|
|
5
|
-
diagnosticConsole
|
|
6
|
-
} from "./chunk-ETXDTUJO.js";
|
|
7
7
|
|
|
8
8
|
// src/sdk/server/revenue-reporter.ts
|
|
9
9
|
import { randomUUID } from "crypto";
|
|
@@ -2,19 +2,20 @@ import {
|
|
|
2
2
|
createX402FacilitatorAuthHeaders,
|
|
3
3
|
settleWithFacilitator,
|
|
4
4
|
verifyWithFacilitator
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-26W6GPCD.js";
|
|
6
6
|
import {
|
|
7
7
|
buildPaymentRequirements,
|
|
8
8
|
decodePayment,
|
|
9
9
|
encodeSettleResponseHeader,
|
|
10
|
-
exactEvmAuthorization
|
|
11
|
-
} from "./chunk-IWQHUSMO.js";
|
|
12
|
-
import {
|
|
10
|
+
exactEvmAuthorization,
|
|
13
11
|
usdcToMsats
|
|
14
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-62FI3NJF.js";
|
|
15
13
|
import {
|
|
16
14
|
callerLoggers
|
|
17
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-KXWROQGK.js";
|
|
16
|
+
import {
|
|
17
|
+
diagnosticConsole
|
|
18
|
+
} from "./chunk-LAKP6FUI.js";
|
|
18
19
|
|
|
19
20
|
// src/lib/x402/verify.ts
|
|
20
21
|
async function verifyX402Payment(paymentHeader, config, requiredUsdcMicro, resource, btcUsdRate, exactVersions = { v1: true, v2: true }) {
|
|
@@ -30,9 +31,11 @@ async function verifyX402Payment(paymentHeader, config, requiredUsdcMicro, resou
|
|
|
30
31
|
try {
|
|
31
32
|
payload = decodePayment(paymentHeader);
|
|
32
33
|
} catch {
|
|
34
|
+
logRejected("malformed_credential", "verifier");
|
|
33
35
|
return { verified: false, amountMsats: 0, invalidReason: "decode_failed" };
|
|
34
36
|
}
|
|
35
37
|
if (payload.x402Version === 1 && !exactVersions.v1 || payload.x402Version === 2 && !exactVersions.v2) {
|
|
38
|
+
logRejected("unsupported_version", "verifier");
|
|
36
39
|
return { verified: false, amountMsats: 0, invalidReason: "unsupported_version" };
|
|
37
40
|
}
|
|
38
41
|
const requirementOpts = { x402Config: config, requiredUsdcMicro, resource };
|
|
@@ -81,6 +84,14 @@ async function verifyX402Payment(paymentHeader, config, requiredUsdcMicro, resou
|
|
|
81
84
|
}
|
|
82
85
|
);
|
|
83
86
|
}
|
|
87
|
+
function logRejected(category, stage) {
|
|
88
|
+
diagnosticConsole.warn({
|
|
89
|
+
event: "x402_credential_rejected",
|
|
90
|
+
rail: "x402",
|
|
91
|
+
failure_category: category,
|
|
92
|
+
failure_stage: stage
|
|
93
|
+
});
|
|
94
|
+
}
|
|
84
95
|
|
|
85
96
|
export {
|
|
86
97
|
verifyX402Payment
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
ContentHoldError,
|
|
3
3
|
applyContentHoldMutation
|
|
4
4
|
} from "./chunk-AFV77S4C.js";
|
|
5
|
+
import {
|
|
6
|
+
diagnosticConsole
|
|
7
|
+
} from "./chunk-LAKP6FUI.js";
|
|
5
8
|
import {
|
|
6
9
|
withSdkInitLock
|
|
7
10
|
} from "./chunk-COYKJRMM.js";
|
|
8
|
-
import {
|
|
9
|
-
diagnosticConsole
|
|
10
|
-
} from "./chunk-ETXDTUJO.js";
|
|
11
11
|
|
|
12
12
|
// src/sdk/server/postgres-job-store.ts
|
|
13
13
|
import { createHash } from "crypto";
|
|
@@ -45,7 +45,30 @@ function isOpaqueToken(segment) {
|
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// src/lib/caller-loggers.ts
|
|
49
|
+
var callerLoggers = buildNoopLoggers();
|
|
50
|
+
function initCallerLoggers(nextLoggers) {
|
|
51
|
+
callerLoggers = nextLoggers;
|
|
52
|
+
}
|
|
53
|
+
function buildNoopLoggers() {
|
|
54
|
+
const noopLogger = {
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function -- standalone caller has no exporter
|
|
56
|
+
info() {
|
|
57
|
+
},
|
|
58
|
+
async span(_name, _attrs, fn) {
|
|
59
|
+
return fn();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
cashu: noopLogger,
|
|
64
|
+
lightning: noopLogger,
|
|
65
|
+
x402: noopLogger
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
48
69
|
export {
|
|
49
70
|
redactUrl,
|
|
50
|
-
redactUrlsInText
|
|
71
|
+
redactUrlsInText,
|
|
72
|
+
callerLoggers,
|
|
73
|
+
initCallerLoggers
|
|
51
74
|
};
|
|
@@ -998,11 +998,63 @@ var diagnostic_catalogue_v1_default = {
|
|
|
998
998
|
],
|
|
999
999
|
clientVersionFields: [
|
|
1000
1000
|
"client.version"
|
|
1001
|
+
],
|
|
1002
|
+
paymentSkipReasons: [
|
|
1003
|
+
"credit_or_draw_missing",
|
|
1004
|
+
"draw_not_pending",
|
|
1005
|
+
"draw_job_mismatch",
|
|
1006
|
+
"rail_mismatch",
|
|
1007
|
+
"channel_binding_mismatch",
|
|
1008
|
+
"denomination_unavailable",
|
|
1009
|
+
"topup_cap_unavailable",
|
|
1010
|
+
"topup_cap_currency_mismatch",
|
|
1011
|
+
"unknown"
|
|
1012
|
+
],
|
|
1013
|
+
denominationCauses: [
|
|
1014
|
+
"no_msats",
|
|
1015
|
+
"sub_micro",
|
|
1016
|
+
"unsupported_currency",
|
|
1017
|
+
"rate_unavailable",
|
|
1018
|
+
"rate_stale_refused",
|
|
1019
|
+
"unknown"
|
|
1020
|
+
],
|
|
1021
|
+
paymentFailureCategories: [
|
|
1022
|
+
"invalid_challenge",
|
|
1023
|
+
"malformed_credential",
|
|
1024
|
+
"payment_expired",
|
|
1025
|
+
"verification_failed",
|
|
1026
|
+
"insufficient_funds",
|
|
1027
|
+
"invalid_signature",
|
|
1028
|
+
"unsupported_method",
|
|
1029
|
+
"replay_detected",
|
|
1030
|
+
"ledger_refused",
|
|
1031
|
+
"settlement_failed",
|
|
1032
|
+
"unsupported_version",
|
|
1033
|
+
"unknown"
|
|
1034
|
+
],
|
|
1035
|
+
paymentFailureStages: [
|
|
1036
|
+
"verifier",
|
|
1037
|
+
"broadcast",
|
|
1038
|
+
"verifier_broadcast",
|
|
1039
|
+
"replay_store",
|
|
1040
|
+
"funding_ledger",
|
|
1041
|
+
"unknown"
|
|
1042
|
+
],
|
|
1043
|
+
paymentPhases: [
|
|
1044
|
+
"upfront",
|
|
1045
|
+
"mid-job"
|
|
1001
1046
|
]
|
|
1002
1047
|
};
|
|
1003
1048
|
|
|
1004
1049
|
// src/observability/projection.ts
|
|
1005
1050
|
var DIAGNOSTIC_CATALOGUE_VERSION = diagnostic_catalogue_v1_default.version;
|
|
1051
|
+
var PAYMENT_ENUMS = {
|
|
1052
|
+
reason: new Set(diagnostic_catalogue_v1_default.paymentSkipReasons),
|
|
1053
|
+
cause: new Set(diagnostic_catalogue_v1_default.denominationCauses),
|
|
1054
|
+
failure_category: new Set(diagnostic_catalogue_v1_default.paymentFailureCategories),
|
|
1055
|
+
failure_stage: new Set(diagnostic_catalogue_v1_default.paymentFailureStages),
|
|
1056
|
+
phase: new Set(diagnostic_catalogue_v1_default.paymentPhases)
|
|
1057
|
+
};
|
|
1006
1058
|
var EVENTS = new Set(diagnostic_catalogue_v1_default.events);
|
|
1007
1059
|
var ROUTE_TEMPLATES = [...diagnostic_catalogue_v1_default.routeTemplates].sort(
|
|
1008
1060
|
compareRouteTemplates
|
|
@@ -1202,6 +1254,9 @@ function projectFields(input, dataset, authority, identityAuthority) {
|
|
|
1202
1254
|
return output;
|
|
1203
1255
|
}
|
|
1204
1256
|
function projectField(key, value, dataset, authority, identityAuthority) {
|
|
1257
|
+
const paymentEnum = Object.hasOwn(PAYMENT_ENUMS, key) ? PAYMENT_ENUMS[key] : void 0;
|
|
1258
|
+
if (paymentEnum)
|
|
1259
|
+
return typeof value === "string" && paymentEnum.has(value) ? value : void 0;
|
|
1205
1260
|
if (BOOLEAN_FIELDS.has(key))
|
|
1206
1261
|
return typeof value === "boolean" ? value : void 0;
|
|
1207
1262
|
if (INTEGER_FIELDS.has(key))
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
parseStoreValue,
|
|
3
3
|
stringifyStoreValue
|
|
4
4
|
} from "./chunk-YG7G4DPZ.js";
|
|
5
|
+
import {
|
|
6
|
+
withPostgresTransactionRecovery
|
|
7
|
+
} from "./chunk-TRNMTTPX.js";
|
|
5
8
|
import {
|
|
6
9
|
withSdkInitLock
|
|
7
10
|
} from "./chunk-COYKJRMM.js";
|
|
8
|
-
import {
|
|
9
|
-
withPostgresTransactionRecovery
|
|
10
|
-
} from "./chunk-P6QON7ER.js";
|
|
11
11
|
|
|
12
12
|
// src/sdk/server/tempo-session-store.ts
|
|
13
13
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
X402_DEFAULT_NETWORK,
|
|
3
|
+
resolveRpcHttpTransportOptions,
|
|
4
|
+
resolveRpcOverride
|
|
5
|
+
} from "./chunk-62FI3NJF.js";
|
|
6
|
+
import {
|
|
7
|
+
redactUrl,
|
|
8
|
+
redactUrlsInText
|
|
9
|
+
} from "./chunk-KXWROQGK.js";
|
|
10
|
+
import {
|
|
11
|
+
DvmError,
|
|
12
|
+
x402NetworkByCaip2,
|
|
13
|
+
x402SupportedNetworksHint
|
|
14
|
+
} from "./chunk-BPYMEMQX.js";
|
|
15
|
+
|
|
16
|
+
// src/lib/x402/asset.ts
|
|
17
|
+
function resolveX402Asset(network = X402_DEFAULT_NETWORK) {
|
|
18
|
+
const spec = x402NetworkByCaip2(network);
|
|
19
|
+
if (!spec) return null;
|
|
20
|
+
return {
|
|
21
|
+
address: spec.usdc,
|
|
22
|
+
symbol: "USDC",
|
|
23
|
+
// "native" is the load-bearing word: every contract in the table is
|
|
24
|
+
// Circle's own USDC, and the dollars that read as zero here are the
|
|
25
|
+
// bridged ones.
|
|
26
|
+
label: "native USDC",
|
|
27
|
+
unit: "USDC",
|
|
28
|
+
networkLabel: spec.label,
|
|
29
|
+
confusable: spec.confusable
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/lib/evm-private-key.ts
|
|
34
|
+
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
35
|
+
import { hexToBytes } from "@noble/hashes/utils.js";
|
|
36
|
+
var EVM_PRIVATE_KEY_RE = /^0x[0-9a-fA-F]{64}$/;
|
|
37
|
+
function isValidEvmPrivateKey(value) {
|
|
38
|
+
return EVM_PRIVATE_KEY_RE.test(value) && secp256k1.utils.isValidSecretKey(hexToBytes(value.slice(2)));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/lib/x402/wallet.ts
|
|
42
|
+
async function ensureAddress(wallet) {
|
|
43
|
+
if (!isValidEvmPrivateKey(wallet.privateKey)) throw invalidX402PrivateKey();
|
|
44
|
+
if (wallet.address) return wallet;
|
|
45
|
+
const { privateKeyToAccount } = await import("viem/accounts");
|
|
46
|
+
const account = privateKeyToAccount(wallet.privateKey);
|
|
47
|
+
return { ...wallet, address: account.address };
|
|
48
|
+
}
|
|
49
|
+
async function generateX402PrivateKey() {
|
|
50
|
+
const { generatePrivateKey } = await import("viem/accounts");
|
|
51
|
+
return generatePrivateKey();
|
|
52
|
+
}
|
|
53
|
+
function invalidX402PrivateKey() {
|
|
54
|
+
return new DvmError(
|
|
55
|
+
"invalid_key",
|
|
56
|
+
"Invalid secp256k1 private key.",
|
|
57
|
+
"Reconnect with `dvm wallet x402-connect --key-file <path>`, set DVM_X402_KEY, or pipe a valid 0x-prefixed 32-byte secp256k1 private key through stdin."
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
async function getX402Balance(wallet) {
|
|
61
|
+
const w = await ensureAddress(wallet);
|
|
62
|
+
const spec = x402NetworkByCaip2(w.network);
|
|
63
|
+
if (!spec) {
|
|
64
|
+
throw new DvmError(
|
|
65
|
+
"x402_unsupported_network",
|
|
66
|
+
`The x402 wallet is configured for ${w.network}, a chain this rail can't settle on.`,
|
|
67
|
+
`${x402SupportedNetworksHint()} Re-pin the connected wallet without handling its key: 'dvm wallet x402-network ${X402_DEFAULT_NETWORK}'.`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const chains = await import("viem/chains");
|
|
71
|
+
const { createPublicClient, http, erc20Abi } = await import("viem");
|
|
72
|
+
const chain = chains[spec.viemChain];
|
|
73
|
+
const { url: rpcUrl, source: rpcSource } = resolveRpcOverride(
|
|
74
|
+
process.env.DVM_X402_RPC_URL,
|
|
75
|
+
chain?.rpcUrls.default.http[0]
|
|
76
|
+
);
|
|
77
|
+
try {
|
|
78
|
+
const transportOptions = resolveRpcHttpTransportOptions(
|
|
79
|
+
rpcSource,
|
|
80
|
+
process.env.DVM_X402_RPC_HEADERS_JSON
|
|
81
|
+
);
|
|
82
|
+
const client = createPublicClient({
|
|
83
|
+
chain,
|
|
84
|
+
transport: transportOptions ? http(rpcUrl, transportOptions) : http(rpcUrl)
|
|
85
|
+
});
|
|
86
|
+
const balance = await client.readContract({
|
|
87
|
+
address: spec.usdc,
|
|
88
|
+
abi: erc20Abi,
|
|
89
|
+
functionName: "balanceOf",
|
|
90
|
+
args: [w.address]
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
address: w.address,
|
|
94
|
+
usdc: Number(balance) / 1e6,
|
|
95
|
+
network: w.network,
|
|
96
|
+
tokenAddress: spec.usdc,
|
|
97
|
+
// redacted here rather than at a display surface, so the clear
|
|
98
|
+
// endpoint never leaves this function on the success path either.
|
|
99
|
+
rpcUrlRedacted: rpcUrl ? redactUrl(rpcUrl) : void 0,
|
|
100
|
+
rpcSource
|
|
101
|
+
};
|
|
102
|
+
} catch (err) {
|
|
103
|
+
const cause = redactUrlsInText(err instanceof Error ? err.message : String(err));
|
|
104
|
+
throw new DvmError(
|
|
105
|
+
"x402_rpc_error",
|
|
106
|
+
`x402 USDC balance lookup on ${spec.label} failed: ${cause}`,
|
|
107
|
+
// A caller who set the override doesn't need to be told to set it. Which
|
|
108
|
+
// knob is theirs to turn depends on whose endpoint this was.
|
|
109
|
+
rpcSource === "override" ? `DVM_X402_RPC_URL sent this read to ${redactUrl(rpcUrl)}. Correct it, or unset it to fall back to ${spec.label}'s bundled endpoint.` : `Verify connectivity to ${spec.label}'s bundled endpoint${rpcUrl ? ` (${redactUrl(rpcUrl)})` : ""}, or send the read somewhere else with DVM_X402_RPC_URL.`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export {
|
|
115
|
+
resolveX402Asset,
|
|
116
|
+
isValidEvmPrivateKey,
|
|
117
|
+
ensureAddress,
|
|
118
|
+
generateX402PrivateKey,
|
|
119
|
+
getX402Balance
|
|
120
|
+
};
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
} from "./chunk-AFV77S4C.js";
|
|
6
6
|
import {
|
|
7
7
|
loggers
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AQ7OX5NX.js";
|
|
9
9
|
import {
|
|
10
10
|
redactUrl
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-KXWROQGK.js";
|
|
12
12
|
|
|
13
13
|
// src/sdk/server/job-store.ts
|
|
14
14
|
function accumulateAskedTopUp(prior, ask) {
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
parseStoreValue,
|
|
3
3
|
stringifyStoreValue
|
|
4
4
|
} from "./chunk-YG7G4DPZ.js";
|
|
5
|
+
import {
|
|
6
|
+
diagnosticConsole
|
|
7
|
+
} from "./chunk-LAKP6FUI.js";
|
|
5
8
|
import {
|
|
6
9
|
withSdkInitLock
|
|
7
10
|
} from "./chunk-COYKJRMM.js";
|
|
8
|
-
import {
|
|
9
|
-
diagnosticConsole
|
|
10
|
-
} from "./chunk-ETXDTUJO.js";
|
|
11
11
|
|
|
12
12
|
// src/sdk/server/tempo-charge-store.ts
|
|
13
13
|
import { Credential } from "mppx";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
withSdkInitLock
|
|
3
|
-
} from "./chunk-COYKJRMM.js";
|
|
4
1
|
import {
|
|
5
2
|
applyRetryToPool
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TRNMTTPX.js";
|
|
7
4
|
import {
|
|
8
5
|
x402NetworkByCaip2
|
|
9
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BPYMEMQX.js";
|
|
10
7
|
import {
|
|
11
8
|
diagnosticConsole
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LAKP6FUI.js";
|
|
10
|
+
import {
|
|
11
|
+
withSdkInitLock
|
|
12
|
+
} from "./chunk-COYKJRMM.js";
|
|
13
13
|
|
|
14
14
|
// src/sdk/server/credit-ledger.ts
|
|
15
15
|
import { randomUUID } from "crypto";
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
canonicaliseForSigning
|
|
3
|
-
} from "./chunk-OFVV37XC.js";
|
|
4
|
-
|
|
5
1
|
// src/sdk/types.ts
|
|
6
2
|
function isZodSchema(value) {
|
|
7
3
|
return typeof value === "object" && value !== null && "_zod" in value && "parse" in value && "safeParse" in value;
|
|
@@ -16,6 +12,58 @@ var DEFAULT_CREDIT_MAX = "$5.00";
|
|
|
16
12
|
var DEFAULT_CREDIT_TTL_SECONDS = 30 * 24 * 60 * 60;
|
|
17
13
|
var DEFAULT_JOB_RETENTION_DAYS = 730;
|
|
18
14
|
|
|
15
|
+
// src/lib/cast-auth/canonical-json.ts
|
|
16
|
+
function canonicalize(value) {
|
|
17
|
+
return JSON.stringify(sortDeep(value));
|
|
18
|
+
}
|
|
19
|
+
function canonicaliseForSigning(value) {
|
|
20
|
+
return new TextEncoder().encode(canonicalize(value));
|
|
21
|
+
}
|
|
22
|
+
function sortDeep(value) {
|
|
23
|
+
if (value === null) return null;
|
|
24
|
+
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
25
|
+
if (typeof value === "number") {
|
|
26
|
+
if (!Number.isFinite(value)) {
|
|
27
|
+
throw new TypeError(`canonicalize: non-finite number is not JSON-serialisable`);
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
if (Array.isArray(value)) return value.map(sortDeep);
|
|
32
|
+
if (typeof value === "object") {
|
|
33
|
+
const sorted = {};
|
|
34
|
+
for (const key of Object.keys(value).sort()) {
|
|
35
|
+
const v = value[key];
|
|
36
|
+
if (v === void 0) continue;
|
|
37
|
+
sorted[key] = sortDeep(v);
|
|
38
|
+
}
|
|
39
|
+
return sorted;
|
|
40
|
+
}
|
|
41
|
+
throw new TypeError(`canonicalize: unsupported value of type ${typeof value}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/lib/cast-auth/verify.ts
|
|
45
|
+
import { schnorr } from "@noble/curves/secp256k1.js";
|
|
46
|
+
function verifyCanonicalSignedRequest(payload, signatureHex, pubkeyHex) {
|
|
47
|
+
if (!/^[0-9a-f]{64}$/i.test(pubkeyHex) || !/^[0-9a-f]{128}$/i.test(signatureHex)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const data = canonicaliseForSigning(payload);
|
|
51
|
+
const signature = hexToBytes(signatureHex);
|
|
52
|
+
const pubkey = hexToBytes(pubkeyHex);
|
|
53
|
+
try {
|
|
54
|
+
return schnorr.verify(signature, data, pubkey);
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function hexToBytes(hex) {
|
|
60
|
+
const out = new Uint8Array(hex.length / 2);
|
|
61
|
+
for (let i = 0; i < out.length; i++) {
|
|
62
|
+
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
19
67
|
// src/lib/signed-request-statement.ts
|
|
20
68
|
var SIGNED_REQUEST_AUTH_ID = "secp256k1-schnorr-v2";
|
|
21
69
|
var SIGNED_REQUEST_STATEMENT_VERSION = 2;
|
|
@@ -81,6 +129,9 @@ export {
|
|
|
81
129
|
DEFAULT_CREDIT_MAX,
|
|
82
130
|
DEFAULT_CREDIT_TTL_SECONDS,
|
|
83
131
|
DEFAULT_JOB_RETENTION_DAYS,
|
|
132
|
+
canonicalize,
|
|
133
|
+
canonicaliseForSigning,
|
|
134
|
+
verifyCanonicalSignedRequest,
|
|
84
135
|
SIGNED_REQUEST_AUTH_ID,
|
|
85
136
|
SIGNED_REQUEST_STATEMENT_VERSION,
|
|
86
137
|
signedRequestStatementHeader,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateCurrency
|
|
3
|
+
} from "./chunk-CLIAFTUR.js";
|
|
4
|
+
|
|
5
|
+
// src/sdk/pricing/upfront.ts
|
|
6
|
+
function buildUpfront(input) {
|
|
7
|
+
const currency = validateCurrency(input.currency);
|
|
8
|
+
const amount = input.amount;
|
|
9
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
10
|
+
throw new Error(`invalid upfront amount: ${String(amount)} (must be a non-negative number)`);
|
|
11
|
+
}
|
|
12
|
+
return { amount, currency };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
buildUpfront
|
|
17
|
+
};
|