@vapi-network/cli 0.2.1 → 0.2.3
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/brand.d.ts +55 -36
- package/dist/cli.d.ts +1 -6
- package/dist/cli.js +316 -153
- package/dist/cli.js.map +2 -2
- package/dist/index.js +316 -153
- package/dist/index.js.map +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -45333,8 +45333,8 @@ var DEFAULT_DISCOVERY_URL = `${DEFAULT_REGISTRY_URL}/api/call/services`;
|
|
|
45333
45333
|
var DEFAULT_MARKETPLACE_DISCOVERY_URL = `${DEFAULT_REGISTRY_URL}/api/call/discovery`;
|
|
45334
45334
|
var DEFAULT_REGISTRY_FALLBACKS = [
|
|
45335
45335
|
{
|
|
45336
|
-
discoveryUrl:
|
|
45337
|
-
marketplaceDiscoveryUrl:
|
|
45336
|
+
discoveryUrl: DEFAULT_DISCOVERY_URL,
|
|
45337
|
+
marketplaceDiscoveryUrl: DEFAULT_MARKETPLACE_DISCOVERY_URL
|
|
45338
45338
|
}
|
|
45339
45339
|
];
|
|
45340
45340
|
var DEFAULT_SPEND_CAPS = {
|
|
@@ -45439,6 +45439,83 @@ async function migrateLegacyVapiHome(options = {}) {
|
|
|
45439
45439
|
}
|
|
45440
45440
|
return copied;
|
|
45441
45441
|
}
|
|
45442
|
+
var LEGACY_REGISTRY_HOSTS = /* @__PURE__ */ new Map([
|
|
45443
|
+
["console.vapinetwork.ai", "api.vapinetwork.ai"],
|
|
45444
|
+
["console-staging.vapinetwork.ai", "api-staging.vapinetwork.ai"]
|
|
45445
|
+
]);
|
|
45446
|
+
var LEGACY_REGISTRY_PATHS = /* @__PURE__ */ new Map([
|
|
45447
|
+
["/api/network/services", "/api/call/services"],
|
|
45448
|
+
["/api/marketplace/discovery", "/api/call/discovery"]
|
|
45449
|
+
]);
|
|
45450
|
+
var REGISTRY_DOMAIN = "vapinetwork.ai";
|
|
45451
|
+
function rewriteLegacyRegistryUrl(value) {
|
|
45452
|
+
let url2;
|
|
45453
|
+
try {
|
|
45454
|
+
url2 = new URL(value);
|
|
45455
|
+
} catch {
|
|
45456
|
+
return value;
|
|
45457
|
+
}
|
|
45458
|
+
let rewritten = false;
|
|
45459
|
+
const host = LEGACY_REGISTRY_HOSTS.get(url2.hostname.toLowerCase());
|
|
45460
|
+
if (host) {
|
|
45461
|
+
url2.hostname = host;
|
|
45462
|
+
rewritten = true;
|
|
45463
|
+
}
|
|
45464
|
+
const hostname3 = url2.hostname.toLowerCase();
|
|
45465
|
+
if (hostname3 === REGISTRY_DOMAIN || hostname3.endsWith(`.${REGISTRY_DOMAIN}`)) {
|
|
45466
|
+
const path = LEGACY_REGISTRY_PATHS.get(url2.pathname.replace(/\/+$/, ""));
|
|
45467
|
+
if (path) {
|
|
45468
|
+
url2.pathname = path;
|
|
45469
|
+
rewritten = true;
|
|
45470
|
+
}
|
|
45471
|
+
}
|
|
45472
|
+
return rewritten ? url2.href : value;
|
|
45473
|
+
}
|
|
45474
|
+
function rewriteLegacyRegistryUrls(config2) {
|
|
45475
|
+
const changes = [];
|
|
45476
|
+
const rewrite = (field, from16) => {
|
|
45477
|
+
const to = rewriteLegacyRegistryUrl(from16);
|
|
45478
|
+
if (to !== from16) changes.push({ field, from: from16, to });
|
|
45479
|
+
return to;
|
|
45480
|
+
};
|
|
45481
|
+
const next = {
|
|
45482
|
+
...config2,
|
|
45483
|
+
discoveryUrl: rewrite("discoveryUrl", config2.discoveryUrl),
|
|
45484
|
+
marketplaceDiscoveryUrl: rewrite("marketplaceDiscoveryUrl", config2.marketplaceDiscoveryUrl),
|
|
45485
|
+
...config2.registryFallbacks ? {
|
|
45486
|
+
registryFallbacks: config2.registryFallbacks.map((fallback, index2) => ({
|
|
45487
|
+
discoveryUrl: rewrite(
|
|
45488
|
+
`registryFallbacks[${index2}].discoveryUrl`,
|
|
45489
|
+
fallback.discoveryUrl
|
|
45490
|
+
),
|
|
45491
|
+
marketplaceDiscoveryUrl: rewrite(
|
|
45492
|
+
`registryFallbacks[${index2}].marketplaceDiscoveryUrl`,
|
|
45493
|
+
fallback.marketplaceDiscoveryUrl
|
|
45494
|
+
)
|
|
45495
|
+
}))
|
|
45496
|
+
} : {}
|
|
45497
|
+
};
|
|
45498
|
+
return changes.length === 0 ? { config: config2, changes } : { config: next, changes };
|
|
45499
|
+
}
|
|
45500
|
+
function formatLegacyRegistryRewrites(changes) {
|
|
45501
|
+
return [
|
|
45502
|
+
"Rewrote retired vAPI registry URLs in the local config:",
|
|
45503
|
+
...changes.map((change) => ` ${change.field}: ${change.from} -> ${change.to}`)
|
|
45504
|
+
].join("\n");
|
|
45505
|
+
}
|
|
45506
|
+
async function migrateLegacyRegistryConfig(path = getVapiPaths().config) {
|
|
45507
|
+
let raw;
|
|
45508
|
+
try {
|
|
45509
|
+
raw = await readFile(path, "utf8");
|
|
45510
|
+
} catch (error61) {
|
|
45511
|
+
if (isMissingFile(error61)) return [];
|
|
45512
|
+
throw error61;
|
|
45513
|
+
}
|
|
45514
|
+
const { config: config2, changes } = rewriteLegacyRegistryUrls(configSchema.parse(JSON.parse(raw)));
|
|
45515
|
+
if (changes.length === 0) return [];
|
|
45516
|
+
await writeConfigFile(path, config2);
|
|
45517
|
+
return changes;
|
|
45518
|
+
}
|
|
45442
45519
|
function getDefaultConfig(source = process.env, options = {}) {
|
|
45443
45520
|
const registry2 = registryEndpoints(source.VAPI_REGISTRY_URL?.trim() || DEFAULT_REGISTRY_URL);
|
|
45444
45521
|
const requested = new Set(options.networks ?? ["base"]);
|
|
@@ -45477,7 +45554,7 @@ function getDefaultConfig(source = process.env, options = {}) {
|
|
|
45477
45554
|
spendCaps: { ...DEFAULT_SPEND_CAPS }
|
|
45478
45555
|
};
|
|
45479
45556
|
}
|
|
45480
|
-
async function loadConfig(path = getVapiPaths().config, source = process.env) {
|
|
45557
|
+
async function loadConfig(path = getVapiPaths().config, source = process.env, options = {}) {
|
|
45481
45558
|
if (!process.env.VAPI_HOME?.trim() && path === getVapiPaths(join(homedir(), ".vapi")).config) {
|
|
45482
45559
|
await migrateLegacyVapiHome({ targetDirectory: join(homedir(), ".vapi") });
|
|
45483
45560
|
}
|
|
@@ -45488,8 +45565,16 @@ async function loadConfig(path = getVapiPaths().config, source = process.env) {
|
|
|
45488
45565
|
if (isMissingFile(error61)) return getDefaultConfig(source);
|
|
45489
45566
|
throw error61;
|
|
45490
45567
|
}
|
|
45491
|
-
const
|
|
45492
|
-
|
|
45568
|
+
const parsed = configSchema.parse(JSON.parse(raw));
|
|
45569
|
+
parsed.registryFallbacks ??= DEFAULT_REGISTRY_FALLBACKS.map((fallback) => ({ ...fallback }));
|
|
45570
|
+
const migrated = rewriteLegacyRegistryUrls(parsed);
|
|
45571
|
+
const config2 = migrated.config;
|
|
45572
|
+
if (migrated.changes.length > 0 && options.notice) {
|
|
45573
|
+
options.notice(
|
|
45574
|
+
`${formatLegacyRegistryRewrites(migrated.changes)}
|
|
45575
|
+
Run vapi init to write the new URLs to ${path}.`
|
|
45576
|
+
);
|
|
45577
|
+
}
|
|
45493
45578
|
const baseRpcUrl = source.BASE_RPC_URL?.trim();
|
|
45494
45579
|
const arcRpcUrl = source.ARC_TESTNET_RPC_URL?.trim();
|
|
45495
45580
|
const solanaRpcUrl = source.SOLANA_RPC_URL?.trim();
|
|
@@ -45545,15 +45630,7 @@ async function writeDefaultConfig(path = getVapiPaths().config, source = process
|
|
|
45545
45630
|
if (copied.includes(path)) return await loadConfig(path, source);
|
|
45546
45631
|
}
|
|
45547
45632
|
const config2 = getDefaultConfig(source, options);
|
|
45548
|
-
await
|
|
45549
|
-
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
45550
|
-
await writeFile(temporaryPath, `${JSON.stringify(config2, null, 2)}
|
|
45551
|
-
`, {
|
|
45552
|
-
encoding: "utf8",
|
|
45553
|
-
mode: 384,
|
|
45554
|
-
flag: "wx"
|
|
45555
|
-
});
|
|
45556
|
-
await rename(temporaryPath, path);
|
|
45633
|
+
await writeConfigFile(path, config2);
|
|
45557
45634
|
return config2;
|
|
45558
45635
|
}
|
|
45559
45636
|
async function enableDefaultNetwork(network, path = getVapiPaths().config, source = process.env) {
|
|
@@ -45564,6 +45641,10 @@ async function enableDefaultNetwork(network, path = getVapiPaths().config, sourc
|
|
|
45564
45641
|
usdc: NETWORKS[SOLANA_MAINNET_CAIP2].usdc
|
|
45565
45642
|
};
|
|
45566
45643
|
}
|
|
45644
|
+
await writeConfigFile(path, config2);
|
|
45645
|
+
return config2;
|
|
45646
|
+
}
|
|
45647
|
+
async function writeConfigFile(path, config2) {
|
|
45567
45648
|
await mkdir(dirname(path), { recursive: true, mode: 448 });
|
|
45568
45649
|
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
45569
45650
|
await writeFile(temporaryPath, `${JSON.stringify(config2, null, 2)}
|
|
@@ -45573,7 +45654,6 @@ async function enableDefaultNetwork(network, path = getVapiPaths().config, sourc
|
|
|
45573
45654
|
flag: "wx"
|
|
45574
45655
|
});
|
|
45575
45656
|
await rename(temporaryPath, path);
|
|
45576
|
-
return config2;
|
|
45577
45657
|
}
|
|
45578
45658
|
async function pathExists(path) {
|
|
45579
45659
|
try {
|
|
@@ -45994,6 +46074,49 @@ async function unlockKeystore(passphrase, path = getVapiPaths().keystore) {
|
|
|
45994
46074
|
}
|
|
45995
46075
|
return await paymentAccountFromKeys(keys);
|
|
45996
46076
|
}
|
|
46077
|
+
async function readKeystoreAddress(path = getVapiPaths().keystore) {
|
|
46078
|
+
let raw;
|
|
46079
|
+
try {
|
|
46080
|
+
raw = await readFile3(path, "utf8");
|
|
46081
|
+
} catch {
|
|
46082
|
+
return void 0;
|
|
46083
|
+
}
|
|
46084
|
+
let parsed;
|
|
46085
|
+
try {
|
|
46086
|
+
parsed = JSON.parse(raw);
|
|
46087
|
+
} catch {
|
|
46088
|
+
return void 0;
|
|
46089
|
+
}
|
|
46090
|
+
const address2 = typeof parsed === "object" && parsed !== null ? Reflect.get(parsed, "address") : void 0;
|
|
46091
|
+
return typeof address2 === "string" ? address2 : void 0;
|
|
46092
|
+
}
|
|
46093
|
+
async function exportKeystoreKeys(passphrase, path = getVapiPaths().keystore) {
|
|
46094
|
+
let raw;
|
|
46095
|
+
try {
|
|
46096
|
+
raw = await readFile3(path, "utf8");
|
|
46097
|
+
} catch (error61) {
|
|
46098
|
+
if (isMissingFile(error61)) {
|
|
46099
|
+
throw new KeystoreError(`No vAPI keystore found at ${path}. Run vapi init.`);
|
|
46100
|
+
}
|
|
46101
|
+
throw error61;
|
|
46102
|
+
}
|
|
46103
|
+
const keys = await decryptKeys(parseAnyKeystore(JSON.parse(raw)), passphrase);
|
|
46104
|
+
const evmPrivateKey = keys.evm;
|
|
46105
|
+
const exported = {
|
|
46106
|
+
evm: { address: privateKeyToAccount(evmPrivateKey).address, privateKey: evmPrivateKey }
|
|
46107
|
+
};
|
|
46108
|
+
if (!keys.solana) return exported;
|
|
46109
|
+
const seed = Uint8Array.from(Buffer.from(keys.solana, "base64"));
|
|
46110
|
+
const signer = await createSolanaSigner(Uint8Array.from(seed));
|
|
46111
|
+
const publicKey = Uint8Array.from(getBase58Encoder().encode(signer.address));
|
|
46112
|
+
const secretKey = new Uint8Array(seed.length + publicKey.length);
|
|
46113
|
+
secretKey.set(seed);
|
|
46114
|
+
secretKey.set(publicKey, seed.length);
|
|
46115
|
+
const encoded = getBase58Decoder().decode(secretKey);
|
|
46116
|
+
seed.fill(0);
|
|
46117
|
+
secretKey.fill(0);
|
|
46118
|
+
return { ...exported, solana: { address: signer.address, secretKey: encoded } };
|
|
46119
|
+
}
|
|
45997
46120
|
async function enableSolanaKey(passphrase, path = getVapiPaths().keystore) {
|
|
45998
46121
|
let raw;
|
|
45999
46122
|
try {
|
|
@@ -46673,7 +46796,7 @@ function csvCell(value) {
|
|
|
46673
46796
|
import { mkdir as mkdir6, writeFile as writeFile4 } from "node:fs/promises";
|
|
46674
46797
|
import { arch, platform, release } from "node:os";
|
|
46675
46798
|
import { join as join2 } from "node:path";
|
|
46676
|
-
var VAPI_CLIENT_VERSION = "0.2.
|
|
46799
|
+
var VAPI_CLIENT_VERSION = "0.2.3";
|
|
46677
46800
|
async function createSupportReport(options) {
|
|
46678
46801
|
const message = options.message.trim();
|
|
46679
46802
|
if (!message) throw new Error("Support report message must not be empty.");
|
|
@@ -48807,132 +48930,122 @@ function asRecord(value) {
|
|
|
48807
48930
|
var MARK_SOURCE_WIDTH = 743;
|
|
48808
48931
|
var MARK_SOURCE_HEIGHT = 659;
|
|
48809
48932
|
var MARK_SOURCE_ROW_HEIGHT = 217;
|
|
48810
|
-
var MARK_COLUMNS =
|
|
48811
|
-
var MARK_ROWS =
|
|
48812
|
-
var
|
|
48813
|
-
var MARK_STEP_MS = 70;
|
|
48933
|
+
var MARK_COLUMNS = 21;
|
|
48934
|
+
var MARK_ROWS = 9;
|
|
48935
|
+
var BLOCK = "\u2588";
|
|
48814
48936
|
var WORDMARK = "vAPI Network";
|
|
48815
48937
|
var WELCOME = "Welcome to the vAPI Network";
|
|
48816
48938
|
var TAGLINE = [
|
|
48817
|
-
"The trusted network where agents
|
|
48818
|
-
"
|
|
48939
|
+
"The trusted network where agents",
|
|
48940
|
+
"and humans do business.",
|
|
48941
|
+
"",
|
|
48942
|
+
"Search APIs, pay per call, keep",
|
|
48943
|
+
"receipts. More coming soon."
|
|
48819
48944
|
];
|
|
48820
|
-
var ESC =
|
|
48945
|
+
var ESC = String.fromCharCode(27);
|
|
48821
48946
|
var RESET = `${ESC}[0m`;
|
|
48822
|
-
var REVERSE = `${ESC}[7m`;
|
|
48823
48947
|
var BOLD = `${ESC}[1m`;
|
|
48824
48948
|
var DIM = `${ESC}[2m`;
|
|
48825
|
-
var
|
|
48826
|
-
var SHOW_CURSOR = `${ESC}[?25h`;
|
|
48949
|
+
var DEFAULT_FOREGROUND = `${ESC}[39m`;
|
|
48827
48950
|
var MARK_PALETTE = {
|
|
48828
|
-
orange: "#ff7300",
|
|
48829
|
-
pink: "#ff337c",
|
|
48830
|
-
lime: "#c3ff3d",
|
|
48831
|
-
cyan: "#97efff",
|
|
48832
|
-
blue: "#0041eb",
|
|
48833
|
-
purple: "#8a37fb",
|
|
48951
|
+
orange: { hex: "#ff7300", ansi16: 33 },
|
|
48952
|
+
pink: { hex: "#ff337c", ansi16: 95 },
|
|
48953
|
+
lime: { hex: "#c3ff3d", ansi16: 92 },
|
|
48954
|
+
cyan: { hex: "#97efff", ansi16: 96 },
|
|
48955
|
+
blue: { hex: "#0041eb", ansi16: 34 },
|
|
48956
|
+
purple: { hex: "#8a37fb", ansi16: 35 },
|
|
48834
48957
|
ink: null
|
|
48835
48958
|
};
|
|
48836
48959
|
var MARK_BLOCKS = [
|
|
48837
|
-
{ row: 0, x: 2, width: 90, color: "orange"
|
|
48838
|
-
{ row: 0, x: 94, width: 35, color: "pink"
|
|
48839
|
-
{ row: 0, x: 131, width: 16, color: "lime"
|
|
48840
|
-
{ row: 0, x: 522, width: 219, color: "ink"
|
|
48841
|
-
{ row: 1, x: 124, width: 50, color: "cyan"
|
|
48842
|
-
{ row: 1, x: 176, width: 24, color: "blue"
|
|
48843
|
-
{ row: 1, x: 202, width: 17, color: "purple"
|
|
48844
|
-
{ row: 1, x: 402, width: 219, color: "blue"
|
|
48845
|
-
{ row: 2, x: 282, width: 219, color: "ink"
|
|
48960
|
+
{ row: 0, x: 2, width: 90, color: "orange" },
|
|
48961
|
+
{ row: 0, x: 94, width: 35, color: "pink" },
|
|
48962
|
+
{ row: 0, x: 131, width: 16, color: "lime" },
|
|
48963
|
+
{ row: 0, x: 522, width: 219, color: "ink" },
|
|
48964
|
+
{ row: 1, x: 124, width: 50, color: "cyan" },
|
|
48965
|
+
{ row: 1, x: 176, width: 24, color: "blue" },
|
|
48966
|
+
{ row: 1, x: 202, width: 17, color: "purple" },
|
|
48967
|
+
{ row: 1, x: 402, width: 219, color: "blue" },
|
|
48968
|
+
{ row: 2, x: 282, width: 219, color: "ink" }
|
|
48846
48969
|
];
|
|
48847
|
-
function
|
|
48970
|
+
function detectColorLevel(environment = {}) {
|
|
48848
48971
|
const env = environment.env ?? process.env;
|
|
48849
48972
|
const isTty = environment.isTty ?? Boolean(process.stdout.isTTY);
|
|
48850
|
-
|
|
48851
|
-
|
|
48852
|
-
|
|
48853
|
-
|
|
48854
|
-
|
|
48855
|
-
|
|
48856
|
-
|
|
48857
|
-
}
|
|
48858
|
-
function renderMarkFrames(options = {}) {
|
|
48859
|
-
const steps = [...new Set(MARK_BLOCKS.map((block) => block.delay))].sort(
|
|
48860
|
-
(left, right) => left - right
|
|
48861
|
-
);
|
|
48862
|
-
return steps.map(
|
|
48863
|
-
(step) => renderFrame(
|
|
48864
|
-
MARK_BLOCKS.filter((block) => block.delay <= step),
|
|
48865
|
-
options.color === true
|
|
48866
|
-
)
|
|
48867
|
-
);
|
|
48868
|
-
}
|
|
48869
|
-
function renderBanner(options) {
|
|
48870
|
-
const frames = renderMarkFrames(options);
|
|
48871
|
-
return renderBox(frames[frames.length - 1], options).join("\n");
|
|
48872
|
-
}
|
|
48873
|
-
async function animateBanner(options) {
|
|
48874
|
-
const frames = renderMarkFrames({ color: options.color !== false });
|
|
48875
|
-
const sleep = options.sleep ?? defaultSleep;
|
|
48876
|
-
const stepMs = options.stepMs ?? MARK_STEP_MS;
|
|
48877
|
-
const boxes = frames.map((frame) => renderBox(frame, options));
|
|
48878
|
-
const height = boxes[0].length;
|
|
48879
|
-
options.write(HIDE_CURSOR);
|
|
48880
|
-
try {
|
|
48881
|
-
for (const [index2, box] of boxes.entries()) {
|
|
48882
|
-
if (index2 > 0) options.write(`${ESC}[${height}A`);
|
|
48883
|
-
options.write(box.map((line) => `\r${ESC}[2K${line}
|
|
48884
|
-
`).join(""));
|
|
48885
|
-
if (index2 < boxes.length - 1) await sleep(stepMs);
|
|
48886
|
-
}
|
|
48887
|
-
} finally {
|
|
48888
|
-
options.write(SHOW_CURSOR);
|
|
48889
|
-
}
|
|
48890
|
-
}
|
|
48891
|
-
function renderBox(frame, options) {
|
|
48892
|
-
const color = options.color === true;
|
|
48893
|
-
const text = [
|
|
48894
|
-
{ value: WELCOME, style: BOLD },
|
|
48895
|
-
{ value: "", style: "" },
|
|
48896
|
-
...TAGLINE.map((line) => ({ value: line, style: "" })),
|
|
48897
|
-
{ value: "", style: "" },
|
|
48898
|
-
{ value: `${WORDMARK} v${options.version}`, style: DIM }
|
|
48899
|
-
];
|
|
48900
|
-
const textWidth = Math.max(...text.map((line) => line.value.length));
|
|
48901
|
-
const gap = 3;
|
|
48902
|
-
const inner = 2 + MARK_COLUMNS + gap + textWidth + 2;
|
|
48903
|
-
const markLines = frame.split("\n");
|
|
48904
|
-
const textTop = Math.floor((MARK_ROWS - text.length) / 2);
|
|
48905
|
-
const lines = [];
|
|
48906
|
-
lines.push(`\u256D${"\u2500".repeat(inner)}\u256E`);
|
|
48907
|
-
lines.push(`\u2502${" ".repeat(inner)}\u2502`);
|
|
48908
|
-
for (let row = 0; row < MARK_ROWS; row += 1) {
|
|
48909
|
-
const mark = markLines[row] ?? "";
|
|
48910
|
-
const markPad = " ".repeat(Math.max(0, MARK_COLUMNS - visibleLength(mark)));
|
|
48911
|
-
const entry = text[row - textTop];
|
|
48912
|
-
const raw = entry?.value ?? "";
|
|
48913
|
-
const styled = color && entry && entry.style && raw ? `${entry.style}${raw}${RESET}` : raw;
|
|
48914
|
-
const textPad = " ".repeat(textWidth - raw.length);
|
|
48915
|
-
lines.push(`\u2502 ${mark}${markPad}${" ".repeat(gap)}${styled}${textPad} \u2502`);
|
|
48973
|
+
if (env.NO_COLOR) return 0;
|
|
48974
|
+
const forced = env.FORCE_COLOR;
|
|
48975
|
+
if (forced !== void 0) {
|
|
48976
|
+
if (forced === "0" || forced === "false") return 0;
|
|
48977
|
+
if (forced === "2") return 2;
|
|
48978
|
+
if (forced === "3") return 3;
|
|
48979
|
+
return 1;
|
|
48916
48980
|
}
|
|
48917
|
-
|
|
48918
|
-
|
|
48919
|
-
|
|
48920
|
-
|
|
48921
|
-
|
|
48981
|
+
if (!isTty) return 0;
|
|
48982
|
+
const term = env.TERM ?? "";
|
|
48983
|
+
const program = env.TERM_PROGRAM ?? "";
|
|
48984
|
+
if (term === "dumb") return 0;
|
|
48985
|
+
if (/^(truecolor|24bit)$/i.test(env.COLORTERM ?? "")) return 3;
|
|
48986
|
+
if (/kitty|wezterm|ghostty|alacritty/i.test(term)) return 3;
|
|
48987
|
+
if (/^(iTerm\.app|vscode|Hyper|WezTerm|ghostty)$/i.test(program)) return 3;
|
|
48988
|
+
if (/-256(?:color)?$/i.test(term) || program === "Apple_Terminal") return 2;
|
|
48989
|
+
return 1;
|
|
48990
|
+
}
|
|
48991
|
+
function renderMark(colorLevel = 0) {
|
|
48922
48992
|
const rows = [];
|
|
48923
48993
|
for (let row = 0; row < MARK_ROWS; row += 1) {
|
|
48924
48994
|
const sourceY = row * MARK_SOURCE_HEIGHT / MARK_ROWS;
|
|
48925
48995
|
const band = Math.min(2, Math.floor(sourceY / MARK_SOURCE_ROW_HEIGHT));
|
|
48926
48996
|
rows.push(
|
|
48927
48997
|
renderRow(
|
|
48928
|
-
|
|
48929
|
-
|
|
48998
|
+
MARK_BLOCKS.filter((block) => block.row === band),
|
|
48999
|
+
colorLevel
|
|
48930
49000
|
)
|
|
48931
49001
|
);
|
|
48932
49002
|
}
|
|
48933
49003
|
return rows.join("\n");
|
|
48934
49004
|
}
|
|
48935
|
-
function
|
|
49005
|
+
function bannerWidth() {
|
|
49006
|
+
return frameInnerWidth() + 2;
|
|
49007
|
+
}
|
|
49008
|
+
function renderBanner(options) {
|
|
49009
|
+
const colorLevel = options.colorLevel ?? 0;
|
|
49010
|
+
const columns = options.columns ?? Number.POSITIVE_INFINITY;
|
|
49011
|
+
const text = bannerText(options.version, colorLevel);
|
|
49012
|
+
if (columns < bannerWidth()) {
|
|
49013
|
+
return text.map((line) => line.styled).join("\n");
|
|
49014
|
+
}
|
|
49015
|
+
const inner = frameInnerWidth();
|
|
49016
|
+
const markLines = renderMark(colorLevel).split("\n");
|
|
49017
|
+
const lines = [];
|
|
49018
|
+
lines.push(`\u256D${"\u2500".repeat(inner)}\u256E`);
|
|
49019
|
+
lines.push(`\u2502${" ".repeat(inner)}\u2502`);
|
|
49020
|
+
for (let row = 0; row < MARK_ROWS; row += 1) {
|
|
49021
|
+
const entry = text[row];
|
|
49022
|
+
const value = entry?.value ?? "";
|
|
49023
|
+
const styled = entry?.styled ?? "";
|
|
49024
|
+
const pad4 = " ".repeat(TEXT_WIDTH - value.length);
|
|
49025
|
+
lines.push(`\u2502 ${markLines[row]}${" ".repeat(GAP)}${styled}${pad4} \u2502`);
|
|
49026
|
+
}
|
|
49027
|
+
lines.push(`\u2502${" ".repeat(inner)}\u2502`);
|
|
49028
|
+
lines.push(`\u2570${"\u2500".repeat(inner)}\u256F`);
|
|
49029
|
+
return lines.join("\n");
|
|
49030
|
+
}
|
|
49031
|
+
var GAP = 3;
|
|
49032
|
+
var TEXT_WIDTH = Math.max(WELCOME.length, ...TAGLINE.map((line) => line.length));
|
|
49033
|
+
function frameInnerWidth() {
|
|
49034
|
+
return 2 + MARK_COLUMNS + GAP + TEXT_WIDTH + 2;
|
|
49035
|
+
}
|
|
49036
|
+
function bannerText(version5, colorLevel) {
|
|
49037
|
+
const style = (value, code) => colorLevel > 0 && value ? `${code}${value}${RESET}` : value;
|
|
49038
|
+
const rows = [
|
|
49039
|
+
{ value: WELCOME, styled: style(WELCOME, BOLD) },
|
|
49040
|
+
{ value: "", styled: "" },
|
|
49041
|
+
...TAGLINE.map((line) => ({ value: line, styled: line })),
|
|
49042
|
+
{ value: "", styled: "" },
|
|
49043
|
+
{ value: `${WORDMARK} v${version5}`, styled: style(`${WORDMARK} v${version5}`, DIM) }
|
|
49044
|
+
];
|
|
49045
|
+
if (rows.length > MARK_ROWS) throw new Error("banner text is taller than the mark");
|
|
49046
|
+
return rows;
|
|
49047
|
+
}
|
|
49048
|
+
function renderRow(blocks, colorLevel) {
|
|
48936
49049
|
const ordered = [...blocks].sort((left, right) => left.x - right.x);
|
|
48937
49050
|
let column = 0;
|
|
48938
49051
|
let line = "";
|
|
@@ -48943,7 +49056,8 @@ function renderRow(blocks, color) {
|
|
|
48943
49056
|
column = start;
|
|
48944
49057
|
}
|
|
48945
49058
|
const width = scaleWidth(block.width);
|
|
48946
|
-
|
|
49059
|
+
const cells = BLOCK.repeat(width);
|
|
49060
|
+
line += colorLevel > 0 ? `${foreground(block.color, colorLevel)}${cells}${RESET}` : cells;
|
|
48947
49061
|
column += width;
|
|
48948
49062
|
}
|
|
48949
49063
|
return line + " ".repeat(Math.max(0, MARK_COLUMNS - column));
|
|
@@ -48954,23 +49068,28 @@ function scaleColumn(x) {
|
|
|
48954
49068
|
function scaleWidth(width) {
|
|
48955
49069
|
return Math.max(1, Math.round(width * MARK_COLUMNS / MARK_SOURCE_WIDTH));
|
|
48956
49070
|
}
|
|
48957
|
-
function
|
|
48958
|
-
const
|
|
48959
|
-
if (
|
|
48960
|
-
const value = Number.parseInt(
|
|
48961
|
-
|
|
48962
|
-
|
|
48963
|
-
|
|
48964
|
-
|
|
49071
|
+
function foreground(color, colorLevel) {
|
|
49072
|
+
const entry = MARK_PALETTE[color];
|
|
49073
|
+
if (entry === null) return DEFAULT_FOREGROUND;
|
|
49074
|
+
const value = Number.parseInt(entry.hex.slice(1), 16);
|
|
49075
|
+
const red = value >> 16 & 255;
|
|
49076
|
+
const green = value >> 8 & 255;
|
|
49077
|
+
const blue = value & 255;
|
|
49078
|
+
if (colorLevel === 3) return `${ESC}[38;2;${red};${green};${blue}m`;
|
|
49079
|
+
if (colorLevel === 2) return `${ESC}[38;5;${rgbToAnsi256(red, green, blue)}m`;
|
|
49080
|
+
return `${ESC}[${entry.ansi16}m`;
|
|
48965
49081
|
}
|
|
48966
|
-
function
|
|
48967
|
-
|
|
48968
|
-
|
|
48969
|
-
|
|
49082
|
+
function rgbToAnsi256(red, green, blue) {
|
|
49083
|
+
if (red === green && green === blue) {
|
|
49084
|
+
if (red < 8) return 16;
|
|
49085
|
+
if (red > 248) return 231;
|
|
49086
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
49087
|
+
}
|
|
49088
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
48970
49089
|
}
|
|
48971
49090
|
|
|
48972
49091
|
// src/version.ts
|
|
48973
|
-
var CLI_VERSION = "0.2.
|
|
49092
|
+
var CLI_VERSION = "0.2.3";
|
|
48974
49093
|
|
|
48975
49094
|
// src/cli.ts
|
|
48976
49095
|
var HELP_HEADING = "vAPI Network";
|
|
@@ -48988,6 +49107,7 @@ Usage:
|
|
|
48988
49107
|
vapi receipts export --format <json|csv> [--range <24h|7d|30d>]
|
|
48989
49108
|
vapi stats [--range <24h|7d|30d>] [--json]
|
|
48990
49109
|
vapi sweep <address> [--network <caip2>] [--json]
|
|
49110
|
+
vapi export-key [--network <caip2>] [--json]
|
|
48991
49111
|
vapi report "<what happened>" [--include-addresses] [--send] [--json]
|
|
48992
49112
|
vapi mcp [--json]
|
|
48993
49113
|
vapi serve [--json]
|
|
@@ -48999,8 +49119,7 @@ var processIo = {
|
|
|
48999
49119
|
stdout: (message) => process.stdout.write(`${message}
|
|
49000
49120
|
`),
|
|
49001
49121
|
stderr: (message) => process.stderr.write(`${message}
|
|
49002
|
-
`)
|
|
49003
|
-
write: (chunk) => process.stdout.write(chunk)
|
|
49122
|
+
`)
|
|
49004
49123
|
};
|
|
49005
49124
|
var UsageError = class extends Error {
|
|
49006
49125
|
};
|
|
@@ -49019,7 +49138,7 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
|
|
|
49019
49138
|
if (command === void 0 || command === "help" || command === "--help" || command === "-h") {
|
|
49020
49139
|
requireNoArguments(args.slice(command === void 0 ? 0 : 1), command ?? "help");
|
|
49021
49140
|
if (command === void 0 && !json2) {
|
|
49022
|
-
io
|
|
49141
|
+
showBanner(io);
|
|
49023
49142
|
io.stdout(HELP.slice(HELP_HEADING.length + 2));
|
|
49024
49143
|
return 0;
|
|
49025
49144
|
}
|
|
@@ -49057,6 +49176,9 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
|
|
|
49057
49176
|
case "sweep":
|
|
49058
49177
|
await sweepCommand(args.slice(1), json2, io);
|
|
49059
49178
|
return 0;
|
|
49179
|
+
case "export-key":
|
|
49180
|
+
await exportKeyCommand(args.slice(1), json2, io);
|
|
49181
|
+
return 0;
|
|
49060
49182
|
case "report":
|
|
49061
49183
|
await reportCommand(args.slice(1), json2, io, dependencies);
|
|
49062
49184
|
return 0;
|
|
@@ -49090,14 +49212,24 @@ async function initCommand(argv, json2, io, dependencies) {
|
|
|
49090
49212
|
});
|
|
49091
49213
|
const networks = parseInitNetworks(parsed.one("--networks") ?? "base");
|
|
49092
49214
|
const enableSolana = networks.includes("solana");
|
|
49093
|
-
if (!json2)
|
|
49215
|
+
if (!json2) showBanner(io);
|
|
49094
49216
|
const paths = getVapiPaths();
|
|
49095
49217
|
let migrated = [];
|
|
49096
49218
|
if (!process.env.VAPI_HOME?.trim()) {
|
|
49097
49219
|
migrated = await migrateLegacyVapiHome({ targetDirectory: paths.directory, notice: io.stderr });
|
|
49098
49220
|
}
|
|
49221
|
+
const adopted = migrated.includes(paths.keystore);
|
|
49222
|
+
if (!adopted && await fileExists(paths.keystore)) {
|
|
49223
|
+
const address2 = await readKeystoreAddress(paths.keystore);
|
|
49224
|
+
throw new Error(
|
|
49225
|
+
[
|
|
49226
|
+
`Keystore already exists at ${paths.keystore}. Refusing to replace the local payment key.`,
|
|
49227
|
+
...address2 ? [`Address: ${address2}`] : []
|
|
49228
|
+
].join("\n")
|
|
49229
|
+
);
|
|
49230
|
+
}
|
|
49099
49231
|
const passphrase = await getKeystorePassphrase({ confirm: true });
|
|
49100
|
-
let account =
|
|
49232
|
+
let account = adopted ? await unlockKeystore(passphrase, paths.keystore) : await createKeystore(passphrase, paths.keystore, { enableSolana });
|
|
49101
49233
|
if (enableSolana && !account.solana) {
|
|
49102
49234
|
account = await enableSolanaKey(passphrase, paths.keystore);
|
|
49103
49235
|
}
|
|
@@ -49106,7 +49238,8 @@ async function initCommand(argv, json2, io, dependencies) {
|
|
|
49106
49238
|
} else if (enableSolana) {
|
|
49107
49239
|
await enableDefaultNetwork("solana", paths.config);
|
|
49108
49240
|
}
|
|
49109
|
-
const
|
|
49241
|
+
const configRewrites = await migrateLegacyRegistryConfig(paths.config);
|
|
49242
|
+
const config2 = await readConfig(paths.config, io);
|
|
49110
49243
|
const accounts = await listAccounts({
|
|
49111
49244
|
address: account.address,
|
|
49112
49245
|
...account.solana ? { solanaAddress: account.solana.address } : {},
|
|
@@ -49118,6 +49251,7 @@ async function initCommand(argv, json2, io, dependencies) {
|
|
|
49118
49251
|
accounts,
|
|
49119
49252
|
config: paths.config,
|
|
49120
49253
|
keystore: paths.keystore,
|
|
49254
|
+
...configRewrites.length > 0 ? { configRewrites } : {},
|
|
49121
49255
|
message: "vAPI wallet created. Its encrypted key stays on this machine.",
|
|
49122
49256
|
nextSteps: buildNextSteps(account.address)
|
|
49123
49257
|
};
|
|
@@ -49125,6 +49259,7 @@ async function initCommand(argv, json2, io, dependencies) {
|
|
|
49125
49259
|
io.stdout(JSON.stringify(result));
|
|
49126
49260
|
return;
|
|
49127
49261
|
}
|
|
49262
|
+
if (configRewrites.length > 0) io.stdout(formatLegacyRegistryRewrites(configRewrites));
|
|
49128
49263
|
io.stdout(result.message);
|
|
49129
49264
|
io.stdout(`Address: ${result.address}`);
|
|
49130
49265
|
io.stdout(
|
|
@@ -49149,7 +49284,7 @@ async function fundCommand(argv, json2, io, dependencies) {
|
|
|
49149
49284
|
});
|
|
49150
49285
|
const fiatAmount = optionalUsdAmount(parsed.one("--amount"), "--amount");
|
|
49151
49286
|
const paths = getVapiPaths();
|
|
49152
|
-
const config2 = await
|
|
49287
|
+
const config2 = await readConfig(paths.config, io);
|
|
49153
49288
|
const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
|
|
49154
49289
|
const session = await createOnrampSession({
|
|
49155
49290
|
address: account.address,
|
|
@@ -49169,7 +49304,7 @@ async function searchCommand(argv, json2, io, dependencies) {
|
|
|
49169
49304
|
maximumPositionals: 1
|
|
49170
49305
|
});
|
|
49171
49306
|
const limit = optionalPositiveInteger(parsed.one("--limit"), "--limit");
|
|
49172
|
-
const config2 = await
|
|
49307
|
+
const config2 = await readConfig(getVapiPaths().config, io);
|
|
49173
49308
|
const page = await searchMarketplace(
|
|
49174
49309
|
{
|
|
49175
49310
|
...parsed.positionals[0] ? { query: parsed.positionals[0] } : {},
|
|
@@ -49193,7 +49328,7 @@ async function inspectCommand(argv, json2, io, dependencies) {
|
|
|
49193
49328
|
parsed.positionals[0],
|
|
49194
49329
|
"Usage: vapi inspect <id> [--endpoint <name>]"
|
|
49195
49330
|
);
|
|
49196
|
-
const config2 = await
|
|
49331
|
+
const config2 = await readConfig(getVapiPaths().config, io);
|
|
49197
49332
|
const result = await inspectService(
|
|
49198
49333
|
{ id, ...parsed.one("--endpoint") ? { endpoint: parsed.one("--endpoint") } : {} },
|
|
49199
49334
|
config2,
|
|
@@ -49217,7 +49352,7 @@ async function payCommand(argv, json2, io) {
|
|
|
49217
49352
|
});
|
|
49218
49353
|
const target = requiredPositional(parsed.positionals[0], "Usage: vapi pay <id-or-url> [options]");
|
|
49219
49354
|
const paths = getVapiPaths();
|
|
49220
|
-
const config2 = await
|
|
49355
|
+
const config2 = await readConfig(paths.config, io);
|
|
49221
49356
|
const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
|
|
49222
49357
|
const bodyText = parsed.one("--body");
|
|
49223
49358
|
const maxPriceUsd = aliasedOption(parsed, "--max", "--max-price-usd");
|
|
@@ -49243,7 +49378,7 @@ async function payCommand(argv, json2, io) {
|
|
|
49243
49378
|
async function balanceCommand(argv, json2, io, dependencies) {
|
|
49244
49379
|
requireNoArguments(argv, "balance");
|
|
49245
49380
|
const paths = getVapiPaths();
|
|
49246
|
-
const config2 = await
|
|
49381
|
+
const config2 = await readConfig(paths.config, io);
|
|
49247
49382
|
const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
|
|
49248
49383
|
const wallet = await getWallet(account, config2, dependencies);
|
|
49249
49384
|
output2(io, json2, wallet, formatWallet(wallet));
|
|
@@ -49261,7 +49396,7 @@ async function accountsCommand(argv, json2, io, dependencies) {
|
|
|
49261
49396
|
const passphrase = await getKeystorePassphrase();
|
|
49262
49397
|
const account = enable ? await enableSolanaKey(passphrase, paths.keystore) : await unlockKeystore(passphrase, paths.keystore);
|
|
49263
49398
|
if (enable) await enableDefaultNetwork("solana", paths.config);
|
|
49264
|
-
const config2 = await
|
|
49399
|
+
const config2 = await readConfig(paths.config, io);
|
|
49265
49400
|
const accounts = await listAccounts({
|
|
49266
49401
|
address: account.address,
|
|
49267
49402
|
...account.solana ? { solanaAddress: account.solana.address } : {},
|
|
@@ -49330,7 +49465,7 @@ async function sweepCommand(argv, json2, io) {
|
|
|
49330
49465
|
);
|
|
49331
49466
|
const requestedNetwork = parsed.one("--network");
|
|
49332
49467
|
const paths = getVapiPaths();
|
|
49333
|
-
const config2 = await
|
|
49468
|
+
const config2 = await readConfig(paths.config, io);
|
|
49334
49469
|
const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
|
|
49335
49470
|
if (requestedNetwork && !isNetworkConfigured(config2.networks, requestedNetwork)) {
|
|
49336
49471
|
throw new Error(`Network ${requestedNetwork} is not configured.`);
|
|
@@ -49374,6 +49509,33 @@ async function reportCommand(argv, json2, io, dependencies) {
|
|
|
49374
49509
|
});
|
|
49375
49510
|
output2(io, json2, result, formatSupportReport(result));
|
|
49376
49511
|
}
|
|
49512
|
+
var EXPORT_KEY_WARNING = "Anyone with this key can spend the wallet. Never paste it into a website or chat.";
|
|
49513
|
+
async function exportKeyCommand(argv, json2, io) {
|
|
49514
|
+
const parsed = parseArguments(argv, {
|
|
49515
|
+
valueOptions: /* @__PURE__ */ new Set(["--network"]),
|
|
49516
|
+
maximumPositionals: 0
|
|
49517
|
+
});
|
|
49518
|
+
const network = parsed.one("--network") ?? BASE_MAINNET_CAIP2;
|
|
49519
|
+
const solana = isSolanaNetwork(network);
|
|
49520
|
+
if (!solana && !network.startsWith("eip155:")) {
|
|
49521
|
+
throw new UsageError("--network must be an eip155:<chainId> or Solana network identifier.");
|
|
49522
|
+
}
|
|
49523
|
+
const paths = getVapiPaths();
|
|
49524
|
+
const keys = await exportKeystoreKeys(await getKeystorePassphrase(), paths.keystore);
|
|
49525
|
+
if (solana && !keys.solana) {
|
|
49526
|
+
throw new Error(
|
|
49527
|
+
`No Solana key is enabled in ${paths.keystore}. Run vapi accounts --enable solana first.`
|
|
49528
|
+
);
|
|
49529
|
+
}
|
|
49530
|
+
const selected = solana && keys.solana ? keys.solana : keys.evm;
|
|
49531
|
+
const result = {
|
|
49532
|
+
network,
|
|
49533
|
+
address: selected.address,
|
|
49534
|
+
privateKey: "secretKey" in selected ? selected.secretKey : selected.privateKey
|
|
49535
|
+
};
|
|
49536
|
+
io.stderr(EXPORT_KEY_WARNING);
|
|
49537
|
+
io.stdout(json2 ? JSON.stringify(result) : result.privateKey);
|
|
49538
|
+
}
|
|
49377
49539
|
async function mcpCommand(argv) {
|
|
49378
49540
|
requireNoArguments(argv, "mcp");
|
|
49379
49541
|
const paths = getVapiPaths();
|
|
@@ -49387,6 +49549,9 @@ async function mcpCommand(argv) {
|
|
|
49387
49549
|
searchesPath: paths.searches
|
|
49388
49550
|
});
|
|
49389
49551
|
}
|
|
49552
|
+
async function readConfig(path, io) {
|
|
49553
|
+
return await loadConfig(path, process.env, { notice: io.stderr });
|
|
49554
|
+
}
|
|
49390
49555
|
function output2(io, json2, value, human) {
|
|
49391
49556
|
io.stdout(json2 ? JSON.stringify(value) : human);
|
|
49392
49557
|
}
|
|
@@ -49452,16 +49617,14 @@ function formatNextStep(label, value, note) {
|
|
|
49452
49617
|
const step = `${label.padEnd(10)}${value}`;
|
|
49453
49618
|
return note === void 0 ? step : `${step.padEnd(52)} ${note}`;
|
|
49454
49619
|
}
|
|
49455
|
-
|
|
49456
|
-
|
|
49457
|
-
|
|
49458
|
-
|
|
49459
|
-
|
|
49460
|
-
|
|
49461
|
-
|
|
49462
|
-
|
|
49463
|
-
function staticBanner() {
|
|
49464
|
-
return renderBanner({ version: CLI_VERSION, color: markColorEnabled() });
|
|
49620
|
+
function showBanner(io) {
|
|
49621
|
+
io.stdout(
|
|
49622
|
+
renderBanner({
|
|
49623
|
+
version: CLI_VERSION,
|
|
49624
|
+
colorLevel: detectColorLevel(),
|
|
49625
|
+
columns: process.stdout.columns
|
|
49626
|
+
})
|
|
49627
|
+
);
|
|
49465
49628
|
}
|
|
49466
49629
|
function formatAccounts(accounts) {
|
|
49467
49630
|
if (accounts.length === 0) return "No configured network accounts.";
|