@vapi-network/core 0.8.0 → 0.9.0
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 +14 -1
- package/dist/agent-link.d.ts.map +1 -1
- package/dist/agent-link.js +6 -1
- package/dist/agent-link.js.map +1 -1
- package/dist/agent-profile.d.ts +4 -0
- package/dist/agent-profile.d.ts.map +1 -1
- package/dist/api-key.js +47 -0
- package/dist/api-key.js.map +1 -1
- package/dist/backup.d.ts +2 -0
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +65 -0
- package/dist/backup.js.map +1 -1
- package/dist/cloud-backup.js +71 -1
- package/dist/cloud-backup.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/docs.d.ts +40 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/funding-policy.d.ts +29 -0
- package/dist/funding-policy.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +718 -35
- package/dist/index.js.map +3 -3
- package/dist/router-client.js +230 -33
- package/dist/router-client.js.map +2 -2
- package/dist/secrets.js +29 -1
- package/dist/secrets.js.map +1 -1
- package/dist/spend-policy.d.ts +41 -7
- package/dist/spend-policy.d.ts.map +1 -1
- package/dist/support-report.d.ts +1 -1
- package/dist/tasks/actions.d.ts +152 -0
- package/dist/tasks/actions.d.ts.map +1 -0
- package/dist/tasks/canonical-json.d.ts +6 -0
- package/dist/tasks/canonical-json.d.ts.map +1 -0
- package/dist/tasks/chain-error.d.ts +6 -0
- package/dist/tasks/chain-error.d.ts.map +1 -0
- package/dist/tasks/chain-port.d.ts +88 -0
- package/dist/tasks/chain-port.d.ts.map +1 -0
- package/dist/tasks/chain-verification.d.ts +36 -0
- package/dist/tasks/chain-verification.d.ts.map +1 -0
- package/dist/tasks/chain.d.ts +22 -0
- package/dist/tasks/chain.d.ts.map +1 -0
- package/dist/tasks/client.d.ts +76 -0
- package/dist/tasks/client.d.ts.map +1 -0
- package/dist/tasks/delivery-manifest.d.ts +24 -0
- package/dist/tasks/delivery-manifest.d.ts.map +1 -0
- package/dist/tasks/dispute-fee.d.ts +4 -0
- package/dist/tasks/dispute-fee.d.ts.map +1 -0
- package/dist/tasks/index.d.ts +22 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/money.d.ts +17 -0
- package/dist/tasks/money.d.ts.map +1 -0
- package/dist/tasks/operation-support.d.ts +127 -0
- package/dist/tasks/operation-support.d.ts.map +1 -0
- package/dist/tasks/operations.d.ts +722 -0
- package/dist/tasks/operations.d.ts.map +1 -0
- package/dist/tasks/pending-transactions.d.ts +52 -0
- package/dist/tasks/pending-transactions.d.ts.map +1 -0
- package/dist/tasks/plan-guard.d.ts +326 -0
- package/dist/tasks/plan-guard.d.ts.map +1 -0
- package/dist/tasks/rpc.d.ts +8 -0
- package/dist/tasks/rpc.d.ts.map +1 -0
- package/dist/tasks/scope-bindings.d.ts +20 -0
- package/dist/tasks/scope-bindings.d.ts.map +1 -0
- package/dist/tasks/scope-terms.d.ts +75 -0
- package/dist/tasks/scope-terms.d.ts.map +1 -0
- package/dist/tasks/trusted-deployments.d.ts +14 -0
- package/dist/tasks/trusted-deployments.d.ts.map +1 -0
- package/dist/tasks/types.d.ts +4439 -0
- package/dist/tasks/types.d.ts.map +1 -0
- package/dist/tasks/verbs.d.ts +4 -0
- package/dist/tasks/verbs.d.ts.map +1 -0
- package/dist/tasks.js +43906 -0
- package/dist/tasks.js.map +6 -0
- package/dist/transfer.d.ts.map +1 -1
- package/package.json +5 -1
package/dist/router-client.js
CHANGED
|
@@ -37290,6 +37290,14 @@ var configSchema = external_exports.object({
|
|
|
37290
37290
|
})
|
|
37291
37291
|
).optional(),
|
|
37292
37292
|
allowPrivateNetwork: external_exports.boolean().default(false).optional(),
|
|
37293
|
+
tasksEscrowDurationOverrides: external_exports.record(
|
|
37294
|
+
external_exports.string().regex(/^\d+$/),
|
|
37295
|
+
external_exports.object({
|
|
37296
|
+
workDurationSeconds: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),
|
|
37297
|
+
reviewWindowSeconds: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional()
|
|
37298
|
+
}).strict()
|
|
37299
|
+
).optional(),
|
|
37300
|
+
tasksEscrowFactoryOverrides: external_exports.record(external_exports.string().regex(/^\d+$/), external_exports.string()).optional(),
|
|
37293
37301
|
networks: external_exports.record(
|
|
37294
37302
|
external_exports.string().refine((network) => isSupportedPaymentNetwork(network), {
|
|
37295
37303
|
message: "Expected a supported eip155:<chainId> or Solana network identifier."
|
|
@@ -37308,6 +37316,17 @@ var configSchema = external_exports.object({
|
|
|
37308
37316
|
spendCaps: spendCapsSchema,
|
|
37309
37317
|
device: external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,31}$/).optional()
|
|
37310
37318
|
}).superRefine((config2, context) => {
|
|
37319
|
+
for (const [chainId, factory] of Object.entries(config2.tasksEscrowFactoryOverrides ?? {})) {
|
|
37320
|
+
try {
|
|
37321
|
+
getAddress(factory);
|
|
37322
|
+
} catch {
|
|
37323
|
+
context.addIssue({
|
|
37324
|
+
code: "custom",
|
|
37325
|
+
path: ["tasksEscrowFactoryOverrides", chainId],
|
|
37326
|
+
message: "Expected a valid EVM escrow factory address."
|
|
37327
|
+
});
|
|
37328
|
+
}
|
|
37329
|
+
}
|
|
37311
37330
|
for (const [network, configured] of Object.entries(config2.networks)) {
|
|
37312
37331
|
if (isSolanaNetwork(network)) {
|
|
37313
37332
|
if (configured.usdc !== NETWORKS[SOLANA_MAINNET_CAIP2].usdc) {
|
|
@@ -37454,6 +37473,7 @@ function getDefaultConfig(source = process.env, options = {}) {
|
|
|
37454
37473
|
const registry2 = registryEndpoints(source.VAPI_REGISTRY_URL?.trim() || DEFAULT_REGISTRY_URL);
|
|
37455
37474
|
const requested = new Set(options.networks ?? ["base"]);
|
|
37456
37475
|
const networks = {};
|
|
37476
|
+
const tasksEscrowFactoryOverrides = tasksFactoryOverridesFromEnv(source);
|
|
37457
37477
|
if (requested.has("base") || requested.has(BASE_MAINNET_CAIP2)) {
|
|
37458
37478
|
networks[BASE_MAINNET_CAIP2] = {
|
|
37459
37479
|
rpcUrl: source.BASE_RPC_URL?.trim() || NETWORKS[BASE_MAINNET_CAIP2].publicRpcUrl,
|
|
@@ -37491,6 +37511,8 @@ function getDefaultConfig(source = process.env, options = {}) {
|
|
|
37491
37511
|
marketplaceDiscoveryUrl: source.VAPI_MARKETPLACE_DISCOVERY_URL?.trim() || registry2.marketplaceDiscoveryUrl,
|
|
37492
37512
|
registryFallbacks: DEFAULT_REGISTRY_FALLBACKS.map((fallback) => ({ ...fallback })),
|
|
37493
37513
|
allowPrivateNetwork: false,
|
|
37514
|
+
tasksEscrowFactoryOverrides,
|
|
37515
|
+
tasksEscrowDurationOverrides: tasksDurationOverridesFromEnv(source),
|
|
37494
37516
|
networks,
|
|
37495
37517
|
spendCaps: { ...DEFAULT_SPEND_CAPS }
|
|
37496
37518
|
};
|
|
@@ -37508,8 +37530,10 @@ async function loadConfig(path = getVapiPaths().config, source = process.env, op
|
|
|
37508
37530
|
}
|
|
37509
37531
|
const parsed = configSchema.parse(JSON.parse(raw));
|
|
37510
37532
|
parsed.registryFallbacks ??= DEFAULT_REGISTRY_FALLBACKS.map((fallback) => ({ ...fallback }));
|
|
37533
|
+
parsed.tasksEscrowFactoryOverrides ??= {};
|
|
37511
37534
|
const migrated = rewriteLegacyRegistryUrls(parsed);
|
|
37512
37535
|
const config2 = migrated.config;
|
|
37536
|
+
config2.tasksEscrowFactoryOverrides ??= {};
|
|
37513
37537
|
if (migrated.changes.length > 0 && options.notice) {
|
|
37514
37538
|
options.notice(
|
|
37515
37539
|
`${formatLegacyRegistryRewrites(migrated.changes)}
|
|
@@ -37523,6 +37547,14 @@ Run vapi init to write the new URLs to ${path}.`
|
|
|
37523
37547
|
const discoveryUrl = source.VAPI_DISCOVERY_URL?.trim();
|
|
37524
37548
|
const marketplaceDiscoveryUrl = source.VAPI_MARKETPLACE_DISCOVERY_URL?.trim();
|
|
37525
37549
|
const registryUrl = source.VAPI_REGISTRY_URL?.trim();
|
|
37550
|
+
Object.assign(config2.tasksEscrowFactoryOverrides, tasksFactoryOverridesFromEnv(source));
|
|
37551
|
+
config2.tasksEscrowDurationOverrides ??= {};
|
|
37552
|
+
for (const [chainId, overrides] of Object.entries(tasksDurationOverridesFromEnv(source))) {
|
|
37553
|
+
config2.tasksEscrowDurationOverrides[chainId] = {
|
|
37554
|
+
...config2.tasksEscrowDurationOverrides[chainId],
|
|
37555
|
+
...overrides
|
|
37556
|
+
};
|
|
37557
|
+
}
|
|
37526
37558
|
if (config2.networks[BASE_MAINNET_CAIP2] && baseRpcUrl) {
|
|
37527
37559
|
config2.networks[BASE_MAINNET_CAIP2].rpcUrl = baseRpcUrl;
|
|
37528
37560
|
}
|
|
@@ -37563,6 +37595,31 @@ Run vapi init to write the new URLs to ${path}.`
|
|
|
37563
37595
|
}
|
|
37564
37596
|
return config2;
|
|
37565
37597
|
}
|
|
37598
|
+
function tasksDurationOverridesFromEnv(source) {
|
|
37599
|
+
const result = {};
|
|
37600
|
+
for (const [name, raw] of Object.entries(source)) {
|
|
37601
|
+
const match = /^VAPI_TASKS_(WORK_DURATION|REVIEW_WINDOW)_SECONDS_(\d+)$/.exec(name);
|
|
37602
|
+
const value = raw?.trim();
|
|
37603
|
+
if (!match || !value) continue;
|
|
37604
|
+
const seconds = Number(value);
|
|
37605
|
+
if (!/^\d+$/.test(value) || !Number.isSafeInteger(seconds) || seconds <= 0)
|
|
37606
|
+
throw new Error(`Invalid trusted Tasks duration ${name}.`);
|
|
37607
|
+
const entry = result[match[2]] ??= {};
|
|
37608
|
+
if (match[1] === "WORK_DURATION") entry.workDurationSeconds = seconds;
|
|
37609
|
+
else entry.reviewWindowSeconds = seconds;
|
|
37610
|
+
}
|
|
37611
|
+
return result;
|
|
37612
|
+
}
|
|
37613
|
+
function tasksFactoryOverridesFromEnv(source) {
|
|
37614
|
+
const overrides = {};
|
|
37615
|
+
for (const [name, raw] of Object.entries(source)) {
|
|
37616
|
+
const match = /^VAPI_TASKS_ESCROW_FACTORY_(\d+)$/.exec(name);
|
|
37617
|
+
const value = raw?.trim();
|
|
37618
|
+
if (!match || !value) continue;
|
|
37619
|
+
overrides[match[1]] = getAddress(value);
|
|
37620
|
+
}
|
|
37621
|
+
return overrides;
|
|
37622
|
+
}
|
|
37566
37623
|
function registryEndpoints(baseUrl) {
|
|
37567
37624
|
const base = new URL(baseUrl);
|
|
37568
37625
|
base.search = "";
|
|
@@ -37629,7 +37686,12 @@ var AgentLinkError = class extends Error {
|
|
|
37629
37686
|
code;
|
|
37630
37687
|
};
|
|
37631
37688
|
var DEFAULT_AGENT_SCOPES = ["mcp:call", "router.use"];
|
|
37632
|
-
var ALLOWED_AGENT_SCOPES = /* @__PURE__ */ new Set([
|
|
37689
|
+
var ALLOWED_AGENT_SCOPES = /* @__PURE__ */ new Set([
|
|
37690
|
+
...DEFAULT_AGENT_SCOPES,
|
|
37691
|
+
"call.publish",
|
|
37692
|
+
"tasks:read",
|
|
37693
|
+
"tasks:write"
|
|
37694
|
+
]);
|
|
37633
37695
|
var publicFetch = createPublicFetch({ allowPrivateNetwork: false });
|
|
37634
37696
|
var agentSecretAccounts = (wallet) => ({
|
|
37635
37697
|
tokens: `vapi.agent.${wallet}.tokens`,
|
|
@@ -38048,7 +38110,9 @@ var ledgerSchema = external_exports.object({
|
|
|
38048
38110
|
});
|
|
38049
38111
|
var spendReservationSchema = external_exports.object({
|
|
38050
38112
|
id: external_exports.string().min(1),
|
|
38051
|
-
amountAtomic: external_exports.string().regex(/^\d+$/)
|
|
38113
|
+
amountAtomic: external_exports.string().regex(/^\d+$/),
|
|
38114
|
+
kind: external_exports.enum(["payment", "escrow-funding", "dispute-fee"]).optional(),
|
|
38115
|
+
taskKey: external_exports.string().optional()
|
|
38052
38116
|
});
|
|
38053
38117
|
var ledgerRowSchema = ledgerSchema.extend({
|
|
38054
38118
|
wallet: walletNameSchema.optional(),
|
|
@@ -38069,7 +38133,18 @@ var SpendCapError = class extends Error {
|
|
|
38069
38133
|
function utcDateKey(now = /* @__PURE__ */ new Date()) {
|
|
38070
38134
|
return now.toISOString().slice(0, 10);
|
|
38071
38135
|
}
|
|
38072
|
-
|
|
38136
|
+
function sumTaskReservations(rows, wallet, taskKey, excludeReservationId) {
|
|
38137
|
+
let total = 0n;
|
|
38138
|
+
for (const row of rows) {
|
|
38139
|
+
if (row.wallet !== wallet) continue;
|
|
38140
|
+
for (const reservation of row.reservations ?? []) {
|
|
38141
|
+
if (reservation.taskKey === taskKey && reservation.id !== excludeReservationId)
|
|
38142
|
+
total += BigInt(reservation.amountAtomic);
|
|
38143
|
+
}
|
|
38144
|
+
}
|
|
38145
|
+
return total;
|
|
38146
|
+
}
|
|
38147
|
+
async function readStoredSpendLedgerRows(path, now, allDays = false) {
|
|
38073
38148
|
let raw;
|
|
38074
38149
|
try {
|
|
38075
38150
|
raw = await readFile5(path, "utf8");
|
|
@@ -38080,7 +38155,7 @@ async function readStoredSpendLedgerRows(path, now) {
|
|
|
38080
38155
|
const parsed = ledgerFileSchema.parse(JSON.parse(raw));
|
|
38081
38156
|
const rows = "rows" in parsed ? parsed.rows : [parsed];
|
|
38082
38157
|
const today = utcDateKey(now);
|
|
38083
|
-
return rows.filter((row) => row.date === today).map((row) => ({
|
|
38158
|
+
return rows.filter((row) => allDays || row.date === today).map((row) => ({
|
|
38084
38159
|
date: row.date,
|
|
38085
38160
|
spentAtomic: row.spentAtomic,
|
|
38086
38161
|
wallet: row.wallet ?? DEFAULT_WALLET_NAME,
|
|
@@ -38091,49 +38166,164 @@ async function reserveSpend(amountAtomic, caps, options) {
|
|
|
38091
38166
|
if (amountAtomic < 0n) {
|
|
38092
38167
|
throw new Error("Spend amount cannot be negative.");
|
|
38093
38168
|
}
|
|
38094
|
-
const
|
|
38095
|
-
|
|
38096
|
-
if (
|
|
38097
|
-
|
|
38098
|
-
|
|
38099
|
-
|
|
38100
|
-
|
|
38169
|
+
const kind = options?.kind ?? "payment";
|
|
38170
|
+
let perDayAtomic;
|
|
38171
|
+
if (kind === "escrow-funding" || kind === "dispute-fee") {
|
|
38172
|
+
const maxPerTaskAtomic = options?.maxPerTaskAtomic;
|
|
38173
|
+
if (maxPerTaskAtomic === void 0 || maxPerTaskAtomic < 0n) {
|
|
38174
|
+
throw new Error("Escrow funding requires a non-negative per-task cap.");
|
|
38175
|
+
}
|
|
38176
|
+
if (amountAtomic > maxPerTaskAtomic) {
|
|
38177
|
+
throw new SpendCapError(
|
|
38178
|
+
"per_task_cap_exceeded",
|
|
38179
|
+
`Escrow funding ${amountAtomic} atomic USDC exceeds the per-task cap ${maxPerTaskAtomic}. Refusing to sign.`
|
|
38180
|
+
);
|
|
38181
|
+
}
|
|
38182
|
+
perDayAtomic = parseAtomicCap(caps.perDayAtomic, "per-day");
|
|
38183
|
+
} else {
|
|
38184
|
+
const perCallAtomic = parseAtomicCap(caps.perCallAtomic, "per-call");
|
|
38185
|
+
perDayAtomic = parseAtomicCap(caps.perDayAtomic, "per-day");
|
|
38186
|
+
if (amountAtomic > perCallAtomic) {
|
|
38187
|
+
throw new SpendCapError(
|
|
38188
|
+
"per_call_cap_exceeded",
|
|
38189
|
+
`Payment quote ${amountAtomic} atomic USDC exceeds the per-call cap ${perCallAtomic}. Refusing to sign.`
|
|
38190
|
+
);
|
|
38191
|
+
}
|
|
38101
38192
|
}
|
|
38102
38193
|
const ledgerPath = options?.ledgerPath ?? getAgentCashPaths().ledger;
|
|
38103
38194
|
const now = options?.now ?? /* @__PURE__ */ new Date();
|
|
38104
38195
|
const wallet = options?.wallet ?? DEFAULT_WALLET_NAME;
|
|
38105
38196
|
return await withLedgerLock(ledgerPath, async () => {
|
|
38106
|
-
const rows = await readStoredSpendLedgerRows(ledgerPath, now);
|
|
38107
|
-
const
|
|
38197
|
+
const rows = await readStoredSpendLedgerRows(ledgerPath, now, true);
|
|
38198
|
+
const today = utcDateKey(now);
|
|
38199
|
+
const current = rows.find((row) => row.wallet === wallet && row.date === today);
|
|
38200
|
+
if ((kind === "escrow-funding" || kind === "dispute-fee") && options?.taskKey !== void 0) {
|
|
38201
|
+
const taskTotal = sumTaskReservations(
|
|
38202
|
+
rows,
|
|
38203
|
+
wallet,
|
|
38204
|
+
options.taskKey,
|
|
38205
|
+
options.reuseExistingEscrowReservation || options.resumeEscrowReservation ? options.reservationId : void 0
|
|
38206
|
+
) + amountAtomic;
|
|
38207
|
+
if (taskTotal > options.maxPerTaskAtomic)
|
|
38208
|
+
throw new SpendCapError(
|
|
38209
|
+
"per_task_cap_exceeded",
|
|
38210
|
+
`New spend ${amountAtomic} atomic USDC would raise the running total for task ${options.taskKey} and wallet ${wallet} to ${taskTotal}, above the per-task cap ${options.maxPerTaskAtomic}. Refusing to sign.`
|
|
38211
|
+
);
|
|
38212
|
+
}
|
|
38108
38213
|
if (options?.reservationId !== void 0) {
|
|
38109
|
-
|
|
38214
|
+
const existing = current?.reservations?.find(
|
|
38215
|
+
(reservation) => reservation.id === options.reservationId
|
|
38216
|
+
);
|
|
38217
|
+
if (existing && options.reuseExistingEscrowReservation) {
|
|
38218
|
+
if (kind !== "escrow-funding" && kind !== "dispute-fee" || existing.kind !== kind || existing.amountAtomic !== amountAtomic.toString() || existing.taskKey !== void 0 && existing.taskKey !== options.taskKey)
|
|
38219
|
+
throw new Error(
|
|
38220
|
+
`Spend reservation ${options.reservationId} does not match this funding.`
|
|
38221
|
+
);
|
|
38222
|
+
if (existing.taskKey === void 0 && options.taskKey !== void 0) {
|
|
38223
|
+
existing.taskKey = options.taskKey;
|
|
38224
|
+
await writeLedgerAtomically(ledgerPath, rows);
|
|
38225
|
+
}
|
|
38226
|
+
return {
|
|
38227
|
+
date: current.date,
|
|
38228
|
+
spentAtomic: current.spentAtomic,
|
|
38229
|
+
reservationReused: true
|
|
38230
|
+
};
|
|
38231
|
+
}
|
|
38232
|
+
if (existing) {
|
|
38110
38233
|
throw new Error(`Spend reservation ${options.reservationId} already exists.`);
|
|
38111
38234
|
}
|
|
38235
|
+
if (options.resumeEscrowReservation) {
|
|
38236
|
+
const resumed = options.resumeEscrowReservation;
|
|
38237
|
+
const historical = rows.find((row) => row.wallet === wallet && row.date === resumed.date);
|
|
38238
|
+
const stored = historical?.reservations?.find(
|
|
38239
|
+
(reservation) => reservation.id === resumed.id
|
|
38240
|
+
);
|
|
38241
|
+
if (kind !== "escrow-funding" && kind !== "dispute-fee" || resumed.id !== options.reservationId || resumed.wallet !== wallet || resumed.amountAtomic !== amountAtomic.toString() || resumed.date >= utcDateKey(now) || resumed.exposed !== true || resumed.invalidated === true || stored !== void 0 && (stored.kind !== kind || stored.amountAtomic !== amountAtomic.toString() || stored.taskKey !== void 0 && stored.taskKey !== options.taskKey))
|
|
38242
|
+
throw new Error(
|
|
38243
|
+
`Spend reservation ${options.reservationId} does not match this funding.`
|
|
38244
|
+
);
|
|
38245
|
+
if (stored?.taskKey === void 0 && options.taskKey !== void 0) {
|
|
38246
|
+
if (stored) stored.taskKey = options.taskKey;
|
|
38247
|
+
else {
|
|
38248
|
+
const reservation = {
|
|
38249
|
+
id: resumed.id,
|
|
38250
|
+
amountAtomic: resumed.amountAtomic,
|
|
38251
|
+
kind,
|
|
38252
|
+
taskKey: options.taskKey
|
|
38253
|
+
};
|
|
38254
|
+
if (historical)
|
|
38255
|
+
historical.reservations = [...historical.reservations ?? [], reservation];
|
|
38256
|
+
else
|
|
38257
|
+
rows.push({
|
|
38258
|
+
date: resumed.date,
|
|
38259
|
+
spentAtomic: resumed.amountAtomic,
|
|
38260
|
+
wallet,
|
|
38261
|
+
reservations: [reservation]
|
|
38262
|
+
});
|
|
38263
|
+
}
|
|
38264
|
+
await writeLedgerAtomically(ledgerPath, rows);
|
|
38265
|
+
}
|
|
38266
|
+
return {
|
|
38267
|
+
date: resumed.date,
|
|
38268
|
+
spentAtomic: current?.spentAtomic ?? "0",
|
|
38269
|
+
reservationReused: true
|
|
38270
|
+
};
|
|
38271
|
+
}
|
|
38112
38272
|
}
|
|
38113
38273
|
const spentAtomic = current?.spentAtomic ?? "0";
|
|
38114
38274
|
const nextSpent = BigInt(spentAtomic) + amountAtomic;
|
|
38115
38275
|
if (nextSpent > perDayAtomic) {
|
|
38116
38276
|
throw new SpendCapError(
|
|
38117
38277
|
"per_day_cap_exceeded",
|
|
38118
|
-
|
|
38278
|
+
`${kind === "escrow-funding" ? "Escrow funding" : "Payment quote"} ${amountAtomic} atomic USDC would raise today's spend to ${nextSpent} for wallet ${wallet}, above the per-day cap ${perDayAtomic}. Refusing to sign.`
|
|
38119
38279
|
);
|
|
38120
38280
|
}
|
|
38281
|
+
const reservationId = options?.reservationId ?? (options?.taskKey === void 0 ? void 0 : randomBytes4(16).toString("hex"));
|
|
38121
38282
|
const nextRow = {
|
|
38122
38283
|
date: utcDateKey(now),
|
|
38123
38284
|
spentAtomic: nextSpent.toString(),
|
|
38124
38285
|
wallet,
|
|
38125
|
-
...(current?.reservations?.length ?? 0) === 0 &&
|
|
38286
|
+
...(current?.reservations?.length ?? 0) === 0 && reservationId === void 0 ? {} : {
|
|
38126
38287
|
reservations: [
|
|
38127
38288
|
...current?.reservations ?? [],
|
|
38128
|
-
...
|
|
38289
|
+
...reservationId === void 0 ? [] : [
|
|
38290
|
+
{
|
|
38291
|
+
id: reservationId,
|
|
38292
|
+
amountAtomic: amountAtomic.toString(),
|
|
38293
|
+
...kind !== "payment" ? { kind } : {},
|
|
38294
|
+
...options?.taskKey === void 0 ? {} : { taskKey: options.taskKey }
|
|
38295
|
+
}
|
|
38296
|
+
]
|
|
38129
38297
|
]
|
|
38130
38298
|
}
|
|
38131
38299
|
};
|
|
38132
|
-
const
|
|
38133
|
-
(
|
|
38300
|
+
const otherRows = rows.filter((row) => row.wallet !== wallet || row.date !== today).map((row) => {
|
|
38301
|
+
if (row.wallet !== wallet || !options?.reuseExistingEscrowReservation || options.reservationId === void 0)
|
|
38302
|
+
return row;
|
|
38303
|
+
const previous = row.reservations?.find(
|
|
38304
|
+
(reservation) => reservation.id === options.reservationId
|
|
38305
|
+
);
|
|
38306
|
+
if (!previous) return row;
|
|
38307
|
+
if (kind !== "escrow-funding" && kind !== "dispute-fee" || previous.kind !== kind || previous.amountAtomic !== amountAtomic.toString() || previous.taskKey !== void 0 && previous.taskKey !== options.taskKey)
|
|
38308
|
+
throw new Error(
|
|
38309
|
+
`Spend reservation ${options.reservationId} does not match this funding.`
|
|
38310
|
+
);
|
|
38311
|
+
return {
|
|
38312
|
+
...row,
|
|
38313
|
+
reservations: row.reservations.filter(
|
|
38314
|
+
(reservation) => reservation.id !== options.reservationId
|
|
38315
|
+
)
|
|
38316
|
+
};
|
|
38317
|
+
});
|
|
38318
|
+
const nextRows = [...otherRows, nextRow].sort(
|
|
38319
|
+
(a, b) => a.wallet.localeCompare(b.wallet) || a.date.localeCompare(b.date)
|
|
38134
38320
|
);
|
|
38135
38321
|
await writeLedgerAtomically(ledgerPath, nextRows);
|
|
38136
|
-
return {
|
|
38322
|
+
return {
|
|
38323
|
+
date: nextRow.date,
|
|
38324
|
+
spentAtomic: nextRow.spentAtomic,
|
|
38325
|
+
...options?.reservationId === void 0 && reservationId !== void 0 ? { reservationId } : {}
|
|
38326
|
+
};
|
|
38137
38327
|
});
|
|
38138
38328
|
}
|
|
38139
38329
|
async function releaseSpend(amountAtomic, options) {
|
|
@@ -38145,35 +38335,40 @@ async function releaseSpend(amountAtomic, options) {
|
|
|
38145
38335
|
const wallet = options.wallet ?? DEFAULT_WALLET_NAME;
|
|
38146
38336
|
return await withLedgerLock(ledgerPath, async () => {
|
|
38147
38337
|
const today = utcDateKey(now);
|
|
38148
|
-
const rows = await readStoredSpendLedgerRows(ledgerPath, now);
|
|
38149
|
-
const current = rows.find((row) => row.wallet === wallet);
|
|
38150
|
-
if (options.reservedOn !== today) {
|
|
38338
|
+
const rows = await readStoredSpendLedgerRows(ledgerPath, now, true);
|
|
38339
|
+
const current = rows.find((row) => row.wallet === wallet && row.date === today);
|
|
38340
|
+
if (options.reservedOn !== today && options.reservationId === void 0) {
|
|
38151
38341
|
return { date: today, spentAtomic: current?.spentAtomic ?? "0" };
|
|
38152
38342
|
}
|
|
38153
|
-
const
|
|
38343
|
+
const reserved = rows.find((row) => row.wallet === wallet && row.date === options.reservedOn);
|
|
38344
|
+
const reservation = options.reservationId === void 0 ? void 0 : reserved?.reservations?.find((candidate) => candidate.id === options.reservationId);
|
|
38154
38345
|
if (options.reservationId !== void 0 && reservation === void 0) {
|
|
38155
38346
|
return { date: today, spentAtomic: current?.spentAtomic ?? "0" };
|
|
38156
38347
|
}
|
|
38157
38348
|
if (reservation !== void 0 && reservation.amountAtomic !== amountAtomic.toString()) {
|
|
38158
38349
|
throw new Error(`Spend reservation ${options.reservationId} has a different amount.`);
|
|
38159
38350
|
}
|
|
38160
|
-
const spentAtomic = BigInt(
|
|
38351
|
+
const spentAtomic = BigInt(reserved?.spentAtomic ?? "0");
|
|
38161
38352
|
const releasedAmount = reservation === void 0 ? amountAtomic : BigInt(reservation.amountAtomic);
|
|
38162
38353
|
const nextSpent = spentAtomic > releasedAmount ? spentAtomic - releasedAmount : 0n;
|
|
38163
|
-
const remainingReservations =
|
|
38354
|
+
const remainingReservations = reserved?.reservations?.filter(
|
|
38164
38355
|
(candidate) => candidate.id !== options.reservationId
|
|
38165
38356
|
);
|
|
38166
38357
|
const nextRow = {
|
|
38167
|
-
date:
|
|
38358
|
+
date: options.reservedOn,
|
|
38168
38359
|
spentAtomic: nextSpent.toString(),
|
|
38169
38360
|
wallet,
|
|
38170
38361
|
...remainingReservations === void 0 || remainingReservations.length === 0 ? {} : { reservations: remainingReservations }
|
|
38171
38362
|
};
|
|
38172
|
-
const nextRows = [
|
|
38173
|
-
(
|
|
38174
|
-
|
|
38363
|
+
const nextRows = [
|
|
38364
|
+
...rows.filter((row) => row.wallet !== wallet || row.date !== options.reservedOn),
|
|
38365
|
+
nextRow
|
|
38366
|
+
].sort((a, b) => a.wallet.localeCompare(b.wallet) || a.date.localeCompare(b.date));
|
|
38175
38367
|
await writeLedgerAtomically(ledgerPath, nextRows);
|
|
38176
|
-
return {
|
|
38368
|
+
return {
|
|
38369
|
+
date: today,
|
|
38370
|
+
spentAtomic: options.reservedOn === today ? nextRow.spentAtomic : current?.spentAtomic ?? "0"
|
|
38371
|
+
};
|
|
38177
38372
|
});
|
|
38178
38373
|
}
|
|
38179
38374
|
function parseAtomicCap(value, label) {
|
|
@@ -44435,7 +44630,9 @@ async function transferBetweenAccounts(args) {
|
|
|
44435
44630
|
);
|
|
44436
44631
|
reservedOn = reservation.date;
|
|
44437
44632
|
} catch (error61) {
|
|
44438
|
-
if (error61 instanceof SpendCapError
|
|
44633
|
+
if (error61 instanceof SpendCapError && isTransferErrorCode(error61.code)) {
|
|
44634
|
+
throw transferError(error61.code);
|
|
44635
|
+
}
|
|
44439
44636
|
throw transferError("network_error");
|
|
44440
44637
|
}
|
|
44441
44638
|
}
|
|
@@ -46300,7 +46497,7 @@ var RunBudgetError = class extends Error {
|
|
|
46300
46497
|
};
|
|
46301
46498
|
|
|
46302
46499
|
// src/support-report.ts
|
|
46303
|
-
var VAPI_CLIENT_VERSION = "0.
|
|
46500
|
+
var VAPI_CLIENT_VERSION = "0.9.0";
|
|
46304
46501
|
|
|
46305
46502
|
// src/x402-pay.ts
|
|
46306
46503
|
var X402PaymentError = class extends Error {
|