@vapi-network/cli 0.9.2 → 0.9.4
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/dist/cli.d.ts +1 -1
- package/dist/cli.js +467 -92
- package/dist/cli.js.map +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +460 -86
- package/dist/index.js.map +3 -3
- package/dist/setup.d.ts +2 -1
- package/dist/update-check.d.ts +13 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10116,11 +10116,9 @@ var init_call = __esm({
|
|
|
10116
10116
|
}
|
|
10117
10117
|
});
|
|
10118
10118
|
|
|
10119
|
-
// src/
|
|
10120
|
-
import {
|
|
10121
|
-
import {
|
|
10122
|
-
import { join as join28 } from "node:path";
|
|
10123
|
-
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
10119
|
+
// src/update-check.ts
|
|
10120
|
+
import { lookup } from "node:dns/promises";
|
|
10121
|
+
import { mkdir as mkdir21, readFile as readFile29, writeFile as writeFile12 } from "node:fs/promises";
|
|
10124
10122
|
|
|
10125
10123
|
// ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
|
|
10126
10124
|
var external_exports = {};
|
|
@@ -39357,8 +39355,10 @@ var listingIdentitySchema = external_exports.looseObject({
|
|
|
39357
39355
|
}).optional().catch(void 0)
|
|
39358
39356
|
});
|
|
39359
39357
|
var listingDisclosureShape = {
|
|
39360
|
-
|
|
39361
|
-
fee
|
|
39358
|
+
// Presentation metadata must not make an otherwise executable row vanish
|
|
39359
|
+
// when the registry adds a new group or changes the fee display shape.
|
|
39360
|
+
group: listingGroupSchema.optional().catch(void 0),
|
|
39361
|
+
fee: listingFeeSchema.optional().catch(void 0),
|
|
39362
39362
|
verification: listingVerificationFieldSchema,
|
|
39363
39363
|
liveness: listingLivenessSchema.optional().catch(void 0),
|
|
39364
39364
|
conformance: listingConformanceSchema.optional().catch(void 0),
|
|
@@ -39366,11 +39366,13 @@ var listingDisclosureShape = {
|
|
|
39366
39366
|
};
|
|
39367
39367
|
var marketplaceBadgeCodeSchema = external_exports.enum([
|
|
39368
39368
|
"live_x402",
|
|
39369
|
+
"mpp",
|
|
39369
39370
|
"partner",
|
|
39370
39371
|
"payout_wallet_confirmed",
|
|
39371
39372
|
"vapi_verified",
|
|
39372
39373
|
"external_catalog",
|
|
39373
|
-
"approved_vendor"
|
|
39374
|
+
"approved_vendor",
|
|
39375
|
+
"unverified"
|
|
39374
39376
|
]);
|
|
39375
39377
|
var marketplaceBadgeSchema = external_exports.looseObject({
|
|
39376
39378
|
code: marketplaceBadgeCodeSchema,
|
|
@@ -39389,7 +39391,13 @@ var marketplaceCardSchema = external_exports.looseObject({
|
|
|
39389
39391
|
summary: external_exports.string().trim().min(1).max(1e3),
|
|
39390
39392
|
byline: external_exports.string().trim().min(1).max(160).optional(),
|
|
39391
39393
|
bylineHref: marketplaceHrefSchema.optional(),
|
|
39392
|
-
badges: external_exports.
|
|
39394
|
+
badges: external_exports.preprocess(
|
|
39395
|
+
(badges) => Array.isArray(badges) ? badges.flatMap((badge) => {
|
|
39396
|
+
const parsed = marketplaceBadgeSchema.safeParse(badge);
|
|
39397
|
+
return parsed.success ? [parsed.data] : [];
|
|
39398
|
+
}) : badges,
|
|
39399
|
+
external_exports.array(marketplaceBadgeSchema).max(8)
|
|
39400
|
+
),
|
|
39393
39401
|
facts: external_exports.array(marketplacePublicFactSchema).max(12)
|
|
39394
39402
|
});
|
|
39395
39403
|
var marketplaceHitBase = {
|
|
@@ -44870,9 +44878,9 @@ function createPublicFetch(options) {
|
|
|
44870
44878
|
});
|
|
44871
44879
|
});
|
|
44872
44880
|
}
|
|
44873
|
-
function pinnedLookup(
|
|
44881
|
+
function pinnedLookup(lookup2) {
|
|
44874
44882
|
return (hostname3, dnsOptions, callback) => {
|
|
44875
|
-
void
|
|
44883
|
+
void lookup2(normalizeHostname(hostname3)).then((addresses) => {
|
|
44876
44884
|
if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
|
|
44877
44885
|
callback(guardError(new URL(`https://${hostname3}`)), "");
|
|
44878
44886
|
return;
|
|
@@ -46010,9 +46018,9 @@ function isRecord2(value) {
|
|
|
46010
46018
|
var CALLABLE_CATEGORIES = ["ai", "data", "crypto", "compute", "search"];
|
|
46011
46019
|
var callableCategorySchema = external_exports.enum(CALLABLE_CATEGORIES);
|
|
46012
46020
|
var DISCOVERY_CATEGORIES = [...CALLABLE_CATEGORIES, "other"];
|
|
46013
|
-
var discoveryCategorySchema = external_exports.
|
|
46021
|
+
var discoveryCategorySchema = external_exports.string().trim().min(1);
|
|
46014
46022
|
var CALLABLE_CATEGORY_SET = new Set(CALLABLE_CATEGORIES);
|
|
46015
|
-
var serviceTierSchema = external_exports.
|
|
46023
|
+
var serviceTierSchema = external_exports.string().trim().min(1);
|
|
46016
46024
|
var discoveryEndpointSchema = external_exports.looseObject({
|
|
46017
46025
|
name: external_exports.string(),
|
|
46018
46026
|
method: external_exports.string(),
|
|
@@ -46042,6 +46050,24 @@ var discoveryEndpointSchema = external_exports.looseObject({
|
|
|
46042
46050
|
asset: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
|
|
46043
46051
|
payTo: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
|
|
46044
46052
|
checkedAt: external_exports.iso.datetime()
|
|
46053
|
+
}),
|
|
46054
|
+
external_exports.looseObject({
|
|
46055
|
+
protocol: external_exports.literal("mpp"),
|
|
46056
|
+
intent: external_exports.enum(["charge", "authorize", "subscription"]).nullable(),
|
|
46057
|
+
method: external_exports.string().trim().min(1).max(40).nullable(),
|
|
46058
|
+
checkedAt: external_exports.iso.datetime(),
|
|
46059
|
+
// Keep common x402 properties readable on the union while making it
|
|
46060
|
+
// impossible for MPP metadata to masquerade as executable x402 terms.
|
|
46061
|
+
network: external_exports.never().optional(),
|
|
46062
|
+
payTo: external_exports.never().optional()
|
|
46063
|
+
}),
|
|
46064
|
+
external_exports.looseObject({
|
|
46065
|
+
// Future payment protocols remain visible to callers so the payment
|
|
46066
|
+
// layer can refuse them explicitly instead of discovery losing the row.
|
|
46067
|
+
protocol: external_exports.string().trim().min(1).max(40),
|
|
46068
|
+
checkedAt: external_exports.iso.datetime(),
|
|
46069
|
+
network: external_exports.never().optional(),
|
|
46070
|
+
payTo: external_exports.never().optional()
|
|
46045
46071
|
})
|
|
46046
46072
|
]).optional()
|
|
46047
46073
|
});
|
|
@@ -46135,7 +46161,7 @@ function resolveTarget(service, endpointName) {
|
|
|
46135
46161
|
}
|
|
46136
46162
|
if (targets.size !== 1) {
|
|
46137
46163
|
const paymentNetworks = service.endpoints.flatMap(
|
|
46138
|
-
(endpoint) => endpoint.payment ? [endpoint.payment.network] : []
|
|
46164
|
+
(endpoint) => typeof endpoint.payment?.network === "string" ? [endpoint.payment.network] : []
|
|
46139
46165
|
);
|
|
46140
46166
|
throw new DiscoveryCatalogError(
|
|
46141
46167
|
"ambiguous_default",
|
|
@@ -47110,7 +47136,8 @@ function getVapiPaths(directory = process.env.VAPI_HOME?.trim() || join2(homedir
|
|
|
47110
47136
|
keystore: join2(directory, "keystore.json"),
|
|
47111
47137
|
receipts: join2(directory, "receipts.jsonl"),
|
|
47112
47138
|
searches: join2(directory, "searches.jsonl"),
|
|
47113
|
-
ledger: join2(directory, "spend-ledger.json")
|
|
47139
|
+
ledger: join2(directory, "spend-ledger.json"),
|
|
47140
|
+
updateCheck: join2(directory, "update-check.json")
|
|
47114
47141
|
};
|
|
47115
47142
|
}
|
|
47116
47143
|
var getAgentCashPaths = getVapiPaths;
|
|
@@ -70374,7 +70401,7 @@ function windowsDataProtectionStore(platform2, run, env, installed) {
|
|
|
70374
70401
|
};
|
|
70375
70402
|
}
|
|
70376
70403
|
function libsecretStore(platform2, run, installed) {
|
|
70377
|
-
const
|
|
70404
|
+
const lookup2 = async (name) => {
|
|
70378
70405
|
const result = await run(SECRET_TOOL_BINARY, [
|
|
70379
70406
|
"lookup",
|
|
70380
70407
|
"service",
|
|
@@ -70393,9 +70420,9 @@ function libsecretStore(platform2, run, installed) {
|
|
|
70393
70420
|
available: installed(SECRET_TOOL_BINARY),
|
|
70394
70421
|
platform: platform2,
|
|
70395
70422
|
description: "the libsecret keyring",
|
|
70396
|
-
get:
|
|
70423
|
+
get: lookup2,
|
|
70397
70424
|
async has(name) {
|
|
70398
|
-
return await
|
|
70425
|
+
return await lookup2(name) !== void 0;
|
|
70399
70426
|
},
|
|
70400
70427
|
async set(name, passphrase) {
|
|
70401
70428
|
requirePassphrase(passphrase);
|
|
@@ -70417,7 +70444,7 @@ function libsecretStore(platform2, run, installed) {
|
|
|
70417
70444
|
requireSuccess(result, `store the passphrase of ${name} in the secret service`);
|
|
70418
70445
|
},
|
|
70419
70446
|
async remove(name) {
|
|
70420
|
-
const existed = await
|
|
70447
|
+
const existed = await lookup2(name) !== void 0;
|
|
70421
70448
|
const result = await run(SECRET_TOOL_BINARY, [
|
|
70422
70449
|
"clear",
|
|
70423
70450
|
"service",
|
|
@@ -71480,6 +71507,8 @@ var VAULT_KEY_ACCOUNT = "vault-key";
|
|
|
71480
71507
|
var VAULT_SESSION_ACCOUNT = "vault-session";
|
|
71481
71508
|
var DEVICE_KEY_LENGTH = 32;
|
|
71482
71509
|
var DEFAULT_SESSION_HOURS = 8;
|
|
71510
|
+
var RESTORE_GAP_LIMIT = 5;
|
|
71511
|
+
var MAX_RESTORE_ACCOUNTS = 1e4;
|
|
71483
71512
|
var BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
|
|
71484
71513
|
var deviceKeyOperations = Promise.resolve();
|
|
71485
71514
|
var sessionSchema = external_exports.object({
|
|
@@ -71629,26 +71658,41 @@ async function restoreVault(args) {
|
|
|
71629
71658
|
throw new VaultError("corrupt", "That recovery phrase is not valid.", { cause: error61 });
|
|
71630
71659
|
}
|
|
71631
71660
|
let seed;
|
|
71632
|
-
|
|
71661
|
+
if (args.accountCount !== void 0 && (!Number.isSafeInteger(args.accountCount) || args.accountCount < 1 || args.accountCount > MAX_RESTORE_ACCOUNTS)) {
|
|
71662
|
+
throw new VaultError(
|
|
71663
|
+
"corrupt",
|
|
71664
|
+
`Account count must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
71665
|
+
);
|
|
71666
|
+
}
|
|
71667
|
+
let discoveredAccounts = args.accountCount ?? 0;
|
|
71668
|
+
let scannedAddresses = 0;
|
|
71633
71669
|
try {
|
|
71634
71670
|
seed = phraseToSeed(phrase);
|
|
71635
71671
|
} catch (error61) {
|
|
71636
71672
|
throw asVaultError2(error61, "Unable to derive an account while restoring the vault.");
|
|
71637
71673
|
}
|
|
71638
71674
|
try {
|
|
71639
|
-
for (let index2 = 0; ; index2 += 1) {
|
|
71675
|
+
for (let index2 = 0, emptyRun = 0; args.accountCount === void 0; index2 += 1) {
|
|
71640
71676
|
let address4;
|
|
71641
71677
|
try {
|
|
71642
71678
|
address4 = privateKeyToAccount(deriveEvmPrivateKey(seed, `m/44'/60'/0'/0/${index2}`)).address;
|
|
71643
71679
|
} catch (error61) {
|
|
71644
71680
|
throw asVaultError2(error61, "Unable to derive an account while restoring the vault.");
|
|
71645
71681
|
}
|
|
71646
|
-
|
|
71647
|
-
|
|
71682
|
+
const funded = await args.probe(address4);
|
|
71683
|
+
scannedAddresses += 1;
|
|
71684
|
+
if (funded) {
|
|
71685
|
+
discoveredAccounts = index2 + 1;
|
|
71686
|
+
emptyRun = 0;
|
|
71687
|
+
} else {
|
|
71688
|
+
emptyRun += 1;
|
|
71689
|
+
if (emptyRun === RESTORE_GAP_LIMIT) break;
|
|
71690
|
+
}
|
|
71648
71691
|
}
|
|
71649
71692
|
} finally {
|
|
71650
71693
|
seed.fill(0);
|
|
71651
71694
|
}
|
|
71695
|
+
args.onScanComplete?.(scannedAddresses);
|
|
71652
71696
|
let vault;
|
|
71653
71697
|
try {
|
|
71654
71698
|
vault = await createVault({ path: args.path, key: args.key, phrase, now: args.now });
|
|
@@ -72137,6 +72181,26 @@ var WalletStore = class _WalletStore {
|
|
|
72137
72181
|
}
|
|
72138
72182
|
);
|
|
72139
72183
|
}
|
|
72184
|
+
/** Checks a cached signer's current vault session without decrypting its account again. */
|
|
72185
|
+
async assertSigningAuthority(name) {
|
|
72186
|
+
const stored = await this.readVaultUnlocked();
|
|
72187
|
+
if (!stored?.protected || !stored.accounts.some((account) => account.name === name)) return;
|
|
72188
|
+
try {
|
|
72189
|
+
const key2 = await unlockProtectedVault({
|
|
72190
|
+
path: this.vaultPath,
|
|
72191
|
+
secrets: this.secrets,
|
|
72192
|
+
env: this.environment,
|
|
72193
|
+
now: () => this.now()
|
|
72194
|
+
});
|
|
72195
|
+
key2.fill(0);
|
|
72196
|
+
} catch (error61) {
|
|
72197
|
+
this.dropVaultCache();
|
|
72198
|
+
if (error61 instanceof VaultError && error61.code === "password_required") {
|
|
72199
|
+
throw new KeystoreError(VAULT_LOCKED_MESSAGE, { cause: error61 });
|
|
72200
|
+
}
|
|
72201
|
+
throw error61;
|
|
72202
|
+
}
|
|
72203
|
+
}
|
|
72140
72204
|
/** Returns one wallet's vault signer, migrating its legacy keystore if needed. */
|
|
72141
72205
|
async unlock(name, passphrase) {
|
|
72142
72206
|
const wallet = this.resolve({ name });
|
|
@@ -77523,7 +77587,7 @@ function createRunBudget(args) {
|
|
|
77523
77587
|
import { mkdir as mkdir15, writeFile as writeFile8 } from "node:fs/promises";
|
|
77524
77588
|
import { arch, platform, release } from "node:os";
|
|
77525
77589
|
import { join as join13 } from "node:path";
|
|
77526
|
-
var VAPI_CLIENT_VERSION = "0.9.
|
|
77590
|
+
var VAPI_CLIENT_VERSION = "0.9.4";
|
|
77527
77591
|
async function createSupportReport(options) {
|
|
77528
77592
|
const message = options.message.trim();
|
|
77529
77593
|
if (!message) throw new Error("Support report message must not be empty.");
|
|
@@ -77796,7 +77860,7 @@ async function completeX402Payment(args) {
|
|
|
77796
77860
|
let paidAttempt;
|
|
77797
77861
|
const requestStarted = nowMs();
|
|
77798
77862
|
try {
|
|
77799
|
-
paidAttempt = await args.send(paidRequest);
|
|
77863
|
+
paidAttempt = await args.send(paidRequest, quote);
|
|
77800
77864
|
} catch (error61) {
|
|
77801
77865
|
if (trace) trace.phases.requestMs = elapsed(nowMs, requestStarted);
|
|
77802
77866
|
throw settlementUnknown(
|
|
@@ -77814,7 +77878,7 @@ async function completeX402Payment(args) {
|
|
|
77814
77878
|
const settleStarted = nowMs();
|
|
77815
77879
|
const settlement = parseSettlementResponse(paidResponse.headers);
|
|
77816
77880
|
const settlementOutcome = classifySettlement(settlement);
|
|
77817
|
-
const receiptSettlement =
|
|
77881
|
+
const receiptSettlement = sanitizeReturnedValue(settlement, receiptSecrets);
|
|
77818
77882
|
if (trace) {
|
|
77819
77883
|
const transaction2 = settlementTransaction(receiptSettlement);
|
|
77820
77884
|
const explorerUrl = transaction2 ? explorerTransactionUrl(quote.accepted.network, transaction2) : void 0;
|
|
@@ -77891,6 +77955,7 @@ async function completeX402Payment(args) {
|
|
|
77891
77955
|
trace.phases.requestMs = (trace.phases.requestMs ?? 0) + elapsed(nowMs, bodyStarted);
|
|
77892
77956
|
}
|
|
77893
77957
|
}
|
|
77958
|
+
body = sanitizeReturnedValue(body, receiptSecrets);
|
|
77894
77959
|
}
|
|
77895
77960
|
const result = {
|
|
77896
77961
|
response: paidResponse,
|
|
@@ -77899,7 +77964,11 @@ async function completeX402Payment(args) {
|
|
|
77899
77964
|
quote,
|
|
77900
77965
|
payer,
|
|
77901
77966
|
...payment.paymentId ? { paymentId: payment.paymentId } : {},
|
|
77902
|
-
|
|
77967
|
+
paymentProof: sanitizeReturnedValue(
|
|
77968
|
+
paidResponse.headers.get("x-vapi-payment-proof"),
|
|
77969
|
+
receiptSecrets
|
|
77970
|
+
),
|
|
77971
|
+
settlement: receiptSettlement,
|
|
77903
77972
|
settlementOutcome
|
|
77904
77973
|
};
|
|
77905
77974
|
if (settlementOutcome === "succeeded" && args.ceilingSweep) {
|
|
@@ -78036,19 +78105,70 @@ function sanitizeThrownError(error61, secrets) {
|
|
|
78036
78105
|
}
|
|
78037
78106
|
return new Error(message, cause === void 0 ? void 0 : { cause });
|
|
78038
78107
|
}
|
|
78039
|
-
function
|
|
78108
|
+
function sanitizeReturnedValue(value, secrets) {
|
|
78040
78109
|
if (typeof value === "string") return redactKnownSecrets(value, secrets);
|
|
78041
|
-
if (value
|
|
78042
|
-
|
|
78043
|
-
|
|
78044
|
-
|
|
78110
|
+
if (!isPlainReturnedContainer(value)) return value;
|
|
78111
|
+
const nodes = /* @__PURE__ */ new WeakMap();
|
|
78112
|
+
const ordered = [];
|
|
78113
|
+
const nodeFor = (source) => {
|
|
78114
|
+
const existing = nodes.get(source);
|
|
78115
|
+
if (existing) return existing;
|
|
78116
|
+
const copy = Array.isArray(source) ? new Array(source.length) : Object.create(Object.getPrototypeOf(source));
|
|
78117
|
+
const node2 = { source, copy, parents: /* @__PURE__ */ new Set(), changed: false };
|
|
78118
|
+
nodes.set(source, node2);
|
|
78119
|
+
ordered.push(node2);
|
|
78120
|
+
return node2;
|
|
78121
|
+
};
|
|
78122
|
+
const root = nodeFor(value);
|
|
78123
|
+
for (let index2 = 0; index2 < ordered.length; index2 += 1) {
|
|
78124
|
+
const node2 = ordered[index2];
|
|
78125
|
+
for (const [key2, item] of Object.entries(node2.source)) {
|
|
78126
|
+
const safeKey = Array.isArray(node2.source) ? key2 : redactKnownSecrets(key2, secrets);
|
|
78127
|
+
if (safeKey !== key2) node2.changed = true;
|
|
78128
|
+
if (typeof item === "string") {
|
|
78129
|
+
const safeItem = redactKnownSecrets(item, secrets);
|
|
78130
|
+
defineReturnedProperty(node2.copy, safeKey, safeItem);
|
|
78131
|
+
if (safeItem !== item) node2.changed = true;
|
|
78132
|
+
} else if (isPlainReturnedContainer(item)) {
|
|
78133
|
+
const child = nodeFor(item);
|
|
78134
|
+
child.parents.add(node2);
|
|
78135
|
+
defineReturnedProperty(node2.copy, safeKey, child.copy);
|
|
78136
|
+
} else {
|
|
78137
|
+
defineReturnedProperty(node2.copy, safeKey, item);
|
|
78138
|
+
}
|
|
78139
|
+
}
|
|
78045
78140
|
}
|
|
78046
|
-
|
|
78047
|
-
|
|
78048
|
-
|
|
78049
|
-
|
|
78050
|
-
|
|
78051
|
-
|
|
78141
|
+
const changed = ordered.filter((node2) => node2.changed);
|
|
78142
|
+
for (let index2 = 0; index2 < changed.length; index2 += 1) {
|
|
78143
|
+
for (const parent of changed[index2].parents) {
|
|
78144
|
+
if (parent.changed) continue;
|
|
78145
|
+
parent.changed = true;
|
|
78146
|
+
changed.push(parent);
|
|
78147
|
+
}
|
|
78148
|
+
}
|
|
78149
|
+
for (const node2 of ordered) {
|
|
78150
|
+
for (const [key2, item] of Object.entries(node2.source)) {
|
|
78151
|
+
if (!isPlainReturnedContainer(item)) continue;
|
|
78152
|
+
const safeKey = Array.isArray(node2.source) ? key2 : redactKnownSecrets(key2, secrets);
|
|
78153
|
+
const child = nodes.get(item);
|
|
78154
|
+
defineReturnedProperty(node2.copy, safeKey, child.changed ? child.copy : item);
|
|
78155
|
+
}
|
|
78156
|
+
}
|
|
78157
|
+
return root.changed ? root.copy : value;
|
|
78158
|
+
}
|
|
78159
|
+
function defineReturnedProperty(target, key2, value) {
|
|
78160
|
+
Object.defineProperty(target, key2, {
|
|
78161
|
+
value,
|
|
78162
|
+
enumerable: true,
|
|
78163
|
+
configurable: true,
|
|
78164
|
+
writable: true
|
|
78165
|
+
});
|
|
78166
|
+
}
|
|
78167
|
+
function isPlainReturnedContainer(value) {
|
|
78168
|
+
if (Array.isArray(value)) return true;
|
|
78169
|
+
if (value === null || typeof value !== "object") return false;
|
|
78170
|
+
const prototype = Object.getPrototypeOf(value);
|
|
78171
|
+
return prototype === Object.prototype || prototype === null;
|
|
78052
78172
|
}
|
|
78053
78173
|
function redactKnownSecrets(value, secrets) {
|
|
78054
78174
|
let redacted = value;
|
|
@@ -78083,9 +78203,7 @@ function possibleSettlement(quote, payment, payer, receipt) {
|
|
|
78083
78203
|
payTo: quote.accepted.payTo,
|
|
78084
78204
|
payer,
|
|
78085
78205
|
...payment.paymentId ? { paymentId: payment.paymentId } : {},
|
|
78086
|
-
...isSvmPaymentRequirements(quote.accepted) ? {
|
|
78087
|
-
authorizationTransaction: "transaction" in payment.payload.payload ? payment.payload.payload.transaction : ""
|
|
78088
|
-
} : "authorization" in payment.payload.payload ? {
|
|
78206
|
+
...isSvmPaymentRequirements(quote.accepted) ? {} : "authorization" in payment.payload.payload ? {
|
|
78089
78207
|
authorizationNonce: payment.payload.payload.authorization.nonce,
|
|
78090
78208
|
authorizationExpiresAt: payment.payload.payload.authorization.validBefore
|
|
78091
78209
|
} : {},
|
|
@@ -78463,13 +78581,22 @@ async function sendRouterChat(deps, routerBaseUrl, routerKey, request, keyUsed)
|
|
|
78463
78581
|
}
|
|
78464
78582
|
const body = await responseText(response);
|
|
78465
78583
|
if (!response.ok) {
|
|
78466
|
-
if (
|
|
78584
|
+
if (/budget (?:has been )?exceeded|exceededbudget/iu.test(body)) {
|
|
78467
78585
|
throw new RouterClientError(
|
|
78468
78586
|
"budget_exhausted",
|
|
78469
78587
|
"The Router key has no remaining budget.",
|
|
78470
78588
|
response.status
|
|
78471
78589
|
);
|
|
78472
78590
|
}
|
|
78591
|
+
if (response.status === 429) {
|
|
78592
|
+
const retryAfter = response.headers.get("retry-after")?.trim();
|
|
78593
|
+
const retrySeconds = retryAfter !== void 0 && /^\d+$/u.test(retryAfter) ? Number(retryAfter) : void 0;
|
|
78594
|
+
throw new RouterClientError(
|
|
78595
|
+
"rate_limited",
|
|
78596
|
+
`The vAPI Router is rate limited. ${retrySeconds !== void 0 && Number.isFinite(retrySeconds) ? `Retry after ${retrySeconds} seconds.` : "Wait and retry shortly."}`,
|
|
78597
|
+
response.status
|
|
78598
|
+
);
|
|
78599
|
+
}
|
|
78473
78600
|
if (response.status === 401) {
|
|
78474
78601
|
throw new RouterClientError(
|
|
78475
78602
|
"no_router_key",
|
|
@@ -87055,6 +87182,12 @@ function isRecord4(value) {
|
|
|
87055
87182
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
87056
87183
|
}
|
|
87057
87184
|
|
|
87185
|
+
// src/cli.ts
|
|
87186
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
87187
|
+
import { stat as stat16 } from "node:fs/promises";
|
|
87188
|
+
import { join as join28 } from "node:path";
|
|
87189
|
+
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
87190
|
+
|
|
87058
87191
|
// ../core/src/member-bundle.ts
|
|
87059
87192
|
var MEMBER_BUNDLE_MAX_BYTES = 32 * 1024;
|
|
87060
87193
|
var REMOTE_BLOCKED_GRANTS = /* @__PURE__ */ new Set([
|
|
@@ -87746,12 +87879,13 @@ var BODY_HEADER_NAMES = [
|
|
|
87746
87879
|
"content-type"
|
|
87747
87880
|
];
|
|
87748
87881
|
async function callService(args) {
|
|
87882
|
+
validateTimeoutSeconds(args.input.timeoutSeconds);
|
|
87749
87883
|
const trace = createCallTrace(args);
|
|
87750
87884
|
let execution;
|
|
87751
87885
|
try {
|
|
87752
87886
|
execution = await executeCallService(args, trace);
|
|
87753
87887
|
} catch (error61) {
|
|
87754
|
-
if (!(error61 instanceof VapiCallError && error61.code === "unsupported_network")) {
|
|
87888
|
+
if (!(error61 instanceof VapiCallError && (error61.code === "unsupported_network" || error61.code === "unsupported_payment"))) {
|
|
87755
87889
|
await recordCallError(args, error61, trace).catch(() => void 0);
|
|
87756
87890
|
}
|
|
87757
87891
|
throw error61;
|
|
@@ -87865,6 +87999,8 @@ async function executeCallService(args, trace) {
|
|
|
87865
87999
|
body: method === "GET" || method === "HEAD" ? void 0 : requestBody
|
|
87866
88000
|
});
|
|
87867
88001
|
const request = createRequest(headers);
|
|
88002
|
+
const probeTimeoutMs = input2.timeoutSeconds === void 0 ? args.timeoutMs ?? 3e4 : Math.min(input2.timeoutSeconds, 30) * 1e3;
|
|
88003
|
+
let requestTimeoutMs = probeTimeoutMs;
|
|
87868
88004
|
const fetchWithGuardedRedirects = async (candidateRequest, followRedirects = true) => {
|
|
87869
88005
|
let currentRequest = candidateRequest;
|
|
87870
88006
|
let followedRedirects = 0;
|
|
@@ -87872,7 +88008,7 @@ async function executeCallService(args, trace) {
|
|
|
87872
88008
|
const attempt = await fetchAttempt(
|
|
87873
88009
|
fetchImpl,
|
|
87874
88010
|
new Request(currentRequest.clone(), { redirect: "manual" }),
|
|
87875
|
-
|
|
88011
|
+
requestTimeoutMs
|
|
87876
88012
|
);
|
|
87877
88013
|
const response = attempt.response;
|
|
87878
88014
|
if (!isRedirectStatus2(response.status)) {
|
|
@@ -88027,7 +88163,12 @@ async function executeCallService(args, trace) {
|
|
|
88027
88163
|
account,
|
|
88028
88164
|
caps: args.spendCaps ?? config2.spendCaps,
|
|
88029
88165
|
config: payableConfig(config2, account),
|
|
88030
|
-
send: async (paidRequest) => {
|
|
88166
|
+
send: async (paidRequest, quote) => {
|
|
88167
|
+
requestTimeoutMs = paidRequestTimeoutMs(
|
|
88168
|
+
input2.timeoutSeconds,
|
|
88169
|
+
args.timeoutMs,
|
|
88170
|
+
quote.accepted.maxTimeoutSeconds
|
|
88171
|
+
);
|
|
88031
88172
|
paidAttempt = await fetchWithGuardedRedirects(paidRequest, false);
|
|
88032
88173
|
return paidAttempt;
|
|
88033
88174
|
},
|
|
@@ -88066,7 +88207,7 @@ async function executeCallService(args, trace) {
|
|
|
88066
88207
|
asset: completed.quote.accepted.asset,
|
|
88067
88208
|
payTo: completed.quote.accepted.payTo,
|
|
88068
88209
|
settlement: settlementWithExplorer2(completed.settlement, completed.quote.accepted.network),
|
|
88069
|
-
proof: completed.
|
|
88210
|
+
proof: completed.paymentProof
|
|
88070
88211
|
},
|
|
88071
88212
|
...verificationFor(endpoint),
|
|
88072
88213
|
...expectedRequestFor(endpoint, completed.response.status)
|
|
@@ -88313,8 +88454,16 @@ async function resolveCallEndpoint(id2, endpointName, marketplaceHit, config2, f
|
|
|
88313
88454
|
);
|
|
88314
88455
|
}
|
|
88315
88456
|
function registeredEndpoint(listing, verification) {
|
|
88457
|
+
const { payment, ...endpoint } = listing.endpoint;
|
|
88458
|
+
if (payment && (typeof payment.protocol === "string" || typeof payment.network !== "string")) {
|
|
88459
|
+
throw new VapiCallError(
|
|
88460
|
+
"unsupported_payment",
|
|
88461
|
+
`Payment protocol ${payment.protocol} is not supported. This client pays x402 exact USDC endpoints only.`
|
|
88462
|
+
);
|
|
88463
|
+
}
|
|
88316
88464
|
return {
|
|
88317
|
-
...
|
|
88465
|
+
...endpoint,
|
|
88466
|
+
...payment ? { payment: { network: payment.network, payTo: payment.payTo } } : {},
|
|
88318
88467
|
verification: verification ?? listing.service.verification,
|
|
88319
88468
|
serviceNetworks: listing.service.networks,
|
|
88320
88469
|
registered: true,
|
|
@@ -88476,7 +88625,7 @@ async function readResponseBody2(response) {
|
|
|
88476
88625
|
async function fetchAttempt(fetchImpl, request, timeoutMs) {
|
|
88477
88626
|
const controller = new AbortController();
|
|
88478
88627
|
let rejectTimeout = null;
|
|
88479
|
-
const timeoutError = new Error(`API request timed out after ${timeoutMs}
|
|
88628
|
+
const timeoutError = new Error(`API request timed out after ${timeoutMs / 1e3} seconds.`);
|
|
88480
88629
|
const timedOut = new Promise((_resolve, reject) => {
|
|
88481
88630
|
rejectTimeout = reject;
|
|
88482
88631
|
});
|
|
@@ -88516,6 +88665,19 @@ async function fetchAttempt(fetchImpl, request, timeoutMs) {
|
|
|
88516
88665
|
throw error61;
|
|
88517
88666
|
}
|
|
88518
88667
|
}
|
|
88668
|
+
function validateTimeoutSeconds(timeoutSeconds) {
|
|
88669
|
+
if (timeoutSeconds !== void 0 && (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 1 || timeoutSeconds > 300)) {
|
|
88670
|
+
throw new Error("call timeoutSeconds must be an integer from 1 to 300 seconds.");
|
|
88671
|
+
}
|
|
88672
|
+
}
|
|
88673
|
+
function paidRequestTimeoutMs(timeoutSeconds, internalTimeoutMs, offerTimeoutSeconds) {
|
|
88674
|
+
const usableOfferTimeout = Number.isInteger(offerTimeoutSeconds) && offerTimeoutSeconds > 0 ? offerTimeoutSeconds : void 0;
|
|
88675
|
+
if (timeoutSeconds !== void 0) {
|
|
88676
|
+
return Math.min(timeoutSeconds, usableOfferTimeout ?? timeoutSeconds) * 1e3;
|
|
88677
|
+
}
|
|
88678
|
+
if (internalTimeoutMs !== void 0) return internalTimeoutMs;
|
|
88679
|
+
return usableOfferTimeout === void 0 ? 12e4 : Math.min(12e4, Math.max(3e4, usableOfferTimeout * 1e3));
|
|
88680
|
+
}
|
|
88519
88681
|
function mapX402PaymentError(error61, resumeId) {
|
|
88520
88682
|
if (!(error61 instanceof X402PaymentError)) return error61;
|
|
88521
88683
|
if (error61.code === "payment_rejected") {
|
|
@@ -88531,9 +88693,10 @@ function mapX402PaymentError(error61, resumeId) {
|
|
|
88531
88693
|
});
|
|
88532
88694
|
}
|
|
88533
88695
|
const resume = resumeId !== void 0 && error61.possibleSettlement?.authorizationNonce ? ` Check whether it settled with \`vapi pay --resume ${resumeId}\` before paying again.` : "";
|
|
88696
|
+
const timeoutDetail = error61.cause instanceof Error && error61.cause.message.startsWith("API request timed out after ") ? `${error61.cause.message} ` : "";
|
|
88534
88697
|
return new VapiCallError(
|
|
88535
88698
|
"settlement_unknown",
|
|
88536
|
-
`${error61.message}${resume}`,
|
|
88699
|
+
`${timeoutDetail}${error61.message}${resume}`,
|
|
88537
88700
|
error61.possibleSettlement,
|
|
88538
88701
|
{ cause: error61.cause }
|
|
88539
88702
|
);
|
|
@@ -88665,13 +88828,7 @@ var inspectToolResultSchema = external_exports.object({
|
|
|
88665
88828
|
liveness: listingLivenessSchema.optional(),
|
|
88666
88829
|
conformance: listingConformanceSchema.optional(),
|
|
88667
88830
|
identity: listingIdentitySchema.optional(),
|
|
88668
|
-
payment:
|
|
88669
|
-
scheme: external_exports.literal("exact"),
|
|
88670
|
-
network: external_exports.string(),
|
|
88671
|
-
asset: external_exports.string(),
|
|
88672
|
-
payTo: external_exports.string(),
|
|
88673
|
-
checkedAt: external_exports.string()
|
|
88674
|
-
}).nullable()
|
|
88831
|
+
payment: discoveryEndpointSchema.shape.payment.unwrap().nullable()
|
|
88675
88832
|
});
|
|
88676
88833
|
var callSearchInputSchema = external_exports.object({
|
|
88677
88834
|
query: external_exports.string().trim().max(200).optional().describe("Capability, API, service, or request."),
|
|
@@ -88700,7 +88857,10 @@ var callPayInputSchema = external_exports.object({
|
|
|
88700
88857
|
(value) => /^0x[0-9a-fA-F]{40}$/.test(value) || isSolanaAddress(value),
|
|
88701
88858
|
"Expected an EVM or Solana address."
|
|
88702
88859
|
).optional(),
|
|
88703
|
-
maxPriceUsd: external_exports.union([external_exports.number().nonnegative(), external_exports.string().regex(/^\d+(?:\.\d{1,6})?$/)]).optional()
|
|
88860
|
+
maxPriceUsd: external_exports.union([external_exports.number().nonnegative(), external_exports.string().regex(/^\d+(?:\.\d{1,6})?$/)]).optional(),
|
|
88861
|
+
timeoutSeconds: external_exports.number().int().min(1).max(300).optional().describe(
|
|
88862
|
+
"Seconds to wait for the paid response. Default: the provider's maxTimeoutSeconds, at most 120."
|
|
88863
|
+
)
|
|
88704
88864
|
});
|
|
88705
88865
|
var callSearch = defineAction({
|
|
88706
88866
|
name: "call.search",
|
|
@@ -88963,7 +89123,7 @@ async function readResult(response, signal, secrets = []) {
|
|
|
88963
89123
|
return {
|
|
88964
89124
|
status: response.status,
|
|
88965
89125
|
contentType: contentType === null ? null : redactKnownSecrets2(contentType, secrets),
|
|
88966
|
-
body:
|
|
89126
|
+
body: sanitizeReturnedValue2(await readResponseBody3(response, contentType, signal), secrets)
|
|
88967
89127
|
};
|
|
88968
89128
|
}
|
|
88969
89129
|
async function readResponseBody3(response, contentType, signal) {
|
|
@@ -89008,17 +89168,17 @@ function isJsonContentType2(value) {
|
|
|
89008
89168
|
const mediaType = value?.split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
89009
89169
|
return mediaType === "application/json" || mediaType.endsWith("+json");
|
|
89010
89170
|
}
|
|
89011
|
-
function
|
|
89171
|
+
function sanitizeReturnedValue2(value, secrets, depth = 0) {
|
|
89012
89172
|
if (typeof value === "string") return redactKnownSecrets2(value, secrets);
|
|
89013
89173
|
if (value === null || typeof value !== "object") return value;
|
|
89014
89174
|
if (depth >= 16) return "[redacted nested response value]";
|
|
89015
89175
|
if (Array.isArray(value)) {
|
|
89016
|
-
return value.map((item) =>
|
|
89176
|
+
return value.map((item) => sanitizeReturnedValue2(item, secrets, depth + 1));
|
|
89017
89177
|
}
|
|
89018
89178
|
return Object.fromEntries(
|
|
89019
89179
|
Object.entries(value).map(([key2, item]) => [
|
|
89020
89180
|
redactKnownSecrets2(key2, secrets),
|
|
89021
|
-
|
|
89181
|
+
sanitizeReturnedValue2(item, secrets, depth + 1)
|
|
89022
89182
|
])
|
|
89023
89183
|
);
|
|
89024
89184
|
}
|
|
@@ -94524,7 +94684,13 @@ function toolError(error61) {
|
|
|
94524
94684
|
{
|
|
94525
94685
|
error: error61.message,
|
|
94526
94686
|
code: error61.code,
|
|
94527
|
-
...error61.possibleSettlement ? {
|
|
94687
|
+
...error61.possibleSettlement ? {
|
|
94688
|
+
possibleSettlement: Object.fromEntries(
|
|
94689
|
+
Object.entries(error61.possibleSettlement).filter(
|
|
94690
|
+
([key2]) => key2 !== "authorizationTransaction"
|
|
94691
|
+
)
|
|
94692
|
+
)
|
|
94693
|
+
} : {},
|
|
94528
94694
|
...error61.paymentRejection ? { paymentRejection: error61.paymentRejection } : {},
|
|
94529
94695
|
...error61.confirmedSettlement ? { confirmedSettlement: error61.confirmedSettlement } : {}
|
|
94530
94696
|
},
|
|
@@ -98018,7 +98184,7 @@ async function readProcessStdin() {
|
|
|
98018
98184
|
}
|
|
98019
98185
|
|
|
98020
98186
|
// src/version.ts
|
|
98021
|
-
var CLI_VERSION = "0.9.
|
|
98187
|
+
var CLI_VERSION = "0.9.4";
|
|
98022
98188
|
|
|
98023
98189
|
// src/status.ts
|
|
98024
98190
|
async function statusCommand(argv, json2, io, dependencies) {
|
|
@@ -101520,7 +101686,7 @@ function createLocalRuntime(options) {
|
|
|
101520
101686
|
const processCommand = options.processCommand ?? defaultProcessCommand;
|
|
101521
101687
|
const ownsProcess = (handle, pid) => processCommand(pid)?.includes(runResultPath(home, handle.runId)) === true;
|
|
101522
101688
|
const closeFd = options.closeFd ?? closeSync2;
|
|
101523
|
-
const
|
|
101689
|
+
const readFile30 = options.readFile ?? nodeReadFile;
|
|
101524
101690
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
101525
101691
|
const openLog = options.openLog ?? ((path) => {
|
|
101526
101692
|
mkdirSync2(runsDirectory(home), { recursive: true, mode: 448 });
|
|
@@ -101575,7 +101741,7 @@ function createLocalRuntime(options) {
|
|
|
101575
101741
|
return handle;
|
|
101576
101742
|
},
|
|
101577
101743
|
async status(handle) {
|
|
101578
|
-
const result = await readResultFile(
|
|
101744
|
+
const result = await readResultFile(readFile30, runResultPath(home, handle.runId));
|
|
101579
101745
|
if (result !== void 0) return result;
|
|
101580
101746
|
const pid = localPid(handle);
|
|
101581
101747
|
if (pid === void 0 || handle.kind !== "local") {
|
|
@@ -101678,10 +101844,10 @@ function childArguments(member, run) {
|
|
|
101678
101844
|
...run.drawUsd ? ["--draw", run.drawUsd] : []
|
|
101679
101845
|
];
|
|
101680
101846
|
}
|
|
101681
|
-
async function readResultFile(
|
|
101847
|
+
async function readResultFile(readFile30, path) {
|
|
101682
101848
|
let text;
|
|
101683
101849
|
try {
|
|
101684
|
-
text = await
|
|
101850
|
+
text = await readFile30(path, "utf8");
|
|
101685
101851
|
} catch (error61) {
|
|
101686
101852
|
if (hasCode3(error61, "ENOENT")) return void 0;
|
|
101687
101853
|
return { state: "failed", detail: "unreadable result file" };
|
|
@@ -102531,7 +102697,7 @@ function isMcpInstallApp(value) {
|
|
|
102531
102697
|
function serverEntry(home, registry2) {
|
|
102532
102698
|
return {
|
|
102533
102699
|
command: "npx",
|
|
102534
|
-
args: ["-y", "vapi-network", "mcp"],
|
|
102700
|
+
args: ["-y", "vapi-network@latest", "mcp"],
|
|
102535
102701
|
env: { VAPI_HOME: home, VAPI_REGISTRY_URL: registry2 }
|
|
102536
102702
|
};
|
|
102537
102703
|
}
|
|
@@ -102580,7 +102746,7 @@ function tomlConfig(existing, entry) {
|
|
|
102580
102746
|
const block = [
|
|
102581
102747
|
"[mcp_servers.vapi]",
|
|
102582
102748
|
'command = "npx"',
|
|
102583
|
-
'args = ["-y", "vapi-network", "mcp"]',
|
|
102749
|
+
'args = ["-y", "vapi-network@latest", "mcp"]',
|
|
102584
102750
|
`env = { VAPI_HOME = "${escapeToml(entry.env.VAPI_HOME)}", VAPI_REGISTRY_URL = "${escapeToml(entry.env.VAPI_REGISTRY_URL)}" }`,
|
|
102585
102751
|
""
|
|
102586
102752
|
].join("\n");
|
|
@@ -102747,13 +102913,13 @@ async function sendConfig(dependencies) {
|
|
|
102747
102913
|
// src/setup.ts
|
|
102748
102914
|
import { rm as rm5 } from "node:fs/promises";
|
|
102749
102915
|
import { join as join26 } from "node:path";
|
|
102750
|
-
var SETUP_ARGUMENT_ERROR =
|
|
102916
|
+
var SETUP_ARGUMENT_ERROR = `vapi setup accepts only --no-cloud-backup and --accounts <n> (1-${MAX_RESTORE_ACCOUNTS}); a recovery phrase is typed at the prompt, never passed on the command line.`;
|
|
102751
102917
|
var VAULT_CHOICE = "Create a new vault, or restore one from a recovery phrase? [new/restore] ";
|
|
102752
102918
|
async function setupCommand(argv, json2, io, dependencies) {
|
|
102753
102919
|
let parsed;
|
|
102754
102920
|
try {
|
|
102755
102921
|
parsed = parseArguments(argv, {
|
|
102756
|
-
valueOptions: /* @__PURE__ */ new Set(),
|
|
102922
|
+
valueOptions: /* @__PURE__ */ new Set(["--accounts"]),
|
|
102757
102923
|
booleanOptions: /* @__PURE__ */ new Set(["--no-cloud-backup"]),
|
|
102758
102924
|
maximumPositionals: 0
|
|
102759
102925
|
});
|
|
@@ -102764,6 +102930,7 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102764
102930
|
const paths = getVapiPaths();
|
|
102765
102931
|
const steps = [];
|
|
102766
102932
|
const humanIo = json2 ? stderrIo(io) : io;
|
|
102933
|
+
const accountCount = parseAccountCount(parsed.one("--accounts"));
|
|
102767
102934
|
if (!await fileExists2(paths.config)) {
|
|
102768
102935
|
await writeDefaultConfig(paths.config, process.env, { networks: ["base"] });
|
|
102769
102936
|
steps.push("config");
|
|
@@ -102774,6 +102941,7 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102774
102941
|
let changedVault = false;
|
|
102775
102942
|
let changedAccount = false;
|
|
102776
102943
|
let changedLink = false;
|
|
102944
|
+
let scannedAddresses;
|
|
102777
102945
|
if (!await fileExists2(join26(paths.directory, "vault.json"))) {
|
|
102778
102946
|
const choice = await vaultChoice(dependencies);
|
|
102779
102947
|
if (choice === "restore") {
|
|
@@ -102781,12 +102949,14 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102781
102949
|
throw new Error("Restoring needs a terminal to type the phrase.");
|
|
102782
102950
|
}
|
|
102783
102951
|
const readSecret = dependencies.prompts?.secret ?? promptForSecret;
|
|
102784
|
-
await restoreVaultFromPhrase(
|
|
102952
|
+
const restored = await restoreVaultFromPhrase(
|
|
102785
102953
|
await readSecret("Recovery phrase: "),
|
|
102786
102954
|
config2,
|
|
102787
102955
|
humanIo,
|
|
102788
|
-
dependencies
|
|
102956
|
+
dependencies,
|
|
102957
|
+
accountCount
|
|
102789
102958
|
);
|
|
102959
|
+
scannedAddresses = restored.scannedAddresses;
|
|
102790
102960
|
store = await WalletStore.open(paths.directory, {
|
|
102791
102961
|
secrets: getSecretStore(dependencies),
|
|
102792
102962
|
env: dependencies.env ?? process.env,
|
|
@@ -102839,22 +103009,35 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102839
103009
|
}
|
|
102840
103010
|
if (json2) {
|
|
102841
103011
|
io.stdout(
|
|
102842
|
-
JSON.stringify({
|
|
103012
|
+
JSON.stringify({
|
|
103013
|
+
vault,
|
|
103014
|
+
account,
|
|
103015
|
+
address: address4,
|
|
103016
|
+
linked,
|
|
103017
|
+
steps,
|
|
103018
|
+
cloudBackup,
|
|
103019
|
+
...scannedAddresses === void 0 ? {} : { scannedAddresses }
|
|
103020
|
+
})
|
|
102843
103021
|
);
|
|
102844
103022
|
}
|
|
102845
103023
|
}
|
|
102846
|
-
async function restoreVaultFromPhrase(phrase, config2, io, dependencies) {
|
|
103024
|
+
async function restoreVaultFromPhrase(phrase, config2, io, dependencies, accountCount) {
|
|
102847
103025
|
const paths = getVapiPaths();
|
|
102848
103026
|
const validatedPhrase = validateRecoveryPhrase(phrase);
|
|
102849
103027
|
const readBalance3 = baseUsdcBalanceReader(config2, dependencies);
|
|
102850
103028
|
const key2 = await loadOrCreateDeviceKey({ secrets: getSecretStore(dependencies) });
|
|
102851
103029
|
let names;
|
|
103030
|
+
let scannedAddresses = 0;
|
|
102852
103031
|
try {
|
|
102853
103032
|
const restored = await restoreVault({
|
|
102854
103033
|
path: join26(paths.directory, "vault.json"),
|
|
102855
103034
|
key: key2,
|
|
102856
103035
|
phrase: validatedPhrase,
|
|
102857
103036
|
probe: async (address4) => await readBalance3(address4) > 0n,
|
|
103037
|
+
...accountCount === void 0 ? {} : { accountCount },
|
|
103038
|
+
onScanComplete: (count) => {
|
|
103039
|
+
scannedAddresses = count;
|
|
103040
|
+
},
|
|
102858
103041
|
...dependencies.now === void 0 ? {} : { now: dependencies.now }
|
|
102859
103042
|
});
|
|
102860
103043
|
names = restored.accounts().map((account) => account.name);
|
|
@@ -102866,8 +103049,25 @@ async function restoreVaultFromPhrase(phrase, config2, io, dependencies) {
|
|
|
102866
103049
|
...names[0] === void 0 ? {} : { wallet: names[0] },
|
|
102867
103050
|
detail: `${names.length} account(s)`
|
|
102868
103051
|
});
|
|
102869
|
-
io.stdout(
|
|
102870
|
-
|
|
103052
|
+
io.stdout(
|
|
103053
|
+
`Vault restored with ${names.length} account(s): ${names.join(", ")}. ${scannedAddresses} address(es) scanned.`
|
|
103054
|
+
);
|
|
103055
|
+
return { names, scannedAddresses };
|
|
103056
|
+
}
|
|
103057
|
+
function parseAccountCount(value) {
|
|
103058
|
+
if (value === void 0) return void 0;
|
|
103059
|
+
if (!/^\d+$/u.test(value)) {
|
|
103060
|
+
throw new UsageError(
|
|
103061
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
103062
|
+
);
|
|
103063
|
+
}
|
|
103064
|
+
const count = Number(value);
|
|
103065
|
+
if (!Number.isSafeInteger(count) || count < 1 || count > MAX_RESTORE_ACCOUNTS) {
|
|
103066
|
+
throw new UsageError(
|
|
103067
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
103068
|
+
);
|
|
103069
|
+
}
|
|
103070
|
+
return count;
|
|
102871
103071
|
}
|
|
102872
103072
|
async function vaultChoice(dependencies) {
|
|
102873
103073
|
const answer = dependencies.prompts?.line === void 0 ? isInteractive(dependencies) ? await promptForLine(VAULT_CHOICE) : "" : await dependencies.prompts.line(VAULT_CHOICE);
|
|
@@ -104975,6 +105175,7 @@ async function referencedSleep(milliseconds, signal) {
|
|
|
104975
105175
|
// src/vault.ts
|
|
104976
105176
|
import { join as join27 } from "node:path";
|
|
104977
105177
|
var VAULT_USAGE = "Usage: vapi vault protect|unprotect|lock|unlock|status [--json]";
|
|
105178
|
+
var RESTORE_USAGE = "Usage: vapi restore [--accounts <n> | --from-owner [--owner <0x\u2026>]] [--json]";
|
|
104978
105179
|
var LEGACY_PASSWORD_NOTICE = "VAPI_KEYSTORE_PASSWORD is deprecated for vault passwords; use VAPI_VAULT_PASSWORD instead.";
|
|
104979
105180
|
async function vaultCommand(argv, json2, io, dependencies) {
|
|
104980
105181
|
const subcommand = argv[0];
|
|
@@ -105004,9 +105205,17 @@ async function restoreCommand(argv, json2, io, dependencies) {
|
|
|
105004
105205
|
await restoreFromOwnerCommand(argv, json2, io, dependencies);
|
|
105005
105206
|
return;
|
|
105006
105207
|
}
|
|
105007
|
-
|
|
105008
|
-
|
|
105208
|
+
let parsed;
|
|
105209
|
+
try {
|
|
105210
|
+
parsed = parseArguments(argv, {
|
|
105211
|
+
valueOptions: /* @__PURE__ */ new Set(["--accounts"]),
|
|
105212
|
+
maximumPositionals: 0
|
|
105213
|
+
});
|
|
105214
|
+
} catch (error61) {
|
|
105215
|
+
if (error61 instanceof UsageError) throw new UsageError(RESTORE_USAGE);
|
|
105216
|
+
throw error61;
|
|
105009
105217
|
}
|
|
105218
|
+
const accountCount = parseRestoreAccountCount(parsed.one("--accounts"));
|
|
105010
105219
|
const paths = getVapiPaths();
|
|
105011
105220
|
const path = join27(paths.directory, "vault.json");
|
|
105012
105221
|
if (await fileExists2(path)) {
|
|
@@ -105020,13 +105229,39 @@ async function restoreCommand(argv, json2, io, dependencies) {
|
|
|
105020
105229
|
const config2 = await readConfig(paths.config, json2 ? quietIo(io) : io);
|
|
105021
105230
|
const phrase = isStdinInteractive(dependencies) ? await getPrompts(dependencies).secret("Recovery phrase: ") : await (dependencies.readStdin ?? readProcessStdin3)();
|
|
105022
105231
|
const restoreIo = json2 ? quietIo(io) : io;
|
|
105023
|
-
const { names } = await restoreVaultFromPhrase(
|
|
105232
|
+
const { names, scannedAddresses } = await restoreVaultFromPhrase(
|
|
105233
|
+
phrase.trim(),
|
|
105234
|
+
config2,
|
|
105235
|
+
restoreIo,
|
|
105236
|
+
dependencies,
|
|
105237
|
+
accountCount
|
|
105238
|
+
);
|
|
105024
105239
|
if (json2) {
|
|
105025
|
-
output3(
|
|
105240
|
+
output3(
|
|
105241
|
+
io,
|
|
105242
|
+
true,
|
|
105243
|
+
{ command: "restore", vault: "restored", accounts: names, scannedAddresses },
|
|
105244
|
+
""
|
|
105245
|
+
);
|
|
105026
105246
|
return;
|
|
105027
105247
|
}
|
|
105028
105248
|
io.stdout(`Run vapi setup to link ${names[0]}.`);
|
|
105029
105249
|
}
|
|
105250
|
+
function parseRestoreAccountCount(value) {
|
|
105251
|
+
if (value === void 0) return void 0;
|
|
105252
|
+
if (!/^\d+$/u.test(value)) {
|
|
105253
|
+
throw new UsageError(
|
|
105254
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
105255
|
+
);
|
|
105256
|
+
}
|
|
105257
|
+
const count = Number(value);
|
|
105258
|
+
if (!Number.isSafeInteger(count) || count < 1 || count > MAX_RESTORE_ACCOUNTS) {
|
|
105259
|
+
throw new UsageError(
|
|
105260
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
105261
|
+
);
|
|
105262
|
+
}
|
|
105263
|
+
return count;
|
|
105264
|
+
}
|
|
105030
105265
|
async function protectCommand(argv, json2, io, dependencies) {
|
|
105031
105266
|
requireNoArguments(argv);
|
|
105032
105267
|
const env = getEnvironment(dependencies);
|
|
@@ -105156,8 +105391,8 @@ var HELP_HEADING = "vAPI Network";
|
|
|
105156
105391
|
var HELP = `${HELP_HEADING}
|
|
105157
105392
|
|
|
105158
105393
|
Usage:
|
|
105159
|
-
vapi init [--networks <base,arc
|
|
105160
|
-
vapi setup [--no-cloud-backup] [--json]
|
|
105394
|
+
vapi init [--networks <base,arc>] [--json]
|
|
105395
|
+
vapi setup [--no-cloud-backup] [--accounts <n>] [--json]
|
|
105161
105396
|
vapi accounts [--all] [--json]
|
|
105162
105397
|
vapi accounts add <name> [--label <text>] [--no-link] [--json]
|
|
105163
105398
|
vapi accounts import <name> [--keystore <path> | --key-file <path>] [--label <text>] [--json]
|
|
@@ -105187,7 +105422,7 @@ Usage:
|
|
|
105187
105422
|
vapi docs read <url-or-path> [--json]
|
|
105188
105423
|
vapi search [query] [--kind <kind>] [--network <caip2>] [--limit <n>] [--cursor <cursor>] [--include-unverified] [--json]
|
|
105189
105424
|
vapi inspect <id> [--endpoint <name>] [--json]
|
|
105190
|
-
vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--account <name>] [--json]
|
|
105425
|
+
vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--timeout <seconds>] [--account <name>] [--json]
|
|
105191
105426
|
vapi pay --resume <receipt-id> [--json]
|
|
105192
105427
|
vapi check <url> [--method <method>] [--json]
|
|
105193
105428
|
vapi balance [--account <name>] [--json]
|
|
@@ -105233,8 +105468,8 @@ Usage:
|
|
|
105233
105468
|
vapi task status <id> [--account <name>] [--json]
|
|
105234
105469
|
vapi export-key [--network <caip2>] [--account <name>] [--json]
|
|
105235
105470
|
vapi backup [--account <name>] [--cloud [off]] [--json]
|
|
105236
|
-
vapi restore [--from-owner [--owner <0x\u2026>]] [--json]
|
|
105237
|
-
vapi import (--phrase | --key) [--account <name>] [--networks <base,arc
|
|
105471
|
+
vapi restore [--accounts <n> | --from-owner [--owner <0x\u2026>]] [--json]
|
|
105472
|
+
vapi import (--phrase | --key) [--account <name>] [--networks <base,arc>] [--replace] [--force] [--json]
|
|
105238
105473
|
vapi passphrase [--account <name>] [--json]
|
|
105239
105474
|
vapi vault protect [--json]
|
|
105240
105475
|
vapi vault unprotect [--json]
|
|
@@ -105262,6 +105497,8 @@ Every command that touches a wallet takes \`--account <name>\`, falls back to \`
|
|
|
105262
105497
|
|
|
105263
105498
|
\`vapi search\` answers with vAPI-verified listings plus the mirrored external catalogs. \`--include-unverified\` also returns self-listed APIs that passed vAPI's automated x402 probe but were never reviewed; every result is tagged \`[verified]\`, \`[requested]\`, \`[unverified]\` or \`[external]\`.
|
|
105264
105499
|
|
|
105500
|
+
Solana listings remain searchable; inspect and pay return \`unsupported_network\`. Solana keys are not part of the device vault yet.
|
|
105501
|
+
|
|
105265
105502
|
\`vapi docs\` asks the public vAPI documentation assistant; \`vapi docs search\` searches documentation excerpts and \`vapi docs read\` reads one Markdown page. They need no account, wallet or payment.
|
|
105266
105503
|
|
|
105267
105504
|
\`vapi task --help\` lists task options and availability. Task exit codes: 0 ok, 1 error, 2 policy refusal (JSON ok:false with a policy. reason) or invalid usage (JSON error), 3 approval needed in non-interactive mode. Posting moves no money; the current create-order contract does not store amount, deadline, intake, max awards or webhook yet.
|
|
@@ -105274,7 +105511,7 @@ Every command that touches a wallet takes \`--account <name>\`, falls back to \`
|
|
|
105274
105511
|
|
|
105275
105512
|
\`vapi vault protect\` adds a password to the device vault. \`vapi vault unlock\` opens it on this device for 8 hours; for unattended use, set \`VAPI_VAULT_PASSWORD\`. \`vapi unlock\` and \`vapi lock\` remain aliases for one release.
|
|
105276
105513
|
|
|
105277
|
-
\`vapi backup\` and \`vapi export-key\` print a secret, so they run only on a real terminal, never for an agent, and ask you to type the wallet name first. \`vapi backup --cloud\` keeps an encrypted vault copy that only the owner can approve for recovery. \`vapi restore\` rebuilds the vault from the phrase and re-derives accounts until
|
|
105514
|
+
\`vapi backup\` and \`vapi export-key\` print a secret, so they run only on a real terminal, never for an agent, and ask you to type the wallet name first. \`vapi backup --cloud\` keeps an encrypted vault copy that only the owner can approve for recovery. \`vapi restore\` rebuilds the vault from the phrase and re-derives accounts until five consecutive addresses have no Base USDC, and reports the number scanned. Use \`--accounts <n>\` with restore or setup to recover a fixed count without querying balances. Set \`VAPI_NO_SECRETS=1\` to switch exports off entirely. Every export and every wallet change is logged to ~/.vapi/audit.log.
|
|
105278
105515
|
|
|
105279
105516
|
\`vapi publish <url>\` lists an API you own. vAPI probes the URL \u2014 an origin, one endpoint, or an OpenAPI document \u2014 you choose which endpoints to list, and your wallet signs one line naming where the payouts go. Listing is permissionless: a listing that passed the probe goes live with \`vapi publish activate <slug>\`, and \`vapi publish verify-request <slug>\` asks for the review that puts it in the default search. Deploying the FeeSplitter that receives the payouts is a wallet transaction and stays in the console. A catalog of more than 20 endpoints is listed as several listings of up to 20, with one result line per endpoint; \`--resume\` skips every endpoint this key already lists.
|
|
105280
105517
|
|
|
@@ -106063,7 +106300,7 @@ async function inspectCommand(argv, json2, io, dependencies) {
|
|
|
106063
106300
|
);
|
|
106064
106301
|
output3(io, json2, result, formatInspect(result));
|
|
106065
106302
|
}
|
|
106066
|
-
var PAY_USAGE = "Usage: vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--account <name>] [--json]";
|
|
106303
|
+
var PAY_USAGE = "Usage: vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--timeout <seconds>] [--account <name>] [--json]";
|
|
106067
106304
|
async function payCommand(argv, json2, io, dependencies) {
|
|
106068
106305
|
if (argv.includes(RESUME_OPTION)) {
|
|
106069
106306
|
await payResumeCommand(argv, json2, io, dependencies);
|
|
@@ -106079,11 +106316,13 @@ async function payCommand(argv, json2, io, dependencies) {
|
|
|
106079
106316
|
"--expected-pay-to",
|
|
106080
106317
|
"--max",
|
|
106081
106318
|
"--max-price-usd",
|
|
106319
|
+
"--timeout",
|
|
106082
106320
|
WALLET_OPTION5
|
|
106083
106321
|
]),
|
|
106084
106322
|
maximumPositionals: 1
|
|
106085
106323
|
});
|
|
106086
106324
|
const target = requiredPositional(parsed.positionals[0], "<id-or-url>", PAY_USAGE);
|
|
106325
|
+
const timeoutSeconds = optionalBoundedInteger(parsed.one("--timeout"), "--timeout", 1, 300);
|
|
106087
106326
|
const paths = getVapiPaths();
|
|
106088
106327
|
const config2 = await readConfig(paths.config, io);
|
|
106089
106328
|
const wallet = await targetWallet(parsed, dependencies);
|
|
@@ -106099,7 +106338,8 @@ async function payCommand(argv, json2, io, dependencies) {
|
|
|
106099
106338
|
...parsed.one("--content-type") ? { contentType: parsed.one("--content-type") } : {},
|
|
106100
106339
|
...parsed.one("--network") ? { network: parsed.one("--network") } : {},
|
|
106101
106340
|
...parsed.one("--expected-pay-to") ? { expectedPayTo: parsed.one("--expected-pay-to") } : {},
|
|
106102
|
-
...maxPriceUsd ? { maxPriceUsd } : {}
|
|
106341
|
+
...maxPriceUsd ? { maxPriceUsd } : {},
|
|
106342
|
+
...timeoutSeconds === void 0 ? {} : { timeoutSeconds }
|
|
106103
106343
|
};
|
|
106104
106344
|
const call2 = createCallPort({
|
|
106105
106345
|
config: config2,
|
|
@@ -107774,7 +108014,7 @@ function buildNextSteps(address4) {
|
|
|
107774
108014
|
formatNextStep("Pay", "vapi pay <ref> --max 0.02"),
|
|
107775
108015
|
formatNextStep(
|
|
107776
108016
|
"Agent",
|
|
107777
|
-
'add {"command":"npx","args":["-y","vapi-network","mcp"]} to your MCP config'
|
|
108017
|
+
'add {"command":"npx","args":["-y","vapi-network@latest","mcp"]} to your MCP config'
|
|
107778
108018
|
)
|
|
107779
108019
|
];
|
|
107780
108020
|
}
|
|
@@ -107955,6 +108195,17 @@ function optionalPositiveInteger(value, option) {
|
|
|
107955
108195
|
if (result === 0) throw new UsageError(`${option} must be a positive integer.`);
|
|
107956
108196
|
return result;
|
|
107957
108197
|
}
|
|
108198
|
+
function optionalBoundedInteger(value, option, minimum, maximum) {
|
|
108199
|
+
if (value === void 0) return void 0;
|
|
108200
|
+
if (!/^\d+$/.test(value)) {
|
|
108201
|
+
throw new UsageError(`${option} must be an integer from ${minimum} to ${maximum}.`);
|
|
108202
|
+
}
|
|
108203
|
+
const parsed = Number(value);
|
|
108204
|
+
if (!Number.isSafeInteger(parsed) || parsed < minimum || parsed > maximum) {
|
|
108205
|
+
throw new UsageError(`${option} must be an integer from ${minimum} to ${maximum}.`);
|
|
108206
|
+
}
|
|
108207
|
+
return parsed;
|
|
108208
|
+
}
|
|
107958
108209
|
function optionalUsdAmount(value, option) {
|
|
107959
108210
|
if (value === void 0) return void 0;
|
|
107960
108211
|
if (!/^\d+(?:\.\d{1,2})?$/.test(value)) {
|
|
@@ -108015,12 +108266,136 @@ function parseInitNetworks(value) {
|
|
|
108015
108266
|
}
|
|
108016
108267
|
for (const network of networks) {
|
|
108017
108268
|
if (network !== "base" && network !== "arc" && network !== "solana") {
|
|
108018
|
-
throw new UsageError("--networks supports base
|
|
108269
|
+
throw new UsageError("--networks supports base and arc; Solana vault setup is unavailable.");
|
|
108019
108270
|
}
|
|
108020
108271
|
}
|
|
108021
108272
|
return networks;
|
|
108022
108273
|
}
|
|
108023
108274
|
|
|
108275
|
+
// src/update-check.ts
|
|
108276
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
108277
|
+
var CHECK_TIMEOUT_MS = 1500;
|
|
108278
|
+
var LATEST_URL = "https://registry.npmjs.org/vapi-network/latest";
|
|
108279
|
+
async function runCliWithUpdateCheck(argv = process.argv.slice(2), io = {
|
|
108280
|
+
stdout: (message) => console.log(message),
|
|
108281
|
+
stderr: (message) => console.error(message)
|
|
108282
|
+
}, dependencies = {}, options = {}) {
|
|
108283
|
+
const notice = checkForUpdate({ ...options, env: options.env ?? dependencies.env, argv });
|
|
108284
|
+
const code = await runCli(argv, io, dependencies);
|
|
108285
|
+
const message = await notice;
|
|
108286
|
+
if (message) io.stderr(message);
|
|
108287
|
+
return code;
|
|
108288
|
+
}
|
|
108289
|
+
async function checkForUpdate(options = {}) {
|
|
108290
|
+
const env = options.env ?? process.env;
|
|
108291
|
+
const argv = options.argv ?? process.argv.slice(2);
|
|
108292
|
+
if (!(options.stderrIsTTY ?? process.stderr.isTTY) || argv.includes("--json") || argv[0] === "mcp" && argv[1] !== "install" || env.VAPI_NO_UPDATE_CHECK === "1" || env.CI !== void 0) {
|
|
108293
|
+
return void 0;
|
|
108294
|
+
}
|
|
108295
|
+
const controller = new AbortController();
|
|
108296
|
+
let timer;
|
|
108297
|
+
try {
|
|
108298
|
+
return await Promise.race([
|
|
108299
|
+
latestNotice(options, env, controller.signal),
|
|
108300
|
+
new Promise((resolve2) => {
|
|
108301
|
+
timer = setTimeout(() => {
|
|
108302
|
+
controller.abort();
|
|
108303
|
+
resolve2(void 0);
|
|
108304
|
+
}, CHECK_TIMEOUT_MS);
|
|
108305
|
+
})
|
|
108306
|
+
]);
|
|
108307
|
+
} catch {
|
|
108308
|
+
return void 0;
|
|
108309
|
+
} finally {
|
|
108310
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
108311
|
+
controller.abort();
|
|
108312
|
+
}
|
|
108313
|
+
}
|
|
108314
|
+
async function latestNotice(options, env, signal) {
|
|
108315
|
+
const paths = getVapiPaths(options.home ?? (env.VAPI_HOME?.trim() || void 0));
|
|
108316
|
+
const now = (options.nowMs ?? Date.now)();
|
|
108317
|
+
let cached2;
|
|
108318
|
+
try {
|
|
108319
|
+
const value = JSON.parse(await readFile29(paths.updateCheck, "utf8"));
|
|
108320
|
+
if (isRecord12(value) && typeof value.checkedAt === "number" && Number.isFinite(value.checkedAt) && typeof value.latest === "string" && parseVersion(value.latest)) {
|
|
108321
|
+
cached2 = { checkedAt: value.checkedAt, latest: value.latest };
|
|
108322
|
+
}
|
|
108323
|
+
} catch {
|
|
108324
|
+
}
|
|
108325
|
+
signal.throwIfAborted();
|
|
108326
|
+
let latest = cached2?.latest ?? CLI_VERSION;
|
|
108327
|
+
if (cached2 === void 0 || now - cached2.checkedAt >= CHECK_INTERVAL_MS || now < cached2.checkedAt) {
|
|
108328
|
+
await mkdir21(paths.directory, { recursive: true });
|
|
108329
|
+
signal.throwIfAborted();
|
|
108330
|
+
await writeFile12(paths.updateCheck, JSON.stringify({ checkedAt: now, latest }), { mode: 384 });
|
|
108331
|
+
signal.throwIfAborted();
|
|
108332
|
+
const fetchImpl = options.fetchImpl ?? createPublicFetch({
|
|
108333
|
+
allowPrivateNetwork: false,
|
|
108334
|
+
lookup: async (hostname3) => {
|
|
108335
|
+
let onAbort;
|
|
108336
|
+
const aborted2 = new Promise((_resolve, reject) => {
|
|
108337
|
+
onAbort = () => reject(signal.reason);
|
|
108338
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
108339
|
+
});
|
|
108340
|
+
try {
|
|
108341
|
+
signal.throwIfAborted();
|
|
108342
|
+
const addresses = await Promise.race([lookup(hostname3, { all: true }), aborted2]);
|
|
108343
|
+
return addresses.map(({ address: address4 }) => address4);
|
|
108344
|
+
} finally {
|
|
108345
|
+
signal.removeEventListener("abort", onAbort);
|
|
108346
|
+
}
|
|
108347
|
+
}
|
|
108348
|
+
});
|
|
108349
|
+
const response = await fetchImpl(LATEST_URL, { signal, redirect: "error" });
|
|
108350
|
+
if (!response.ok) return void 0;
|
|
108351
|
+
const body = await response.json();
|
|
108352
|
+
signal.throwIfAborted();
|
|
108353
|
+
if (!isRecord12(body) || typeof body.version !== "string" || !parseVersion(body.version)) {
|
|
108354
|
+
return void 0;
|
|
108355
|
+
}
|
|
108356
|
+
latest = body.version;
|
|
108357
|
+
await writeFile12(paths.updateCheck, JSON.stringify({ checkedAt: now, latest }), { mode: 384 });
|
|
108358
|
+
}
|
|
108359
|
+
signal.throwIfAborted();
|
|
108360
|
+
return isNewerVersion(latest, CLI_VERSION) ? `vapi-network ${latest} is available (you have ${CLI_VERSION}). Update: npm i -g vapi-network@latest` : void 0;
|
|
108361
|
+
}
|
|
108362
|
+
function isRecord12(value) {
|
|
108363
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
108364
|
+
}
|
|
108365
|
+
function parseVersion(version5) {
|
|
108366
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([\da-zA-Z.-]+))?(?:\+[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?$/.exec(
|
|
108367
|
+
version5
|
|
108368
|
+
);
|
|
108369
|
+
if (!match) return void 0;
|
|
108370
|
+
const prerelease = match[4]?.split(".");
|
|
108371
|
+
if (prerelease?.some((part) => part === "" || /^\d+$/.test(part) && /^0\d/.test(part))) {
|
|
108372
|
+
return void 0;
|
|
108373
|
+
}
|
|
108374
|
+
return { core: match.slice(1, 4).map(BigInt), prerelease };
|
|
108375
|
+
}
|
|
108376
|
+
function isNewerVersion(latest, current) {
|
|
108377
|
+
const next = parseVersion(latest);
|
|
108378
|
+
const running = parseVersion(current);
|
|
108379
|
+
for (let index2 = 0; index2 < 3; index2 += 1) {
|
|
108380
|
+
if (next.core[index2] !== running.core[index2]) return next.core[index2] > running.core[index2];
|
|
108381
|
+
}
|
|
108382
|
+
if (running.prerelease === void 0) return false;
|
|
108383
|
+
if (next.prerelease === void 0) return true;
|
|
108384
|
+
for (let index2 = 0; index2 < Math.max(next.prerelease.length, running.prerelease.length); index2 += 1) {
|
|
108385
|
+
const a = next.prerelease[index2];
|
|
108386
|
+
const b = running.prerelease[index2];
|
|
108387
|
+
if (a === b) continue;
|
|
108388
|
+
if (a === void 0) return false;
|
|
108389
|
+
if (b === void 0) return true;
|
|
108390
|
+
const aNumeric = /^\d+$/.test(a);
|
|
108391
|
+
const bNumeric = /^\d+$/.test(b);
|
|
108392
|
+
if (aNumeric && bNumeric) return BigInt(a) > BigInt(b);
|
|
108393
|
+
if (aNumeric !== bNumeric) return !aNumeric;
|
|
108394
|
+
return a > b;
|
|
108395
|
+
}
|
|
108396
|
+
return false;
|
|
108397
|
+
}
|
|
108398
|
+
|
|
108024
108399
|
// src/main-module.ts
|
|
108025
108400
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
108026
108401
|
import { pathToFileURL } from "node:url";
|
|
@@ -108037,7 +108412,7 @@ function isMainModule(entry, moduleUrl, realpath = realpathSync2) {
|
|
|
108037
108412
|
|
|
108038
108413
|
// src/bin.ts
|
|
108039
108414
|
if (isMainModule(process.argv[1], import.meta.url)) {
|
|
108040
|
-
process.exitCode = await
|
|
108415
|
+
process.exitCode = await runCliWithUpdateCheck();
|
|
108041
108416
|
}
|
|
108042
108417
|
export {
|
|
108043
108418
|
CUSTODY_NOTICE,
|