@dvmkit/sdk 0.1.4-rc.7 → 0.1.5-rc.8
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 +10 -2
- package/dist/{chunk-ANFX5HEG.js → chunk-2UUXIIOC.js} +43 -13
- package/dist/{chunk-C6JHBLMW.js → chunk-BIP6G74V.js} +1 -1
- package/dist/{chunk-EDDYHZ6W.js → chunk-CEOAHV2I.js} +0 -30
- package/dist/{chunk-TSWKITGR.js → chunk-CGKZDODG.js} +8 -1
- package/dist/{chunk-DBCLBYHP.js → chunk-KVEHHC7W.js} +11 -1
- package/dist/{chunk-VRQDX5P4.js → chunk-KXCKFIJI.js} +30 -0
- package/dist/{chunk-5GFED3GJ.js → chunk-M7LHFJ5K.js} +49 -6
- package/dist/{chunk-7AKBC4PW.js → chunk-TQWGQCNV.js} +1 -1
- package/dist/{chunk-QK3VJNCK.js → chunk-UB5FZ43T.js} +339 -212
- package/dist/{credit-menu-C1ezIFlJ.d.ts → credit-menu-s5HmGCqx.d.ts} +64 -21
- package/dist/{fx-C6dl2LVI.d.ts → fx-D860pZvP.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/internal/caller.d.ts +31 -11
- package/dist/internal/caller.js +23 -11
- package/dist/internal/index.js +1 -1
- package/dist/internal/server.d.ts +8 -8
- package/dist/internal/server.js +4 -4
- package/dist/{job-store-DHnW4Cg_.d.ts → job-store-BUGqvCfL.d.ts} +1 -1
- package/dist/{lightning-backend-Ci1nogk_.d.ts → lightning-backend-BozcevPZ.d.ts} +1 -1
- package/dist/{memory-credit-ledger-OP24Z2KO.js → memory-credit-ledger-MNUOTQO5.js} +1 -1
- package/dist/{mpp-setup-MOBWGTWJ.js → mpp-setup-4FJD6ZHV.js} +11 -1
- package/dist/server/index.d.ts +12 -13
- package/dist/server/index.js +215 -51
- package/dist/{step-cache-BLPZNizw.d.ts → step-cache-5dljDqrQ.d.ts} +4 -2
- package/dist/{tempo-lifecycle-SQL3KLEZ.js → tempo-lifecycle-DFIXQ54Q.js} +3 -3
- package/dist/{tempo-wallet-QOLEIPCV.js → tempo-wallet-4QKSV65O.js} +10 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/{usd-BgOfZlk6.d.ts → usd-DoRuAckA.d.ts} +1 -1
- package/dist/{x402-T2C5MX3T.js → x402-5H27DCBE.js} +2 -2
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -18,15 +18,15 @@ import {
|
|
|
18
18
|
NwcBackend,
|
|
19
19
|
NwcError,
|
|
20
20
|
SpanWriter,
|
|
21
|
-
isTestMintUrl,
|
|
22
21
|
parseNwcUri,
|
|
23
22
|
validateX402Env,
|
|
24
23
|
withNwcPool
|
|
25
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-CEOAHV2I.js";
|
|
26
25
|
import {
|
|
27
26
|
MemoryKVStore
|
|
28
27
|
} from "../chunk-RW5LP57K.js";
|
|
29
28
|
import {
|
|
29
|
+
AccumulatorReplayError,
|
|
30
30
|
CLIENT_COMPATIBILITY_HEADERS,
|
|
31
31
|
CREDIT_ENVELOPE_KEYS,
|
|
32
32
|
CREDIT_REQUEST_SCHEMA,
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
createPlatformTempoObserverHealth,
|
|
57
57
|
createX402BatchSettlementServer,
|
|
58
58
|
creditEnvelopeIgnoreFields,
|
|
59
|
+
devModeSkipsPaymentVerification,
|
|
59
60
|
drawSettlementRef,
|
|
60
61
|
extractCreditEnvelope,
|
|
61
62
|
fundingCommitment,
|
|
@@ -77,7 +78,7 @@ import {
|
|
|
77
78
|
stripProtocolEnvelope,
|
|
78
79
|
toCreditView,
|
|
79
80
|
unknownRouteNotFound
|
|
80
|
-
} from "../chunk-
|
|
81
|
+
} from "../chunk-UB5FZ43T.js";
|
|
81
82
|
import {
|
|
82
83
|
MemoryProcessedPaymentStore,
|
|
83
84
|
PostgresProcessedPaymentStore,
|
|
@@ -86,7 +87,7 @@ import {
|
|
|
86
87
|
import "../chunk-BQ2NMWKE.js";
|
|
87
88
|
import {
|
|
88
89
|
MemoryCreditLedger
|
|
89
|
-
} from "../chunk-
|
|
90
|
+
} from "../chunk-KVEHHC7W.js";
|
|
90
91
|
import {
|
|
91
92
|
SignedRequestError,
|
|
92
93
|
createDefaultReplayStore,
|
|
@@ -98,8 +99,9 @@ import {
|
|
|
98
99
|
} from "../chunk-U6M3ATSG.js";
|
|
99
100
|
import {
|
|
100
101
|
generateEphemeralReceiptKey,
|
|
102
|
+
isTestMintUrl,
|
|
101
103
|
receiptPubkeyFromSecret
|
|
102
|
-
} from "../chunk-
|
|
104
|
+
} from "../chunk-KXCKFIJI.js";
|
|
103
105
|
import {
|
|
104
106
|
X402_DEFAULT_FACILITATOR,
|
|
105
107
|
X402_DEFAULT_NETWORK,
|
|
@@ -140,10 +142,12 @@ import {
|
|
|
140
142
|
applyRetryToPool
|
|
141
143
|
} from "../chunk-C3MTFLC6.js";
|
|
142
144
|
import {
|
|
145
|
+
TEMPO_MODERATO_CHAIN_ID,
|
|
146
|
+
TEMPO_MODERATO_RPC,
|
|
143
147
|
TEMPO_SETTLEMENT_DEFAULT_LOW_BALANCE_MICRO,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
} from "../chunk-
|
|
148
|
+
TempoSettlementReadiness,
|
|
149
|
+
resolveTempoNetwork
|
|
150
|
+
} from "../chunk-M7LHFJ5K.js";
|
|
147
151
|
|
|
148
152
|
// src/sdk/server/cashu-env.ts
|
|
149
153
|
async function resolveCashuOptsFromEnv(env, pool, cashuModeHint) {
|
|
@@ -223,6 +227,69 @@ async function resolveCashuOptsFromEnv(env, pool, cashuModeHint) {
|
|
|
223
227
|
return { cashuMode, lockPubkey, lockPubkeyGraceSeconds, db, dvmId, canonicalDvmId };
|
|
224
228
|
}
|
|
225
229
|
|
|
230
|
+
// src/sdk/server/payment-mode.ts
|
|
231
|
+
function resolvePaymentMode(opts) {
|
|
232
|
+
const active = (rail, configured, ready) => ({
|
|
233
|
+
status: !configured && !opts.paymentMethods?.includes(rail) ? "absent" : ready && (!opts.paymentMethods || opts.paymentMethods.includes(rail)) ? "verifying" : "unavailable",
|
|
234
|
+
testFunds: rail === "cashu" ? opts.mints?.length ? opts.mints.every(isTestMintUrl) : null : rail === "x402" ? opts.x402 ? ["base-sepolia", "eip155:84532"].includes(opts.x402.network) : null : opts.mpp?.tempoConfiguration ? opts.mpp.tempoConfiguration.chainId === TEMPO_MODERATO_CHAIN_ID : null
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
mount: opts.mount,
|
|
238
|
+
verification: devModeSkipsPaymentVerification(opts) ? "skipped" : "required",
|
|
239
|
+
storage: opts.durable ? "durable" : "disposable",
|
|
240
|
+
rails: {
|
|
241
|
+
cashu: active("cashu", opts.mints !== void 0, opts.cashuReady),
|
|
242
|
+
x402: active("x402", !!opts.x402, !!opts.x402 && opts.x402Available),
|
|
243
|
+
tempo: active("tempo", !!opts.mpp, !!opts.mpp?.methods.some((method) => method.name === "tempo"))
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/sdk/server/host.ts
|
|
249
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
250
|
+
|
|
251
|
+
// src/sdk/server/disposable-cashu-store.ts
|
|
252
|
+
function createDisposableCashuStore() {
|
|
253
|
+
let current = new MemoryCreditLedger();
|
|
254
|
+
let tail = Promise.resolve();
|
|
255
|
+
const requests = /* @__PURE__ */ new Set();
|
|
256
|
+
const secrets = /* @__PURE__ */ new Set();
|
|
257
|
+
function exclusive(operation) {
|
|
258
|
+
const result = tail.then(operation);
|
|
259
|
+
tail = result.then(() => void 0, () => void 0);
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
const ledger = new Proxy(current, {
|
|
263
|
+
get(_target, key) {
|
|
264
|
+
const member = Reflect.get(current, key);
|
|
265
|
+
if (typeof member !== "function") return member;
|
|
266
|
+
if (key === "useX402SettlementGate") return member.bind(current);
|
|
267
|
+
return (...args) => exclusive(async () => {
|
|
268
|
+
const method = Reflect.get(current, key);
|
|
269
|
+
return await method.apply(current, args);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
return {
|
|
274
|
+
ledger,
|
|
275
|
+
accumulator: {
|
|
276
|
+
commit(requestId, proofs, account) {
|
|
277
|
+
return exclusive(async () => {
|
|
278
|
+
const incoming = proofs.map((proof) => proof.secret);
|
|
279
|
+
if (requests.has(requestId) || new Set(incoming).size !== incoming.length || incoming.some((secret) => secrets.has(secret))) {
|
|
280
|
+
throw new AccumulatorReplayError("disposable", requestId);
|
|
281
|
+
}
|
|
282
|
+
const staged = current.forkForTransaction();
|
|
283
|
+
await account(staged);
|
|
284
|
+
current = staged;
|
|
285
|
+
requests.add(requestId);
|
|
286
|
+
for (const secret of incoming) secrets.add(secret);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
226
293
|
// src/sdk/server/host.ts
|
|
227
294
|
import { serve as honoServe } from "@hono/node-server";
|
|
228
295
|
import { Hono } from "hono";
|
|
@@ -1079,6 +1146,7 @@ function createDVMHost(opts = {}) {
|
|
|
1079
1146
|
app.use("*", clientCompatibilityMiddleware());
|
|
1080
1147
|
const routeClientCompatibility = opts.wrapRouteClientCompatibility?.(requireClientCompatibility) ?? requireClientCompatibility;
|
|
1081
1148
|
const mounts = [];
|
|
1149
|
+
const paymentModes = [];
|
|
1082
1150
|
const ownsPool = !opts.pool;
|
|
1083
1151
|
let pgPool;
|
|
1084
1152
|
let creditLedger;
|
|
@@ -1091,10 +1159,12 @@ function createDVMHost(opts = {}) {
|
|
|
1091
1159
|
let pgStreamStore;
|
|
1092
1160
|
let nodeServer;
|
|
1093
1161
|
let spanWriter;
|
|
1162
|
+
let shutdownPromise;
|
|
1163
|
+
let serveAttempted = false;
|
|
1094
1164
|
function mount(descriptor, mountOpts) {
|
|
1095
|
-
mounts.push({ descriptor, prefix: mountOpts?.prefix });
|
|
1165
|
+
mounts.push({ descriptor, prefix: mountOpts?.prefix, bootCompleted: false });
|
|
1096
1166
|
}
|
|
1097
|
-
async function
|
|
1167
|
+
async function boot(serveOpts) {
|
|
1098
1168
|
const env = opts.env ?? Object.fromEntries(
|
|
1099
1169
|
Object.entries(process.env).filter(
|
|
1100
1170
|
(entry) => entry[1] !== void 0
|
|
@@ -1143,11 +1213,25 @@ function createDVMHost(opts = {}) {
|
|
|
1143
1213
|
kvBackend = "postgres";
|
|
1144
1214
|
}
|
|
1145
1215
|
}
|
|
1146
|
-
const cashuOpts = await resolveCashuOptsFromEnv(env, pgPool, opts.cashuMode);
|
|
1147
1216
|
const mintsFromEnv = envMaybe.DVMKIT_CASHU_MINTS?.split(",").map((m) => m.trim()).filter(Boolean);
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1217
|
+
const effectiveMints = opts.mints ?? mintsFromEnv;
|
|
1218
|
+
const disposableCashu = opts.devMode && !pgPool && (effectiveMints?.length ?? 0) > 0 ? createDisposableCashuStore() : void 0;
|
|
1219
|
+
if (disposableCashu && !effectiveMints.every(isTestMintUrl)) {
|
|
1220
|
+
throw new Error("Disposable development Cashu accepts only known test or loopback mints. Real or unknown mints require durable PostgreSQL storage.");
|
|
1221
|
+
}
|
|
1222
|
+
if (disposableCashu && opts.cashuMode === void 0) {
|
|
1223
|
+
console.log(JSON.stringify({ level: "info", message: "Cashu mode: p2pk-accumulator (default)" }));
|
|
1224
|
+
}
|
|
1225
|
+
const cashuOpts = disposableCashu ? {
|
|
1226
|
+
cashuMode: "p2pk-accumulator",
|
|
1227
|
+
lockPubkey: `02${generateEphemeralReceiptKey().pubkey}`,
|
|
1228
|
+
lockPubkeyGraceSeconds: 0,
|
|
1229
|
+
dvmId: randomUUID2(),
|
|
1230
|
+
canonicalDvmId: void 0,
|
|
1231
|
+
db: void 0
|
|
1232
|
+
} : await resolveCashuOptsFromEnv(env, pgPool, opts.cashuMode);
|
|
1233
|
+
if (envMaybe.BUILDER_LOCK_PRIVKEY) {
|
|
1234
|
+
throw new Error("BUILDER_LOCK_PRIVKEY must not be set on a DVM machine.");
|
|
1151
1235
|
}
|
|
1152
1236
|
if (!opts.devMode && effectiveMints && effectiveMints.length > 0 && envMaybe.DVMKIT_PLATFORM_URL) {
|
|
1153
1237
|
const testMints = effectiveMints.filter(isTestMintUrl);
|
|
@@ -1207,7 +1291,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1207
1291
|
let tempoChargeBackend = "user-supplied";
|
|
1208
1292
|
const mppTempoRecipient = envMaybe.DVMKIT_TEMPO_RECIPIENT;
|
|
1209
1293
|
if (!mpp && mppTempoRecipient) {
|
|
1210
|
-
const { createMppFromOpts, createDualKeyMppxFromOpts, parseMppMethodsAllowlist } = await import("../mpp-setup-
|
|
1294
|
+
const { createMppFromOpts, createDualKeyMppxFromOpts, parseMppMethodsAllowlist } = await import("../mpp-setup-4FJD6ZHV.js");
|
|
1211
1295
|
tempoChargeBackend = pgPool ? "postgres" : "memory";
|
|
1212
1296
|
let tempoCharge;
|
|
1213
1297
|
if (pgPool) {
|
|
@@ -1240,11 +1324,14 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1240
1324
|
tempoPayoutReader.listActive = (limit, cursor) => sessionStore.listActive(limit, cursor);
|
|
1241
1325
|
pendingInits.push(sessionStore.init());
|
|
1242
1326
|
const operator = privateKeyToAccount2(tempoOperatorKey);
|
|
1243
|
-
const
|
|
1244
|
-
const
|
|
1327
|
+
const tempoNetwork = resolveTempoNetwork(envMaybe);
|
|
1328
|
+
const tempoCurrency = tempoNetwork.currency;
|
|
1329
|
+
const selectedChain = tempoNetwork.chainId === tempoModerato.id ? tempoModerato : tempoNetwork.chainId === tempoMainnet.id ? tempoMainnet : { ...tempoNetwork.testnet ? tempoModerato : tempoMainnet, id: tempoNetwork.chainId };
|
|
1330
|
+
const bundledRpc = tempoNetwork.chainId === TEMPO_MODERATO_CHAIN_ID ? TEMPO_MODERATO_RPC : selectedChain.rpcUrls.default.http[0];
|
|
1331
|
+
const tempoRpc = resolveRpcOverride(envMaybe.DVMKIT_TEMPO_RPC_URL, bundledRpc).url;
|
|
1245
1332
|
const publicClient = createPublicClient({
|
|
1246
|
-
chain:
|
|
1247
|
-
transport: http(
|
|
1333
|
+
chain: selectedChain,
|
|
1334
|
+
transport: http(tempoRpc)
|
|
1248
1335
|
});
|
|
1249
1336
|
if (envMaybe.DVMKIT_PLATFORM_URL) {
|
|
1250
1337
|
if (!cashuOpts.dvmId) {
|
|
@@ -1258,7 +1345,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1258
1345
|
pendingInits.push(readinessStore.init());
|
|
1259
1346
|
tempoSettlementReadiness = new TempoSettlementReadiness({
|
|
1260
1347
|
address: operator.address,
|
|
1261
|
-
network: `eip155:${
|
|
1348
|
+
network: `eip155:${tempoNetwork.chainId}`,
|
|
1262
1349
|
token: tempoCurrency,
|
|
1263
1350
|
lowBalanceMicro: parseTempoSettlementFloor(envMaybe),
|
|
1264
1351
|
stateStore: readinessStore,
|
|
@@ -1273,15 +1360,20 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1273
1360
|
tempoSession = {
|
|
1274
1361
|
store: sessionStore,
|
|
1275
1362
|
account: operator,
|
|
1363
|
+
chainId: tempoNetwork.chainId,
|
|
1276
1364
|
getClient: ({ chainId }) => {
|
|
1277
|
-
|
|
1365
|
+
if (chainId !== void 0 && chainId !== tempoNetwork.chainId) {
|
|
1366
|
+
throw new Error(
|
|
1367
|
+
`Tempo session requested chain ${chainId}, but the host is configured for chain ${tempoNetwork.chainId}.`
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1278
1370
|
return createWalletClient({
|
|
1279
1371
|
account: operator,
|
|
1280
|
-
chain,
|
|
1372
|
+
chain: selectedChain,
|
|
1281
1373
|
// Trimmed, so a blank DVMKIT_TEMPO_RPC_URL falls back to the
|
|
1282
1374
|
// chain's bundled endpoint rather than becoming the transport
|
|
1283
1375
|
// target (internal-review).
|
|
1284
|
-
transport: http(
|
|
1376
|
+
transport: http(tempoRpc)
|
|
1285
1377
|
});
|
|
1286
1378
|
},
|
|
1287
1379
|
settlementSchedule: { intervalMs: 24 * 60 * 60 * 1e3 },
|
|
@@ -1406,8 +1498,8 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1406
1498
|
pendingInits.push(pgProcessed.init());
|
|
1407
1499
|
processedPayments = pgProcessed;
|
|
1408
1500
|
} else {
|
|
1409
|
-
const { MemoryCreditLedger: MemoryCreditLedger2 } = await import("../memory-credit-ledger-
|
|
1410
|
-
creditLedger = new MemoryCreditLedger2();
|
|
1501
|
+
const { MemoryCreditLedger: MemoryCreditLedger2 } = await import("../memory-credit-ledger-MNUOTQO5.js");
|
|
1502
|
+
creditLedger = disposableCashu?.ledger ?? new MemoryCreditLedger2();
|
|
1411
1503
|
const { MemoryProcessedPaymentStore: MemoryProcessedPaymentStore2 } = await import("../processed-payment-store-HAA4SFNK.js");
|
|
1412
1504
|
processedPayments = new MemoryProcessedPaymentStore2();
|
|
1413
1505
|
}
|
|
@@ -1477,6 +1569,33 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1477
1569
|
const descX402Support = descX402Health?.support();
|
|
1478
1570
|
if (!bootX402Support && descX402Support) bootX402Support = descX402Support;
|
|
1479
1571
|
const descMpp = descriptor.mpp ?? mpp;
|
|
1572
|
+
const x402Settleable = isConfiguredX402Settleable(
|
|
1573
|
+
descX402Support,
|
|
1574
|
+
descX402WithDualServe
|
|
1575
|
+
);
|
|
1576
|
+
if (descX402Support && !x402Settleable) {
|
|
1577
|
+
const message = `x402 network ${descX402Support.network} has no settleable kind at facilitator ${descX402Support.facilitator}. Use eip155:84532 (Base Sepolia) with x402.org for test funds, or a facilitator supporting your configured mainnet. No network was changed.`;
|
|
1578
|
+
if (failFast) throw new Error(message);
|
|
1579
|
+
console.warn(JSON.stringify({ level: "warn", event: "x402_network_unsupported", message }));
|
|
1580
|
+
}
|
|
1581
|
+
const paymentMode = resolvePaymentMode({
|
|
1582
|
+
mount: descriptor.name,
|
|
1583
|
+
devMode: opts.devMode,
|
|
1584
|
+
mints: effectiveMints,
|
|
1585
|
+
x402: descX402WithDualServe,
|
|
1586
|
+
mpp: descMpp,
|
|
1587
|
+
paymentMethods: opts.paymentMethods ?? descriptor.paymentMethods,
|
|
1588
|
+
cashuReady: !!cashuOpts.lockPubkey && !!(cashuOpts.db || disposableCashu) && !!effectiveMints?.length,
|
|
1589
|
+
x402Available: x402Settleable,
|
|
1590
|
+
durable: !!pgPool
|
|
1591
|
+
});
|
|
1592
|
+
paymentModes.push(paymentMode);
|
|
1593
|
+
console.log(JSON.stringify({
|
|
1594
|
+
level: "info",
|
|
1595
|
+
event: "payment_mode",
|
|
1596
|
+
...paymentMode,
|
|
1597
|
+
...disposableCashu ? { message: "Test funds only. Proofs, balances and jobs are lost on shutdown; the next boot uses a fresh Cashu lock identity." } : {}
|
|
1598
|
+
}));
|
|
1480
1599
|
const {
|
|
1481
1600
|
app: subApp,
|
|
1482
1601
|
shutdown,
|
|
@@ -1488,6 +1607,8 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1488
1607
|
mints: effectiveMints,
|
|
1489
1608
|
jobStore,
|
|
1490
1609
|
devMode: opts.devMode,
|
|
1610
|
+
onPaidJobCompleted: opts.onPaidJobCompleted,
|
|
1611
|
+
paymentMode,
|
|
1491
1612
|
paymentMethods: opts.paymentMethods ?? descriptor.paymentMethods,
|
|
1492
1613
|
x402: descX402WithDualServe,
|
|
1493
1614
|
x402FacilitatorHealth: descX402Health,
|
|
@@ -1495,6 +1616,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1495
1616
|
consumedCredentialStore: opts.consumedCredentialStore ?? sharedPgConsumedStore,
|
|
1496
1617
|
adminCashuNonceStore: sharedPgConsumedStore,
|
|
1497
1618
|
cashuMode: cashuOpts.cashuMode,
|
|
1619
|
+
disposableCashu: disposableCashu?.accumulator,
|
|
1498
1620
|
lockPubkey: cashuOpts.lockPubkey,
|
|
1499
1621
|
lockPubkeyGraceSeconds: cashuOpts.lockPubkeyGraceSeconds,
|
|
1500
1622
|
canonicalDvmId: cashuOpts.canonicalDvmId,
|
|
@@ -1546,6 +1668,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1546
1668
|
if (entry.descriptor.config.onBoot) {
|
|
1547
1669
|
await entry.descriptor.config.onBoot(env);
|
|
1548
1670
|
}
|
|
1671
|
+
entry.bootCompleted = true;
|
|
1549
1672
|
}
|
|
1550
1673
|
mark("onboot");
|
|
1551
1674
|
logBootSummary({
|
|
@@ -1593,21 +1716,63 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1593
1716
|
console.log(`DVM host running at ${url}`);
|
|
1594
1717
|
resolvePromise({
|
|
1595
1718
|
url,
|
|
1596
|
-
|
|
1597
|
-
|
|
1719
|
+
paymentModes,
|
|
1720
|
+
close() {
|
|
1721
|
+
return shutdownInternal();
|
|
1598
1722
|
}
|
|
1599
1723
|
});
|
|
1600
1724
|
});
|
|
1601
1725
|
});
|
|
1602
1726
|
}
|
|
1603
|
-
async function
|
|
1727
|
+
async function serveFn(serveOpts) {
|
|
1728
|
+
if (serveAttempted) {
|
|
1729
|
+
throw new Error("A DVM host can only serve once. Create a new host to retry after shutdown.");
|
|
1730
|
+
}
|
|
1731
|
+
serveAttempted = true;
|
|
1732
|
+
try {
|
|
1733
|
+
return await boot(serveOpts);
|
|
1734
|
+
} catch (bootError) {
|
|
1735
|
+
await shutdownInternal().catch(() => void 0);
|
|
1736
|
+
throw bootError;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
function shutdownInternal() {
|
|
1740
|
+
return shutdownPromise ??= performShutdown();
|
|
1741
|
+
}
|
|
1742
|
+
async function performShutdown() {
|
|
1743
|
+
const errors = [];
|
|
1744
|
+
const capture = async (operation) => {
|
|
1745
|
+
try {
|
|
1746
|
+
await operation();
|
|
1747
|
+
} catch (error) {
|
|
1748
|
+
errors.push(error);
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1751
|
+
if (nodeServer) {
|
|
1752
|
+
const server = nodeServer;
|
|
1753
|
+
await capture(
|
|
1754
|
+
() => new Promise((resolve) => {
|
|
1755
|
+
const idleSweep = setInterval(() => {
|
|
1756
|
+
server.closeIdleConnections();
|
|
1757
|
+
}, IDLE_CONNECTION_SWEEP_MS);
|
|
1758
|
+
idleSweep.unref();
|
|
1759
|
+
server.close(() => {
|
|
1760
|
+
clearInterval(idleSweep);
|
|
1761
|
+
resolve();
|
|
1762
|
+
});
|
|
1763
|
+
server.closeIdleConnections();
|
|
1764
|
+
})
|
|
1765
|
+
);
|
|
1766
|
+
nodeServer = void 0;
|
|
1767
|
+
}
|
|
1604
1768
|
if (spanWriter) {
|
|
1605
|
-
|
|
1769
|
+
const writer = spanWriter;
|
|
1606
1770
|
spanWriter = void 0;
|
|
1771
|
+
await capture(() => writer.shutdown());
|
|
1607
1772
|
}
|
|
1608
1773
|
for (let i = mounts.length - 1; i >= 0; i--) {
|
|
1609
1774
|
const entry = mounts[i];
|
|
1610
|
-
if (entry.descriptor.config.onShutdown) {
|
|
1775
|
+
if (entry.bootCompleted && entry.descriptor.config.onShutdown) {
|
|
1611
1776
|
try {
|
|
1612
1777
|
await entry.descriptor.config.onShutdown();
|
|
1613
1778
|
} catch (err) {
|
|
@@ -1617,34 +1782,27 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1617
1782
|
);
|
|
1618
1783
|
}
|
|
1619
1784
|
}
|
|
1620
|
-
entry.shutdown?.();
|
|
1621
|
-
}
|
|
1622
|
-
if (nodeServer) {
|
|
1623
|
-
const server = nodeServer;
|
|
1624
|
-
await new Promise((resolve) => {
|
|
1625
|
-
const idleSweep = setInterval(() => {
|
|
1626
|
-
server.closeIdleConnections();
|
|
1627
|
-
}, IDLE_CONNECTION_SWEEP_MS);
|
|
1628
|
-
idleSweep.unref();
|
|
1629
|
-
server.close(() => {
|
|
1630
|
-
clearInterval(idleSweep);
|
|
1631
|
-
resolve();
|
|
1632
|
-
});
|
|
1633
|
-
server.closeIdleConnections();
|
|
1634
|
-
});
|
|
1635
|
-
nodeServer = void 0;
|
|
1785
|
+
await capture(() => entry.shutdown?.());
|
|
1636
1786
|
}
|
|
1637
1787
|
if (pgStreamStore && isStreamableJobStore(pgStreamStore)) {
|
|
1638
|
-
await pgStreamStore
|
|
1788
|
+
await capture(() => pgStreamStore?.shutdownStreaming());
|
|
1639
1789
|
}
|
|
1640
1790
|
if (pgPool && ownsPool) {
|
|
1641
|
-
|
|
1791
|
+
const ownedPool = pgPool;
|
|
1792
|
+
await capture(() => ownedPool.end());
|
|
1642
1793
|
}
|
|
1643
1794
|
pgPool = void 0;
|
|
1644
1795
|
creditLedger = void 0;
|
|
1645
1796
|
processedPayments = void 0;
|
|
1646
|
-
tempoSettlementReadiness
|
|
1647
|
-
|
|
1797
|
+
if (tempoSettlementReadiness) {
|
|
1798
|
+
const readiness = tempoSettlementReadiness;
|
|
1799
|
+
tempoSettlementReadiness = void 0;
|
|
1800
|
+
await capture(() => readiness.stop());
|
|
1801
|
+
}
|
|
1802
|
+
if (errors.length === 1) throw errors[0];
|
|
1803
|
+
if (errors.length > 1) {
|
|
1804
|
+
throw new AggregateError(errors, `${String(errors.length)} host shutdown operations failed`);
|
|
1805
|
+
}
|
|
1648
1806
|
}
|
|
1649
1807
|
return {
|
|
1650
1808
|
app,
|
|
@@ -1659,6 +1817,12 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
|
|
|
1659
1817
|
shutdown: shutdownInternal
|
|
1660
1818
|
};
|
|
1661
1819
|
}
|
|
1820
|
+
function isConfiguredX402Settleable(support, config) {
|
|
1821
|
+
if (!support || !config) return false;
|
|
1822
|
+
if (support.available) return true;
|
|
1823
|
+
const batch = config.batchSettlement;
|
|
1824
|
+
return !!batch && (support.batchSettlement || !!batch.selfRelay);
|
|
1825
|
+
}
|
|
1662
1826
|
function mountNeedsFx(entry, hostRailConfigured) {
|
|
1663
1827
|
const descriptor = entry.descriptor;
|
|
1664
1828
|
if (descriptor.credit || descriptor.price) return true;
|
|
@@ -1837,7 +2001,7 @@ function logBootSummary(s) {
|
|
|
1837
2001
|
console.log(` Tempo secret: ${rotState}`);
|
|
1838
2002
|
}
|
|
1839
2003
|
console.log(
|
|
1840
|
-
` x402: ${s.x402 ? `${s.x402.network} \u2192 ${s.x402.payTo}${s.x402Support?.available === false ? " (
|
|
2004
|
+
` x402: ${s.x402 ? `${s.x402.network} \u2192 ${s.x402.payTo}${s.x402Support?.available === false ? isConfiguredX402Settleable(s.x402Support, s.x402) ? " (exact unavailable \u2014 batch configured)" : " (no configured settleable path)" : ""}` : "(unconfigured)"}`
|
|
1841
2005
|
);
|
|
1842
2006
|
console.log(
|
|
1843
2007
|
` LN receive: ${s.lightningReceive ? `receive-only NWC (${s.lightningReceive.available() ? "reachable" : "unreachable \u2014 omitted from the funding menu"})` : "(unconfigured)"}`
|
|
@@ -4919,8 +4919,9 @@ declare class PostgresTempoSessionStore implements Store.AtomicStore {
|
|
|
4919
4919
|
interface MppOpts {
|
|
4920
4920
|
/**
|
|
4921
4921
|
* Tempo recipient (0x-prefixed 40-char hex address). When set, registers
|
|
4922
|
-
* `tempo/charge`.
|
|
4923
|
-
*
|
|
4922
|
+
* `tempo/charge`. Supported chains are Tempo mainnet (4217) and Moderato
|
|
4923
|
+
* (42431). Currency defaults per chain; override it with
|
|
4924
|
+
* `DVMKIT_TEMPO_CURRENCY`.
|
|
4924
4925
|
*/
|
|
4925
4926
|
tempoRecipient?: string;
|
|
4926
4927
|
/**
|
|
@@ -5008,6 +5009,7 @@ interface MppxServer {
|
|
|
5008
5009
|
tempoConfiguration?: {
|
|
5009
5010
|
recipient: string;
|
|
5010
5011
|
paymentToken: string;
|
|
5012
|
+
chainId: number;
|
|
5011
5013
|
operator?: string;
|
|
5012
5014
|
feeToken?: string;
|
|
5013
5015
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertTempoWalletIdle
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-TQWGQCNV.js";
|
|
4
|
+
import "./chunk-2UUXIIOC.js";
|
|
5
5
|
import "./chunk-KSQEFVFJ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-CGKZDODG.js";
|
|
7
7
|
import "./chunk-5URG56JJ.js";
|
|
8
8
|
import "./chunk-MKI6OVW4.js";
|
|
9
9
|
import "./chunk-FUJ36YDV.js";
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TEMPO_CHAIN_ID,
|
|
3
|
+
TEMPO_MODERATO_CHAIN_ID,
|
|
4
|
+
TEMPO_MODERATO_RPC,
|
|
5
|
+
TEMPO_PATH_USD_MODERATO,
|
|
3
6
|
TEMPO_USDC_MAINNET,
|
|
4
7
|
connectedTempoAccount,
|
|
5
8
|
deriveTempoAddress,
|
|
6
9
|
generateTempoKey,
|
|
7
10
|
getTempoUsdcBalance,
|
|
8
11
|
resolveTempoAsset,
|
|
12
|
+
resolveTempoNetwork,
|
|
9
13
|
tempoBalanceCheckHint,
|
|
10
14
|
tempoTokenLabel,
|
|
11
15
|
tempoTokenReference,
|
|
12
16
|
tempoWrongAssetHint,
|
|
13
17
|
tryResolveTempoAsset
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-2UUXIIOC.js";
|
|
19
|
+
import "./chunk-CGKZDODG.js";
|
|
16
20
|
import "./chunk-MKI6OVW4.js";
|
|
17
21
|
import "./chunk-FUJ36YDV.js";
|
|
18
22
|
export {
|
|
19
23
|
TEMPO_CHAIN_ID,
|
|
24
|
+
TEMPO_MODERATO_CHAIN_ID,
|
|
25
|
+
TEMPO_MODERATO_RPC,
|
|
26
|
+
TEMPO_PATH_USD_MODERATO,
|
|
20
27
|
TEMPO_USDC_MAINNET,
|
|
21
28
|
connectedTempoAccount,
|
|
22
29
|
deriveTempoAddress,
|
|
23
30
|
generateTempoKey,
|
|
24
31
|
getTempoUsdcBalance,
|
|
25
32
|
resolveTempoAsset,
|
|
33
|
+
resolveTempoNetwork,
|
|
26
34
|
tempoBalanceCheckHint,
|
|
27
35
|
tempoTokenLabel,
|
|
28
36
|
tempoTokenReference,
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Y as JobReceipt, a1 as Message, a2 as MessageType, K as KVStore, L as Logger, u as ResponseContent, P as PaymentContent, S as SDKJobContext } from '../step-cache-
|
|
2
|
-
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-
|
|
1
|
+
import { Y as JobReceipt, a1 as Message, a2 as MessageType, K as KVStore, L as Logger, u as ResponseContent, P as PaymentContent, S as SDKJobContext } from '../step-cache-5dljDqrQ.js';
|
|
2
|
+
import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-BUGqvCfL.js';
|
|
3
3
|
import 'hono';
|
|
4
4
|
import 'mppx';
|
|
5
5
|
import '@x402/core/server';
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
saveX402Wallet,
|
|
11
11
|
tryX402Payment,
|
|
12
12
|
x402WrongAssetHint
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BIP6G74V.js";
|
|
14
14
|
import "./chunk-KSQEFVFJ.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-CGKZDODG.js";
|
|
16
16
|
import {
|
|
17
17
|
verifyX402Payment
|
|
18
18
|
} from "./chunk-BIFLRKMO.js";
|