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