@vapi-network/core 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/account-add.d.ts +8 -1
- package/dist/account-add.d.ts.map +1 -1
- package/dist/account-movement-lock.d.ts +10 -0
- package/dist/account-movement-lock.d.ts.map +1 -0
- package/dist/agent-link.d.ts +1 -0
- package/dist/agent-link.d.ts.map +1 -1
- package/dist/agent-link.js +21 -10
- package/dist/agent-link.js.map +1 -1
- package/dist/agent-profile.d.ts +14 -2
- package/dist/agent-profile.d.ts.map +1 -1
- package/dist/agent-run.d.ts +12 -0
- package/dist/agent-run.d.ts.map +1 -0
- package/dist/allocation.d.ts +35 -4
- package/dist/allocation.d.ts.map +1 -1
- package/dist/api-key.js.map +1 -1
- package/dist/atomic-file.d.ts +23 -0
- package/dist/atomic-file.d.ts.map +1 -0
- package/dist/audit.d.ts +4 -1
- package/dist/audit.d.ts.map +1 -1
- package/dist/backup.d.ts +153 -32
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +2535 -139
- package/dist/backup.js.map +3 -3
- package/dist/call-contracts-wire.d.ts +12 -12
- package/dist/ceiling.d.ts +8 -0
- package/dist/ceiling.d.ts.map +1 -1
- package/dist/cloud-backup.d.ts +8 -10
- package/dist/cloud-backup.d.ts.map +1 -1
- package/dist/cloud-backup.js +2806 -381
- package/dist/cloud-backup.js.map +3 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/distribute.d.ts +9 -1
- package/dist/distribute.d.ts.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5206 -1270
- package/dist/index.js.map +3 -3
- package/dist/marketplace-contracts.d.ts +14 -14
- package/dist/member-bundle.d.ts +110 -0
- package/dist/member-bundle.d.ts.map +1 -0
- package/dist/movement-open.d.ts +10 -0
- package/dist/movement-open.d.ts.map +1 -0
- package/dist/movement.d.ts +77 -7
- package/dist/movement.d.ts.map +1 -1
- package/dist/receipts.d.ts +9 -0
- package/dist/receipts.d.ts.map +1 -1
- package/dist/router-client.d.ts +9 -1
- package/dist/router-client.d.ts.map +1 -1
- package/dist/router-client.js +2073 -607
- package/dist/router-client.js.map +3 -3
- package/dist/run-budget.d.ts +17 -0
- package/dist/run-budget.d.ts.map +1 -0
- package/dist/secret-store.d.ts +6 -0
- package/dist/secret-store.d.ts.map +1 -1
- package/dist/secrets.d.ts +2 -1
- package/dist/secrets.d.ts.map +1 -1
- package/dist/secrets.js +884 -48
- package/dist/secrets.js.map +3 -3
- package/dist/support-report.d.ts +1 -1
- package/dist/swarm-capital.d.ts +147 -0
- package/dist/swarm-capital.d.ts.map +1 -0
- package/dist/swarm.d.ts +224 -0
- package/dist/swarm.d.ts.map +1 -0
- package/dist/transfer-journal.d.ts +11 -0
- package/dist/transfer-journal.d.ts.map +1 -0
- package/dist/transfer.d.ts +4 -1
- package/dist/transfer.d.ts.map +1 -1
- package/dist/vault.d.ts +11 -0
- package/dist/vault.d.ts.map +1 -1
- package/dist/wallet-store.d.ts +19 -8
- package/dist/wallet-store.d.ts.map +1 -1
- package/dist/x402-pay.d.ts +7 -0
- package/dist/x402-pay.d.ts.map +1 -1
- package/dist/x402.d.ts +3 -0
- package/dist/x402.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/secrets.js
CHANGED
|
@@ -2212,7 +2212,7 @@ function weierstrass(curveDef) {
|
|
|
2212
2212
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
|
2213
2213
|
if (["recovered", "canonical"].some((k) => k in opts))
|
|
2214
2214
|
throw new Error("sign() legacy options not supported");
|
|
2215
|
-
const { hash: hash2, randomBytes:
|
|
2215
|
+
const { hash: hash2, randomBytes: randomBytes5 } = CURVE;
|
|
2216
2216
|
let { lowS, prehash, extraEntropy: ent } = opts;
|
|
2217
2217
|
if (lowS == null)
|
|
2218
2218
|
lowS = true;
|
|
@@ -2224,7 +2224,7 @@ function weierstrass(curveDef) {
|
|
|
2224
2224
|
const d = normPrivateKeyToScalar(privateKey);
|
|
2225
2225
|
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
2226
2226
|
if (ent != null && ent !== false) {
|
|
2227
|
-
const e2 = ent === true ?
|
|
2227
|
+
const e2 = ent === true ? randomBytes5(Fp.BYTES) : ent;
|
|
2228
2228
|
seedArgs.push(ensureBytes("extraEntropy", e2));
|
|
2229
2229
|
}
|
|
2230
2230
|
const seed = concatBytes2(...seedArgs);
|
|
@@ -2793,16 +2793,16 @@ function hexToBytes3(hex_, opts = {}) {
|
|
|
2793
2793
|
assertSize(hex3, { size: opts.size });
|
|
2794
2794
|
hex3 = pad(hex3, { dir: "right", size: opts.size });
|
|
2795
2795
|
}
|
|
2796
|
-
let
|
|
2797
|
-
if (
|
|
2798
|
-
|
|
2799
|
-
const length =
|
|
2796
|
+
let hexString2 = hex3.slice(2);
|
|
2797
|
+
if (hexString2.length % 2)
|
|
2798
|
+
hexString2 = `0${hexString2}`;
|
|
2799
|
+
const length = hexString2.length / 2;
|
|
2800
2800
|
const bytes = new Uint8Array(length);
|
|
2801
2801
|
for (let index = 0, j = 0; index < length; index++) {
|
|
2802
|
-
const nibbleLeft = charCodeToBase16(
|
|
2803
|
-
const nibbleRight = charCodeToBase16(
|
|
2802
|
+
const nibbleLeft = charCodeToBase16(hexString2.charCodeAt(j++));
|
|
2803
|
+
const nibbleRight = charCodeToBase16(hexString2.charCodeAt(j++));
|
|
2804
2804
|
if (nibbleLeft === void 0 || nibbleRight === void 0) {
|
|
2805
|
-
throw new BaseError(`Invalid byte sequence ("${
|
|
2805
|
+
throw new BaseError(`Invalid byte sequence ("${hexString2[j - 2]}${hexString2[j - 1]}" in "${hexString2}").`);
|
|
2806
2806
|
}
|
|
2807
2807
|
bytes[index] = nibbleLeft * 16 + nibbleRight;
|
|
2808
2808
|
}
|
|
@@ -4273,9 +4273,9 @@ var init_stringify = __esm({
|
|
|
4273
4273
|
});
|
|
4274
4274
|
|
|
4275
4275
|
// src/keystore.ts
|
|
4276
|
-
import { createCipheriv, createDecipheriv, randomBytes as
|
|
4277
|
-
import { mkdir as
|
|
4278
|
-
import { dirname as
|
|
4276
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes3, scrypt } from "node:crypto";
|
|
4277
|
+
import { mkdir as mkdir3, readFile as readFile3, rename as rename3, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
4278
|
+
import { dirname as dirname3 } from "node:path";
|
|
4279
4279
|
|
|
4280
4280
|
// ../../node_modules/.pnpm/@solana+errors@5.5.1_typescript@6.0.3/node_modules/@solana/errors/dist/index.node.mjs
|
|
4281
4281
|
var SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED = 1;
|
|
@@ -46542,13 +46542,232 @@ function date4(params) {
|
|
|
46542
46542
|
|
|
46543
46543
|
// src/config.ts
|
|
46544
46544
|
import { constants } from "node:fs";
|
|
46545
|
-
import { copyFile, mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
46545
|
+
import { copyFile, mkdir as mkdir2, readFile as readFile2, rename as rename2, stat as stat2, writeFile } from "node:fs/promises";
|
|
46546
46546
|
import { homedir } from "node:os";
|
|
46547
|
-
import { dirname, join as
|
|
46547
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
46548
46548
|
|
|
46549
46549
|
// ../../node_modules/.pnpm/viem@2.56.1_typescript@6.0.3_zod@4.5.4/node_modules/viem/_esm/index.js
|
|
46550
46550
|
init_getAddress();
|
|
46551
46551
|
|
|
46552
|
+
// src/atomic-file.ts
|
|
46553
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
46554
|
+
import { link, mkdir, open as open2, readdir, readFile, rename, stat, unlink } from "node:fs/promises";
|
|
46555
|
+
import { basename, dirname, join as join2 } from "node:path";
|
|
46556
|
+
var DEFAULT_LOCK_TIMEOUT_MS = 2e3;
|
|
46557
|
+
var LOCK_RETRY_MS = 20;
|
|
46558
|
+
var LOCK_STALE_AFTER_MS = 12e4;
|
|
46559
|
+
var LOCK_HEARTBEAT_MS = 3e4;
|
|
46560
|
+
var atomicFileTestHooks;
|
|
46561
|
+
var FileLockedError = class extends Error {
|
|
46562
|
+
constructor(message = "Timed out waiting for the file lock.") {
|
|
46563
|
+
super(message);
|
|
46564
|
+
this.name = "FileLockedError";
|
|
46565
|
+
}
|
|
46566
|
+
};
|
|
46567
|
+
async function withFileLock(lockPath, fn, options = {}) {
|
|
46568
|
+
await mkdir(dirname(lockPath), { recursive: true, mode: 448 });
|
|
46569
|
+
const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS);
|
|
46570
|
+
const ownerRecord = {
|
|
46571
|
+
pid: process.pid,
|
|
46572
|
+
token: randomBytes2(16).toString("hex")
|
|
46573
|
+
};
|
|
46574
|
+
const owner = JSON.stringify(ownerRecord);
|
|
46575
|
+
const releasedOwner = JSON.stringify({ ...ownerRecord, released: true });
|
|
46576
|
+
let handle;
|
|
46577
|
+
while (handle === void 0) {
|
|
46578
|
+
await atomicFileTestHooks?.beforeLockAttempt?.(lockPath);
|
|
46579
|
+
try {
|
|
46580
|
+
const candidate = await open2(lockPath, "wx", 384);
|
|
46581
|
+
try {
|
|
46582
|
+
await candidate.writeFile(owner, "utf8");
|
|
46583
|
+
await candidate.sync();
|
|
46584
|
+
await atomicFileTestHooks?.afterLockCreate?.(lockPath);
|
|
46585
|
+
if (await lockTakeoverInProgress(lockPath)) {
|
|
46586
|
+
await candidate.close();
|
|
46587
|
+
await removeOwnedLock(lockPath, [owner]);
|
|
46588
|
+
await removeAbandonedLockTombs(lockPath);
|
|
46589
|
+
if (Date.now() >= deadline) {
|
|
46590
|
+
throw new FileLockedError(options.lockedMessage);
|
|
46591
|
+
}
|
|
46592
|
+
await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
|
|
46593
|
+
continue;
|
|
46594
|
+
}
|
|
46595
|
+
handle = candidate;
|
|
46596
|
+
} catch (error61) {
|
|
46597
|
+
await candidate.close().catch(() => void 0);
|
|
46598
|
+
await removeOwnedLock(lockPath, [owner]).catch(() => void 0);
|
|
46599
|
+
throw error61;
|
|
46600
|
+
}
|
|
46601
|
+
} catch (error61) {
|
|
46602
|
+
if (!hasCode(error61, "EEXIST")) throw error61;
|
|
46603
|
+
await removeStaleLock(lockPath);
|
|
46604
|
+
if (Date.now() >= deadline) {
|
|
46605
|
+
throw new FileLockedError(options.lockedMessage);
|
|
46606
|
+
}
|
|
46607
|
+
await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
|
|
46608
|
+
}
|
|
46609
|
+
}
|
|
46610
|
+
const ownedHandle = handle;
|
|
46611
|
+
const heartbeat = setInterval(() => {
|
|
46612
|
+
const time3 = /* @__PURE__ */ new Date();
|
|
46613
|
+
void ownedHandle.utimes(time3, time3).catch(() => void 0);
|
|
46614
|
+
}, LOCK_HEARTBEAT_MS);
|
|
46615
|
+
heartbeat.unref();
|
|
46616
|
+
try {
|
|
46617
|
+
return await fn();
|
|
46618
|
+
} finally {
|
|
46619
|
+
clearInterval(heartbeat);
|
|
46620
|
+
try {
|
|
46621
|
+
await markLockReleased(ownedHandle, releasedOwner);
|
|
46622
|
+
} finally {
|
|
46623
|
+
try {
|
|
46624
|
+
await ownedHandle.close();
|
|
46625
|
+
} finally {
|
|
46626
|
+
await removeOwnedLock(lockPath, [owner, releasedOwner]);
|
|
46627
|
+
}
|
|
46628
|
+
}
|
|
46629
|
+
}
|
|
46630
|
+
}
|
|
46631
|
+
async function removeStaleLock(path) {
|
|
46632
|
+
try {
|
|
46633
|
+
const owner = await readFile(path, "utf8");
|
|
46634
|
+
if (lockOwnerReleased(owner)) {
|
|
46635
|
+
await removeOwnedLock(path, [owner]);
|
|
46636
|
+
return;
|
|
46637
|
+
}
|
|
46638
|
+
const metadata = await stat(path);
|
|
46639
|
+
if (Date.now() - metadata.mtimeMs <= LOCK_STALE_AFTER_MS) return;
|
|
46640
|
+
const pid = lockOwnerPid(owner);
|
|
46641
|
+
if (pid !== void 0 && processIsAlive(pid)) return;
|
|
46642
|
+
await atomicFileTestHooks?.beforeStaleLockBreak?.(path);
|
|
46643
|
+
await removeOwnedLock(path, [owner]);
|
|
46644
|
+
} catch (error61) {
|
|
46645
|
+
if (!hasCode(error61, "ENOENT")) throw error61;
|
|
46646
|
+
}
|
|
46647
|
+
}
|
|
46648
|
+
async function removeOwnedLock(path, owners) {
|
|
46649
|
+
const tombPath = `${path}.stale.${randomBytes2(16).toString("hex")}`;
|
|
46650
|
+
try {
|
|
46651
|
+
await rename(path, tombPath);
|
|
46652
|
+
} catch (error61) {
|
|
46653
|
+
if (hasCode(error61, "ENOENT")) {
|
|
46654
|
+
await removeOwnedTombs(path, owners);
|
|
46655
|
+
const currentOwner = await readFile(path, "utf8").catch(() => void 0);
|
|
46656
|
+
if (currentOwner !== void 0 && owners.includes(currentOwner)) {
|
|
46657
|
+
await removeOwnedLock(path, owners);
|
|
46658
|
+
}
|
|
46659
|
+
return;
|
|
46660
|
+
}
|
|
46661
|
+
throw error61;
|
|
46662
|
+
}
|
|
46663
|
+
let pendingError;
|
|
46664
|
+
try {
|
|
46665
|
+
const renamedOwner = await readFile(tombPath, "utf8");
|
|
46666
|
+
if (!owners.includes(renamedOwner) && !lockOwnerReleased(renamedOwner)) {
|
|
46667
|
+
await atomicFileTestHooks?.afterMismatchedLockRename?.(path);
|
|
46668
|
+
const currentOwner = await readFile(tombPath, "utf8");
|
|
46669
|
+
if (!lockOwnerReleased(currentOwner)) await restoreRenamedLock(path, tombPath);
|
|
46670
|
+
await atomicFileTestHooks?.afterMismatchedLockRestore?.(path);
|
|
46671
|
+
}
|
|
46672
|
+
} catch (error61) {
|
|
46673
|
+
pendingError = error61;
|
|
46674
|
+
}
|
|
46675
|
+
try {
|
|
46676
|
+
await unlink(tombPath);
|
|
46677
|
+
} catch (error61) {
|
|
46678
|
+
if (!hasCode(error61, "ENOENT") && pendingError === void 0) {
|
|
46679
|
+
pendingError = error61;
|
|
46680
|
+
}
|
|
46681
|
+
}
|
|
46682
|
+
if (pendingError !== void 0) throw pendingError;
|
|
46683
|
+
}
|
|
46684
|
+
async function lockTakeoverInProgress(path) {
|
|
46685
|
+
const prefix = `${basename(path)}.stale.`;
|
|
46686
|
+
return (await readdir(dirname(path))).some((entry) => entry.startsWith(prefix));
|
|
46687
|
+
}
|
|
46688
|
+
async function removeAbandonedLockTombs(path) {
|
|
46689
|
+
const directory = dirname(path);
|
|
46690
|
+
const prefix = `${basename(path)}.stale.`;
|
|
46691
|
+
for (const entry of await readdir(directory)) {
|
|
46692
|
+
if (!entry.startsWith(prefix)) continue;
|
|
46693
|
+
const tombPath = join2(directory, entry);
|
|
46694
|
+
const [metadata, owner] = await Promise.all([
|
|
46695
|
+
stat(tombPath).catch(() => void 0),
|
|
46696
|
+
readFile(tombPath, "utf8").catch(() => void 0)
|
|
46697
|
+
]);
|
|
46698
|
+
if (metadata === void 0 || owner === void 0) continue;
|
|
46699
|
+
const pid = lockOwnerPid(owner);
|
|
46700
|
+
const abandoned = lockOwnerReleased(owner) || Date.now() - metadata.mtimeMs > LOCK_STALE_AFTER_MS && (pid === void 0 || !processIsAlive(pid));
|
|
46701
|
+
if (!abandoned) continue;
|
|
46702
|
+
await unlink(tombPath).catch((error61) => {
|
|
46703
|
+
if (!hasCode(error61, "ENOENT")) throw error61;
|
|
46704
|
+
});
|
|
46705
|
+
}
|
|
46706
|
+
}
|
|
46707
|
+
async function removeOwnedTombs(path, owners) {
|
|
46708
|
+
const directory = dirname(path);
|
|
46709
|
+
const prefix = `${basename(path)}.stale.`;
|
|
46710
|
+
for (const entry of await readdir(directory)) {
|
|
46711
|
+
if (!entry.startsWith(prefix)) continue;
|
|
46712
|
+
const tombPath = join2(directory, entry);
|
|
46713
|
+
const owner = await readFile(tombPath, "utf8").catch(() => void 0);
|
|
46714
|
+
if (owner === void 0 || !owners.includes(owner)) continue;
|
|
46715
|
+
await unlink(tombPath).catch((error61) => {
|
|
46716
|
+
if (!hasCode(error61, "ENOENT")) throw error61;
|
|
46717
|
+
});
|
|
46718
|
+
}
|
|
46719
|
+
}
|
|
46720
|
+
async function restoreRenamedLock(path, tombPath) {
|
|
46721
|
+
while (true) {
|
|
46722
|
+
try {
|
|
46723
|
+
await link(tombPath, path);
|
|
46724
|
+
return;
|
|
46725
|
+
} catch (error61) {
|
|
46726
|
+
if (hasCode(error61, "ENOENT")) return;
|
|
46727
|
+
if (!hasCode(error61, "EEXIST")) throw error61;
|
|
46728
|
+
await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
|
|
46729
|
+
}
|
|
46730
|
+
}
|
|
46731
|
+
}
|
|
46732
|
+
async function markLockReleased(handle, owner) {
|
|
46733
|
+
const contents = Buffer.from(owner, "utf8");
|
|
46734
|
+
await handle.write(contents, 0, contents.length, 0);
|
|
46735
|
+
await handle.truncate(contents.length);
|
|
46736
|
+
await handle.sync();
|
|
46737
|
+
}
|
|
46738
|
+
function lockOwnerPid(owner) {
|
|
46739
|
+
try {
|
|
46740
|
+
const value = JSON.parse(owner);
|
|
46741
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
46742
|
+
const pid = Reflect.get(value, "pid");
|
|
46743
|
+
return typeof pid === "number" && Number.isSafeInteger(pid) && pid > 0 ? pid : void 0;
|
|
46744
|
+
} catch {
|
|
46745
|
+
return void 0;
|
|
46746
|
+
}
|
|
46747
|
+
}
|
|
46748
|
+
function lockOwnerReleased(owner) {
|
|
46749
|
+
try {
|
|
46750
|
+
const value = JSON.parse(owner);
|
|
46751
|
+
return typeof value === "object" && value !== null && Reflect.get(value, "released") === true;
|
|
46752
|
+
} catch {
|
|
46753
|
+
return false;
|
|
46754
|
+
}
|
|
46755
|
+
}
|
|
46756
|
+
function processIsAlive(pid) {
|
|
46757
|
+
if (atomicFileTestHooks?.isProcessAlive !== void 0) {
|
|
46758
|
+
return atomicFileTestHooks.isProcessAlive(pid);
|
|
46759
|
+
}
|
|
46760
|
+
try {
|
|
46761
|
+
process.kill(pid, 0);
|
|
46762
|
+
return true;
|
|
46763
|
+
} catch (error61) {
|
|
46764
|
+
return hasCode(error61, "EPERM");
|
|
46765
|
+
}
|
|
46766
|
+
}
|
|
46767
|
+
function hasCode(error61, code) {
|
|
46768
|
+
return error61 instanceof Error && "code" in error61 && error61.code === code;
|
|
46769
|
+
}
|
|
46770
|
+
|
|
46552
46771
|
// src/x402-networks.ts
|
|
46553
46772
|
var BASE_MAINNET_CAIP2 = "eip155:8453";
|
|
46554
46773
|
var ARC_MAINNET_CAIP2 = "eip155:5042";
|
|
@@ -46592,6 +46811,205 @@ var BROWSER_ENABLED_X402_NETWORK_CONFIG = Object.freeze({
|
|
|
46592
46811
|
[ARC_TESTNET_CAIP2]: browserNetwork(arcTestnetUsdc)
|
|
46593
46812
|
});
|
|
46594
46813
|
|
|
46814
|
+
// src/net-guard.ts
|
|
46815
|
+
import { lookup as dnsLookup } from "node:dns/promises";
|
|
46816
|
+
import { request as httpRequest } from "node:http";
|
|
46817
|
+
import { request as httpsRequest } from "node:https";
|
|
46818
|
+
import { isIP } from "node:net";
|
|
46819
|
+
import { Readable } from "node:stream";
|
|
46820
|
+
var defaultLookup = async (hostname3) => {
|
|
46821
|
+
const addresses = await dnsLookup(hostname3, { all: true });
|
|
46822
|
+
return addresses.map(({ address }) => address);
|
|
46823
|
+
};
|
|
46824
|
+
async function assertPublicUrl(url2, options) {
|
|
46825
|
+
if (url2.username || url2.password) {
|
|
46826
|
+
throw guardError(url2);
|
|
46827
|
+
}
|
|
46828
|
+
if (url2.protocol !== "http:" && url2.protocol !== "https:") {
|
|
46829
|
+
throw guardError(url2);
|
|
46830
|
+
}
|
|
46831
|
+
if (options.allowPrivateNetwork) {
|
|
46832
|
+
return;
|
|
46833
|
+
}
|
|
46834
|
+
const hostname3 = normalizeHostname(url2.hostname);
|
|
46835
|
+
const lowercaseHostname = hostname3.toLowerCase();
|
|
46836
|
+
if (!lowercaseHostname || lowercaseHostname === "localhost" || lowercaseHostname.endsWith(".localhost") || lowercaseHostname.endsWith(".local") || lowercaseHostname.endsWith(".internal")) {
|
|
46837
|
+
throw guardError(url2);
|
|
46838
|
+
}
|
|
46839
|
+
if (isIP(hostname3)) {
|
|
46840
|
+
if (isNonPublicAddress(hostname3)) {
|
|
46841
|
+
throw guardError(url2);
|
|
46842
|
+
}
|
|
46843
|
+
return;
|
|
46844
|
+
}
|
|
46845
|
+
let addresses;
|
|
46846
|
+
try {
|
|
46847
|
+
addresses = await withTimeout(
|
|
46848
|
+
(options.lookup ?? defaultLookup)(hostname3),
|
|
46849
|
+
options.timeoutMs ?? 5e3
|
|
46850
|
+
);
|
|
46851
|
+
} catch {
|
|
46852
|
+
throw guardError(url2);
|
|
46853
|
+
}
|
|
46854
|
+
if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
|
|
46855
|
+
throw guardError(url2);
|
|
46856
|
+
}
|
|
46857
|
+
}
|
|
46858
|
+
function createPublicFetch(options) {
|
|
46859
|
+
const lookupFn = options.lookup ?? defaultLookup;
|
|
46860
|
+
return (async (input2, init) => {
|
|
46861
|
+
const url2 = new URL(input2 instanceof Request ? input2.url : input2);
|
|
46862
|
+
await assertPublicUrl(url2, {
|
|
46863
|
+
allowPrivateNetwork: options.allowPrivateNetwork,
|
|
46864
|
+
lookup: lookupFn,
|
|
46865
|
+
timeoutMs: 5e3
|
|
46866
|
+
});
|
|
46867
|
+
const normalized = new Request(input2, init);
|
|
46868
|
+
const bytes = normalized.body ? Buffer.from(await normalized.arrayBuffer()) : null;
|
|
46869
|
+
return await new Promise((resolve, reject) => {
|
|
46870
|
+
const requestOptions = {
|
|
46871
|
+
method: normalized.method,
|
|
46872
|
+
headers: Object.fromEntries(normalized.headers),
|
|
46873
|
+
signal: normalized.signal,
|
|
46874
|
+
...options.allowPrivateNetwork ? {} : { lookup: pinnedLookup(lookupFn) }
|
|
46875
|
+
};
|
|
46876
|
+
const onResponse = (incoming) => {
|
|
46877
|
+
try {
|
|
46878
|
+
const headers = new Headers();
|
|
46879
|
+
for (const [name, value] of Object.entries(incoming.headers)) {
|
|
46880
|
+
if (Array.isArray(value)) {
|
|
46881
|
+
for (const item of value) headers.append(name, item);
|
|
46882
|
+
} else if (value !== void 0) {
|
|
46883
|
+
headers.set(name, value);
|
|
46884
|
+
}
|
|
46885
|
+
}
|
|
46886
|
+
const status = incoming.statusCode ?? 500;
|
|
46887
|
+
const bodyForbidden = normalized.method === "HEAD" || [204, 205, 304].includes(status);
|
|
46888
|
+
if (bodyForbidden) incoming.resume();
|
|
46889
|
+
const response = new Response(
|
|
46890
|
+
bodyForbidden ? null : Readable.toWeb(incoming),
|
|
46891
|
+
{ status, statusText: incoming.statusMessage, headers }
|
|
46892
|
+
);
|
|
46893
|
+
Object.defineProperty(response, "url", { value: url2.toString() });
|
|
46894
|
+
resolve(response);
|
|
46895
|
+
} catch (error61) {
|
|
46896
|
+
incoming.destroy();
|
|
46897
|
+
reject(error61);
|
|
46898
|
+
}
|
|
46899
|
+
};
|
|
46900
|
+
const request = url2.protocol === "https:" ? httpsRequest(url2, requestOptions, onResponse) : httpRequest(url2, requestOptions, onResponse);
|
|
46901
|
+
request.on("error", reject);
|
|
46902
|
+
if (bytes) request.write(bytes);
|
|
46903
|
+
request.end();
|
|
46904
|
+
});
|
|
46905
|
+
});
|
|
46906
|
+
}
|
|
46907
|
+
function pinnedLookup(lookup) {
|
|
46908
|
+
return (hostname3, dnsOptions, callback) => {
|
|
46909
|
+
void lookup(normalizeHostname(hostname3)).then((addresses) => {
|
|
46910
|
+
if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
|
|
46911
|
+
callback(guardError(new URL(`https://${hostname3}`)), "");
|
|
46912
|
+
return;
|
|
46913
|
+
}
|
|
46914
|
+
const address = addresses[0];
|
|
46915
|
+
const family = isIP(address);
|
|
46916
|
+
callback(
|
|
46917
|
+
null,
|
|
46918
|
+
dnsOptions.all ? [{ address, family }] : address,
|
|
46919
|
+
dnsOptions.all ? void 0 : family
|
|
46920
|
+
);
|
|
46921
|
+
}).catch(
|
|
46922
|
+
(error61) => callback(error61 instanceof Error ? error61 : new Error("DNS lookup failed."), "")
|
|
46923
|
+
);
|
|
46924
|
+
};
|
|
46925
|
+
}
|
|
46926
|
+
async function withTimeout(operation, timeoutMs) {
|
|
46927
|
+
let timeout;
|
|
46928
|
+
try {
|
|
46929
|
+
return await Promise.race([
|
|
46930
|
+
operation,
|
|
46931
|
+
new Promise((_resolve, reject) => {
|
|
46932
|
+
timeout = setTimeout(() => reject(new Error("DNS lookup timed out.")), timeoutMs);
|
|
46933
|
+
})
|
|
46934
|
+
]);
|
|
46935
|
+
} finally {
|
|
46936
|
+
if (timeout) clearTimeout(timeout);
|
|
46937
|
+
}
|
|
46938
|
+
}
|
|
46939
|
+
function normalizeHostname(hostname3) {
|
|
46940
|
+
const unbracketed = hostname3.startsWith("[") && hostname3.endsWith("]") ? hostname3.slice(1, -1) : hostname3;
|
|
46941
|
+
return unbracketed.endsWith(".") ? unbracketed.slice(0, -1) : unbracketed;
|
|
46942
|
+
}
|
|
46943
|
+
function isNonPublicAddress(address) {
|
|
46944
|
+
const normalized = normalizeHostname(address);
|
|
46945
|
+
const version3 = isIP(normalized);
|
|
46946
|
+
if (version3 === 4) {
|
|
46947
|
+
return isNonPublicIpv4(parseIpv4(normalized));
|
|
46948
|
+
}
|
|
46949
|
+
if (version3 === 6) {
|
|
46950
|
+
return isNonPublicIpv6(parseIpv6(normalized));
|
|
46951
|
+
}
|
|
46952
|
+
return true;
|
|
46953
|
+
}
|
|
46954
|
+
function parseIpv4(address) {
|
|
46955
|
+
const octets = address.split(".").map(Number);
|
|
46956
|
+
return [octets[0], octets[1], octets[2], octets[3]];
|
|
46957
|
+
}
|
|
46958
|
+
function isNonPublicIpv4([first, second, third]) {
|
|
46959
|
+
return first === 0 || first === 10 || first === 100 && second >= 64 && second <= 127 || first === 127 || first === 169 && second === 254 || first === 172 && second >= 16 && second <= 31 || first === 192 && second === 0 && (third === 0 || third === 2) || first === 192 && second === 168 || first === 198 && second >= 18 && second <= 19 || first === 198 && second === 51 && third === 100 || first === 203 && second === 0 && third === 113 || first >= 224;
|
|
46960
|
+
}
|
|
46961
|
+
function parseIpv6(address) {
|
|
46962
|
+
let normalized = address.toLowerCase();
|
|
46963
|
+
const lastColon = normalized.lastIndexOf(":");
|
|
46964
|
+
const dottedTail = normalized.slice(lastColon + 1);
|
|
46965
|
+
if (dottedTail.includes(".")) {
|
|
46966
|
+
const [first, second, third, fourth] = parseIpv4(dottedTail);
|
|
46967
|
+
normalized = `${normalized.slice(0, lastColon + 1)}${(first << 8 | second).toString(16)}:${(third << 8 | fourth).toString(16)}`;
|
|
46968
|
+
}
|
|
46969
|
+
const halves = normalized.split("::");
|
|
46970
|
+
const left = halves[0] ? halves[0].split(":").map(parseHex) : [];
|
|
46971
|
+
const right = halves[1] ? halves[1].split(":").map(parseHex) : [];
|
|
46972
|
+
const omittedCount = 8 - left.length - right.length;
|
|
46973
|
+
return halves.length === 2 ? [...left, ...Array.from({ length: omittedCount }, () => 0), ...right] : left;
|
|
46974
|
+
}
|
|
46975
|
+
function parseHex(value) {
|
|
46976
|
+
return Number.parseInt(value, 16);
|
|
46977
|
+
}
|
|
46978
|
+
function isNonPublicIpv6(hextets) {
|
|
46979
|
+
if (hextets.slice(0, 5).every((hextet) => hextet === 0) && hextets[5] === 65535) {
|
|
46980
|
+
const embeddedIpv4 = [
|
|
46981
|
+
hextets[6] >> 8,
|
|
46982
|
+
hextets[6] & 255,
|
|
46983
|
+
hextets[7] >> 8,
|
|
46984
|
+
hextets[7] & 255
|
|
46985
|
+
];
|
|
46986
|
+
return isNonPublicIpv4(embeddedIpv4);
|
|
46987
|
+
}
|
|
46988
|
+
if (hextets.slice(0, 6).every((hextet) => hextet === 0)) {
|
|
46989
|
+
const compatibleIpv4 = [
|
|
46990
|
+
hextets[6] >> 8,
|
|
46991
|
+
hextets[6] & 255,
|
|
46992
|
+
hextets[7] >> 8,
|
|
46993
|
+
hextets[7] & 255
|
|
46994
|
+
];
|
|
46995
|
+
if (isNonPublicIpv4(compatibleIpv4)) return true;
|
|
46996
|
+
}
|
|
46997
|
+
const isUnspecified = hextets.every((hextet) => hextet === 0);
|
|
46998
|
+
const isLoopback = hextets.slice(0, 7).every((hextet) => hextet === 0) && hextets[7] === 1;
|
|
46999
|
+
const first = hextets[0];
|
|
47000
|
+
const isUniqueLocal = first >= 64512 && first <= 65023;
|
|
47001
|
+
const isLinkLocal = first >= 65152 && first <= 65215;
|
|
47002
|
+
const isSiteLocal = first >= 65216 && first <= 65279;
|
|
47003
|
+
const isMulticast = first >= 65280;
|
|
47004
|
+
const isDocumentation = first === 8193 && hextets[1] === 3512;
|
|
47005
|
+
return isUnspecified || isLoopback || isUniqueLocal || isLinkLocal || isSiteLocal || isMulticast || isDocumentation;
|
|
47006
|
+
}
|
|
47007
|
+
function guardError(url2) {
|
|
47008
|
+
return new Error(
|
|
47009
|
+
`URL hostname ${JSON.stringify(url2.hostname)} is not allowed; private or internal destinations require allowPrivateNetwork true in the vAPI config.`
|
|
47010
|
+
);
|
|
47011
|
+
}
|
|
47012
|
+
|
|
46595
47013
|
// src/networks.ts
|
|
46596
47014
|
var NETWORKS = {
|
|
46597
47015
|
[BASE_MAINNET_CAIP2]: {
|
|
@@ -46667,6 +47085,10 @@ function isSupportedPaymentNetwork(network) {
|
|
|
46667
47085
|
var DEFAULT_REGISTRY_URL = "https://api.vapinetwork.ai";
|
|
46668
47086
|
var DEFAULT_DISCOVERY_URL = `${DEFAULT_REGISTRY_URL}/api/call/services`;
|
|
46669
47087
|
var DEFAULT_MARKETPLACE_DISCOVERY_URL = `${DEFAULT_REGISTRY_URL}/api/call/discovery`;
|
|
47088
|
+
var DEFAULT_SPEND_CAPS = {
|
|
47089
|
+
perCallAtomic: "100000",
|
|
47090
|
+
perDayAtomic: "1000000"
|
|
47091
|
+
};
|
|
46670
47092
|
var atomicString = external_exports.string().regex(/^\d+$/, "Expected non-negative atomic units.");
|
|
46671
47093
|
var spendCapsSchema = external_exports.object({
|
|
46672
47094
|
perCallAtomic: atomicString,
|
|
@@ -46729,22 +47151,22 @@ var configSchema = external_exports.object({
|
|
|
46729
47151
|
}
|
|
46730
47152
|
}
|
|
46731
47153
|
});
|
|
46732
|
-
function getVapiPaths(directory = process.env.VAPI_HOME?.trim() ||
|
|
47154
|
+
function getVapiPaths(directory = process.env.VAPI_HOME?.trim() || join3(homedir(), ".vapi")) {
|
|
46733
47155
|
return {
|
|
46734
47156
|
directory,
|
|
46735
|
-
agentsDir:
|
|
46736
|
-
config:
|
|
46737
|
-
keystore:
|
|
46738
|
-
receipts:
|
|
46739
|
-
searches:
|
|
46740
|
-
ledger:
|
|
47157
|
+
agentsDir: join3(directory, "agents"),
|
|
47158
|
+
config: join3(directory, "config.json"),
|
|
47159
|
+
keystore: join3(directory, "keystore.json"),
|
|
47160
|
+
receipts: join3(directory, "receipts.jsonl"),
|
|
47161
|
+
searches: join3(directory, "searches.jsonl"),
|
|
47162
|
+
ledger: join3(directory, "spend-ledger.json")
|
|
46741
47163
|
};
|
|
46742
47164
|
}
|
|
46743
47165
|
async function migrateLegacyVapiHome(options = {}) {
|
|
46744
47166
|
const target = getVapiPaths(options.targetDirectory);
|
|
46745
|
-
const legacyDirectory = options.legacyDirectory ??
|
|
47167
|
+
const legacyDirectory = options.legacyDirectory ?? join3(homedir(), ".vapi", "agent-cash");
|
|
46746
47168
|
if (legacyDirectory === target.directory || !await pathExists(legacyDirectory)) return [];
|
|
46747
|
-
await
|
|
47169
|
+
await mkdir2(target.directory, { recursive: true, mode: 448 });
|
|
46748
47170
|
const copied = [];
|
|
46749
47171
|
for (const filename of [
|
|
46750
47172
|
"config.json",
|
|
@@ -46753,10 +47175,17 @@ async function migrateLegacyVapiHome(options = {}) {
|
|
|
46753
47175
|
"searches.jsonl",
|
|
46754
47176
|
"spend-ledger.json"
|
|
46755
47177
|
]) {
|
|
46756
|
-
const source =
|
|
46757
|
-
const destination =
|
|
47178
|
+
const source = join3(legacyDirectory, filename);
|
|
47179
|
+
const destination = join3(target.directory, filename);
|
|
46758
47180
|
try {
|
|
46759
|
-
await copyFile(source, destination, constants.COPYFILE_EXCL);
|
|
47181
|
+
const copy = async () => await copyFile(source, destination, constants.COPYFILE_EXCL);
|
|
47182
|
+
if (filename === "receipts.jsonl") {
|
|
47183
|
+
await withFileLock(`${destination}.lock`, copy, {
|
|
47184
|
+
lockedMessage: "The receipt journal is busy. Wait for the other vapi command to finish, then retry."
|
|
47185
|
+
});
|
|
47186
|
+
} else {
|
|
47187
|
+
await copy();
|
|
47188
|
+
}
|
|
46760
47189
|
copied.push(destination);
|
|
46761
47190
|
} catch (error61) {
|
|
46762
47191
|
if (isMissingFile(error61) || isAlreadyExists(error61)) continue;
|
|
@@ -46772,7 +47201,7 @@ async function migrateLegacyVapiHome(options = {}) {
|
|
|
46772
47201
|
}
|
|
46773
47202
|
async function pathExists(path) {
|
|
46774
47203
|
try {
|
|
46775
|
-
await
|
|
47204
|
+
await stat2(path);
|
|
46776
47205
|
return true;
|
|
46777
47206
|
} catch (error61) {
|
|
46778
47207
|
if (isMissingFile(error61)) return false;
|
|
@@ -46943,7 +47372,7 @@ function encryptWithKey(key, plaintext) {
|
|
|
46943
47372
|
if (key.byteLength !== KEY_LENGTH) {
|
|
46944
47373
|
throw new Error(`Expected a ${KEY_LENGTH}-byte AES-256-GCM key.`);
|
|
46945
47374
|
}
|
|
46946
|
-
const nonce =
|
|
47375
|
+
const nonce = randomBytes3(12);
|
|
46947
47376
|
const cipher = createCipheriv("aes-256-gcm", key, nonce, {
|
|
46948
47377
|
authTagLength: AUTH_TAG_LENGTH
|
|
46949
47378
|
});
|
|
@@ -47027,7 +47456,7 @@ async function sealPlaintext(plaintext, passphrase) {
|
|
|
47027
47456
|
if (passphrase.length === 0) {
|
|
47028
47457
|
throw new KeystoreError("Keystore passphrase cannot be empty.");
|
|
47029
47458
|
}
|
|
47030
|
-
const salt =
|
|
47459
|
+
const salt = randomBytes3(32);
|
|
47031
47460
|
const key = await deriveScryptKey(passphrase, salt);
|
|
47032
47461
|
try {
|
|
47033
47462
|
const sealed = encryptWithKey(key, Buffer.from(plaintext, "utf8"));
|
|
@@ -47145,7 +47574,7 @@ async function refuseExistingKeystore(path) {
|
|
|
47145
47574
|
await migrateLegacyVapiHome({ targetDirectory: getVapiPaths().directory });
|
|
47146
47575
|
}
|
|
47147
47576
|
try {
|
|
47148
|
-
await
|
|
47577
|
+
await stat3(path);
|
|
47149
47578
|
throw new KeystoreError(
|
|
47150
47579
|
`Keystore already exists at ${path}. Refusing to replace the local payment key.`
|
|
47151
47580
|
);
|
|
@@ -47167,7 +47596,7 @@ function validatePrivateKey(value) {
|
|
|
47167
47596
|
async function readStoredKeystore(path) {
|
|
47168
47597
|
let raw;
|
|
47169
47598
|
try {
|
|
47170
|
-
raw = await
|
|
47599
|
+
raw = await readFile3(path, "utf8");
|
|
47171
47600
|
} catch (error61) {
|
|
47172
47601
|
if (isMissingFile(error61)) {
|
|
47173
47602
|
throw new KeystoreError(`No vAPI keystore found at ${path}. Run vapi init.`);
|
|
@@ -47240,8 +47669,8 @@ async function createSolanaSigner(seed) {
|
|
|
47240
47669
|
}
|
|
47241
47670
|
}
|
|
47242
47671
|
async function writeKeystore(path, keystore, exclusive) {
|
|
47243
|
-
await
|
|
47244
|
-
const temporaryPath = `${path}.${process.pid}.${
|
|
47672
|
+
await mkdir3(dirname3(path), { recursive: true, mode: 448 });
|
|
47673
|
+
const temporaryPath = `${path}.${process.pid}.${randomBytes3(6).toString("hex")}.tmp`;
|
|
47245
47674
|
await writeFile2(temporaryPath, `${JSON.stringify(keystore, null, 2)}
|
|
47246
47675
|
`, {
|
|
47247
47676
|
encoding: "utf8",
|
|
@@ -47250,7 +47679,7 @@ async function writeKeystore(path, keystore, exclusive) {
|
|
|
47250
47679
|
});
|
|
47251
47680
|
if (exclusive) {
|
|
47252
47681
|
try {
|
|
47253
|
-
await
|
|
47682
|
+
await stat3(path);
|
|
47254
47683
|
throw new KeystoreError(
|
|
47255
47684
|
`Keystore already exists at ${path}. Refusing to replace the local payment key.`
|
|
47256
47685
|
);
|
|
@@ -47258,13 +47687,13 @@ async function writeKeystore(path, keystore, exclusive) {
|
|
|
47258
47687
|
if (!isMissingFile(error61)) throw error61;
|
|
47259
47688
|
}
|
|
47260
47689
|
}
|
|
47261
|
-
await
|
|
47690
|
+
await rename3(temporaryPath, path);
|
|
47262
47691
|
}
|
|
47263
47692
|
|
|
47264
47693
|
// src/vault.ts
|
|
47265
|
-
import { randomBytes as
|
|
47266
|
-
import { mkdir as
|
|
47267
|
-
import { dirname as
|
|
47694
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
47695
|
+
import { mkdir as mkdir4, open as open3, readFile as readFile4, rename as rename4, rm, stat as stat4, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
47696
|
+
import { dirname as dirname4 } from "node:path";
|
|
47268
47697
|
|
|
47269
47698
|
// src/wallet-name.ts
|
|
47270
47699
|
var WALLET_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
@@ -47272,6 +47701,9 @@ var walletNameSchema = external_exports.string().regex(
|
|
|
47272
47701
|
WALLET_NAME_PATTERN,
|
|
47273
47702
|
"A wallet name is 1 to 32 characters of lowercase letters, digits and dashes, starting with a letter or digit."
|
|
47274
47703
|
);
|
|
47704
|
+
function isWalletName(value) {
|
|
47705
|
+
return WALLET_NAME_PATTERN.test(value);
|
|
47706
|
+
}
|
|
47275
47707
|
|
|
47276
47708
|
// src/vault.ts
|
|
47277
47709
|
var VaultError = class extends Error {
|
|
@@ -47590,6 +48022,9 @@ async function exportVaultAccountKey(args) {
|
|
|
47590
48022
|
throw asVaultError(error61, "corrupt", "Unable to export the vault account key.");
|
|
47591
48023
|
}
|
|
47592
48024
|
}
|
|
48025
|
+
async function exportMemberKey(args) {
|
|
48026
|
+
return await exportVaultAccountKey(args);
|
|
48027
|
+
}
|
|
47593
48028
|
function assertVaultKey(key) {
|
|
47594
48029
|
if (key.byteLength !== 32) {
|
|
47595
48030
|
throw new VaultError("bad_key", "A device vault key must contain exactly 32 bytes.");
|
|
@@ -47706,7 +48141,7 @@ async function readVaultFile(path, key) {
|
|
|
47706
48141
|
async function readVaultFileUnlocked(path) {
|
|
47707
48142
|
let raw;
|
|
47708
48143
|
try {
|
|
47709
|
-
raw = await
|
|
48144
|
+
raw = await readFile4(path, "utf8");
|
|
47710
48145
|
} catch (error61) {
|
|
47711
48146
|
if (isMissingFile2(error61)) {
|
|
47712
48147
|
throw new VaultError("not_found", "No vault file was found at the requested path.", {
|
|
@@ -47718,8 +48153,8 @@ async function readVaultFileUnlocked(path) {
|
|
|
47718
48153
|
return parseVaultFile(raw);
|
|
47719
48154
|
}
|
|
47720
48155
|
async function writeVaultFile(path, file2) {
|
|
47721
|
-
await
|
|
47722
|
-
const temporaryPath = `${path}.${process.pid}.${
|
|
48156
|
+
await mkdir4(dirname4(path), { recursive: true, mode: 448 });
|
|
48157
|
+
const temporaryPath = `${path}.${process.pid}.${randomBytes4(6).toString("hex")}.tmp`;
|
|
47723
48158
|
try {
|
|
47724
48159
|
await writeFile3(temporaryPath, `${JSON.stringify(file2, null, 2)}
|
|
47725
48160
|
`, {
|
|
@@ -47727,20 +48162,20 @@ async function writeVaultFile(path, file2) {
|
|
|
47727
48162
|
mode: 384,
|
|
47728
48163
|
flag: "wx"
|
|
47729
48164
|
});
|
|
47730
|
-
await
|
|
48165
|
+
await rename4(temporaryPath, path);
|
|
47731
48166
|
} catch (error61) {
|
|
47732
48167
|
await rm(temporaryPath, { force: true }).catch(() => void 0);
|
|
47733
48168
|
throw error61;
|
|
47734
48169
|
}
|
|
47735
48170
|
}
|
|
47736
48171
|
async function withVaultLock(path, operation) {
|
|
47737
|
-
await
|
|
48172
|
+
await mkdir4(dirname4(path), { recursive: true, mode: 448 });
|
|
47738
48173
|
const lockPath = `${path}.lock`;
|
|
47739
48174
|
const deadline = Date.now() + VAULT_LOCK_TIMEOUT_MS;
|
|
47740
48175
|
let handle;
|
|
47741
48176
|
while (!handle) {
|
|
47742
48177
|
try {
|
|
47743
|
-
handle = await
|
|
48178
|
+
handle = await open3(lockPath, "wx", 384);
|
|
47744
48179
|
} catch (error61) {
|
|
47745
48180
|
if (!isExistingFile(error61)) throw error61;
|
|
47746
48181
|
await removeStaleVaultLock(lockPath);
|
|
@@ -47754,13 +48189,13 @@ async function withVaultLock(path, operation) {
|
|
|
47754
48189
|
return await operation();
|
|
47755
48190
|
} finally {
|
|
47756
48191
|
await handle.close();
|
|
47757
|
-
await
|
|
48192
|
+
await unlink2(lockPath).catch(() => void 0);
|
|
47758
48193
|
}
|
|
47759
48194
|
}
|
|
47760
48195
|
async function removeStaleVaultLock(path) {
|
|
47761
48196
|
try {
|
|
47762
|
-
const metadata = await
|
|
47763
|
-
if (Date.now() - metadata.mtimeMs > STALE_VAULT_LOCK_MS) await
|
|
48197
|
+
const metadata = await stat4(path);
|
|
48198
|
+
if (Date.now() - metadata.mtimeMs > STALE_VAULT_LOCK_MS) await unlink2(path);
|
|
47764
48199
|
} catch (error61) {
|
|
47765
48200
|
if (!isMissingFile2(error61)) throw error61;
|
|
47766
48201
|
}
|
|
@@ -47774,12 +48209,413 @@ function isExistingFile(error61) {
|
|
|
47774
48209
|
function asVaultError(error61, code, message) {
|
|
47775
48210
|
return error61 instanceof VaultError ? error61 : new VaultError(code, message, { cause: error61 });
|
|
47776
48211
|
}
|
|
48212
|
+
|
|
48213
|
+
// src/device.ts
|
|
48214
|
+
var DEVICE_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
48215
|
+
|
|
48216
|
+
// src/agent-link.ts
|
|
48217
|
+
var DEFAULT_AGENT_SCOPES = ["mcp:call", "router.use"];
|
|
48218
|
+
var ALLOWED_AGENT_SCOPES = /* @__PURE__ */ new Set([...DEFAULT_AGENT_SCOPES, "call.publish"]);
|
|
48219
|
+
var publicFetch = createPublicFetch({ allowPrivateNetwork: false });
|
|
48220
|
+
var agentSecretAccounts = (wallet) => ({
|
|
48221
|
+
tokens: `vapi.agent.${wallet}.tokens`,
|
|
48222
|
+
routerStake: `vapi.agent.${wallet}.router.stake`,
|
|
48223
|
+
routerBalance: `vapi.agent.${wallet}.router.balance`
|
|
48224
|
+
});
|
|
48225
|
+
|
|
48226
|
+
// src/agent-profile.ts
|
|
48227
|
+
var DEFAULT_AGENT_TOOLS = ["call.search", "call.inspect", "call.pay"];
|
|
48228
|
+
var AGENT_GRANTS = ["read", "delegate", "allocate"];
|
|
48229
|
+
var agentProfileShape = {
|
|
48230
|
+
version: external_exports.literal(1),
|
|
48231
|
+
name: walletNameSchema,
|
|
48232
|
+
wallet: external_exports.string(),
|
|
48233
|
+
model: external_exports.string().min(1),
|
|
48234
|
+
instructions: external_exports.string().max(2e4),
|
|
48235
|
+
verifiedOnly: external_exports.boolean().default(true),
|
|
48236
|
+
approveAboveUsd: external_exports.number().min(0).default(0.5),
|
|
48237
|
+
maxSteps: external_exports.number().int().min(1).max(50).default(12),
|
|
48238
|
+
paused: external_exports.boolean().default(false),
|
|
48239
|
+
grants: external_exports.array(external_exports.enum(AGENT_GRANTS)).default([]),
|
|
48240
|
+
createdAt: external_exports.string()
|
|
48241
|
+
};
|
|
48242
|
+
function createAgentProfileSchema(toolNames) {
|
|
48243
|
+
if (toolNames.length === 0) {
|
|
48244
|
+
throw new Error("Agent profiles require at least one registered tool.");
|
|
48245
|
+
}
|
|
48246
|
+
const tools = [...toolNames];
|
|
48247
|
+
return external_exports.object({ ...agentProfileShape, tools: external_exports.array(external_exports.enum(tools)).default(tools) });
|
|
48248
|
+
}
|
|
48249
|
+
var agentProfileSchema = createAgentProfileSchema(DEFAULT_AGENT_TOOLS);
|
|
48250
|
+
|
|
48251
|
+
// src/agent-run.ts
|
|
48252
|
+
var RUN_ID_PATTERN = /^run_[0-9a-f]{24}$/;
|
|
48253
|
+
var runRefSchema = external_exports.strictObject({
|
|
48254
|
+
id: external_exports.string().regex(RUN_ID_PATTERN),
|
|
48255
|
+
swarm: external_exports.string().optional(),
|
|
48256
|
+
member: external_exports.string().optional(),
|
|
48257
|
+
parentRunId: external_exports.string().optional()
|
|
48258
|
+
});
|
|
48259
|
+
|
|
48260
|
+
// src/swarm.ts
|
|
48261
|
+
var SWARM_NAME_PATTERN = /^[a-z][a-z0-9-]{0,15}$/;
|
|
48262
|
+
var SWARM_ROLE_PATTERN = /^[a-z][a-z0-9]{0,7}$/;
|
|
48263
|
+
var atomicSchema = external_exports.string().regex(/^\d+$/);
|
|
48264
|
+
var addressSchema2 = external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/);
|
|
48265
|
+
var capsSchema = external_exports.strictObject({ perCallAtomic: atomicSchema, perDayAtomic: atomicSchema });
|
|
48266
|
+
var movementIdSchema = external_exports.string().regex(/^mv_[A-Za-z0-9_-]{8,128}$/u);
|
|
48267
|
+
var amountUsdSchema = external_exports.string().regex(/^\d+\.\d{2}$/u);
|
|
48268
|
+
var setupFundingStatusSchema = external_exports.enum(["planned", "sent", "incomplete"]);
|
|
48269
|
+
var blockedFundingLegSchema = external_exports.strictObject({
|
|
48270
|
+
to: external_exports.string().trim().min(1),
|
|
48271
|
+
amountUsd: amountUsdSchema,
|
|
48272
|
+
reason: external_exports.string().trim().min(1)
|
|
48273
|
+
});
|
|
48274
|
+
var setupFundingSchema = external_exports.strictObject({
|
|
48275
|
+
amountUsd: amountUsdSchema,
|
|
48276
|
+
from: walletNameSchema,
|
|
48277
|
+
movementId: movementIdSchema.optional(),
|
|
48278
|
+
status: setupFundingStatusSchema,
|
|
48279
|
+
policy: external_exports.strictObject({
|
|
48280
|
+
strategy: external_exports.enum(["targets", "even", "weights"]),
|
|
48281
|
+
movementId: movementIdSchema.optional(),
|
|
48282
|
+
status: setupFundingStatusSchema,
|
|
48283
|
+
blocked: external_exports.array(blockedFundingLegSchema).optional()
|
|
48284
|
+
}).optional()
|
|
48285
|
+
});
|
|
48286
|
+
var accountSteps = {
|
|
48287
|
+
creating: external_exports.boolean().default(false),
|
|
48288
|
+
created: external_exports.boolean(),
|
|
48289
|
+
capped: external_exports.boolean(),
|
|
48290
|
+
linked: external_exports.boolean()
|
|
48291
|
+
};
|
|
48292
|
+
var treasurySchema = external_exports.strictObject({
|
|
48293
|
+
account: walletNameSchema,
|
|
48294
|
+
// A planned account has no address until its vault derivation succeeds.
|
|
48295
|
+
address: addressSchema2.optional(),
|
|
48296
|
+
steps: external_exports.strictObject(accountSteps)
|
|
48297
|
+
}).refine(
|
|
48298
|
+
(value) => !value.steps.created || value.address !== void 0,
|
|
48299
|
+
"Created accounts require an address."
|
|
48300
|
+
);
|
|
48301
|
+
var memberSchema = external_exports.strictObject({
|
|
48302
|
+
account: walletNameSchema,
|
|
48303
|
+
address: addressSchema2.optional(),
|
|
48304
|
+
role: external_exports.string().regex(SWARM_ROLE_PATTERN),
|
|
48305
|
+
weight: external_exports.number().int().positive(),
|
|
48306
|
+
targetAtomic: atomicSchema,
|
|
48307
|
+
ceilingAtomic: atomicSchema.nullable(),
|
|
48308
|
+
steps: external_exports.strictObject({ ...accountSteps, profiled: external_exports.boolean() })
|
|
48309
|
+
}).refine(
|
|
48310
|
+
(value) => !value.steps.created || value.address !== void 0,
|
|
48311
|
+
"Created accounts require an address."
|
|
48312
|
+
);
|
|
48313
|
+
var swarmFileSchema = external_exports.strictObject({
|
|
48314
|
+
v: external_exports.literal(1),
|
|
48315
|
+
name: external_exports.string().regex(SWARM_NAME_PATTERN),
|
|
48316
|
+
device: external_exports.string().regex(DEVICE_NAME_PATTERN),
|
|
48317
|
+
network: external_exports.enum([BASE_MAINNET_CAIP2, ARC_MAINNET_CAIP2]),
|
|
48318
|
+
createdAt: external_exports.iso.datetime(),
|
|
48319
|
+
treasury: treasurySchema,
|
|
48320
|
+
members: external_exports.array(memberSchema),
|
|
48321
|
+
setupFunding: setupFundingSchema.optional(),
|
|
48322
|
+
policy: external_exports.strictObject({
|
|
48323
|
+
strategy: external_exports.enum(["targets", "even", "weights"]),
|
|
48324
|
+
treasuryCaps: capsSchema
|
|
48325
|
+
})
|
|
48326
|
+
}).refine(
|
|
48327
|
+
(value) => (/* @__PURE__ */ new Set([value.treasury.account, ...value.members.map((member) => member.account)])).size === value.members.length + 1,
|
|
48328
|
+
"Swarm accounts must be unique."
|
|
48329
|
+
);
|
|
48330
|
+
|
|
48331
|
+
// src/member-bundle.ts
|
|
48332
|
+
var MEMBER_BUNDLE_MAX_BYTES = 32 * 1024;
|
|
48333
|
+
var REMOTE_BLOCKED_GRANTS = /* @__PURE__ */ new Set([
|
|
48334
|
+
"delegate",
|
|
48335
|
+
"allocate"
|
|
48336
|
+
]);
|
|
48337
|
+
var BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
48338
|
+
var ADDRESS_PATTERN2 = /^0x[0-9a-fA-F]{40}$/;
|
|
48339
|
+
var PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
48340
|
+
var ATOMIC_PATTERN = /^\d+$/;
|
|
48341
|
+
var FORBIDDEN_CONFIG_KEYS = /* @__PURE__ */ new Set(["rpcUrl", "apiKey"]);
|
|
48342
|
+
var MemberBundleError = class extends Error {
|
|
48343
|
+
constructor(code, message) {
|
|
48344
|
+
super(message);
|
|
48345
|
+
this.code = code;
|
|
48346
|
+
this.name = "MemberBundleError";
|
|
48347
|
+
}
|
|
48348
|
+
code;
|
|
48349
|
+
};
|
|
48350
|
+
var hexString = (pattern, message) => external_exports.custom((value) => typeof value === "string" && pattern.test(value), message);
|
|
48351
|
+
var linkSchema = external_exports.strictObject({
|
|
48352
|
+
apiBase: external_exports.string(),
|
|
48353
|
+
clientId: external_exports.string(),
|
|
48354
|
+
owner: external_exports.custom((value) => typeof value === "string" && value.startsWith("0x")),
|
|
48355
|
+
label: external_exports.string(),
|
|
48356
|
+
scopes: external_exports.array(external_exports.string()),
|
|
48357
|
+
linkedAt: external_exports.iso.datetime(),
|
|
48358
|
+
routerBaseUrl: external_exports.string().optional()
|
|
48359
|
+
});
|
|
48360
|
+
var remoteTokensSchema = external_exports.strictObject({
|
|
48361
|
+
accessToken: external_exports.string().min(1),
|
|
48362
|
+
expiresAt: external_exports.number().finite(),
|
|
48363
|
+
scopes: external_exports.array(external_exports.string()),
|
|
48364
|
+
refreshable: external_exports.literal(false)
|
|
48365
|
+
});
|
|
48366
|
+
var storedTokensSchema = external_exports.object({
|
|
48367
|
+
accessToken: external_exports.string().min(1),
|
|
48368
|
+
refreshToken: external_exports.string().min(1),
|
|
48369
|
+
expiresAt: external_exports.number().finite(),
|
|
48370
|
+
scopes: external_exports.array(external_exports.string())
|
|
48371
|
+
});
|
|
48372
|
+
var credentialsSchema = external_exports.strictObject({
|
|
48373
|
+
tokens: external_exports.string().min(1).refine(isRemoteTokens, "A member bundle carries a non-refreshable access token only."),
|
|
48374
|
+
routerStake: external_exports.string().min(1).optional(),
|
|
48375
|
+
routerBalance: external_exports.string().min(1).optional()
|
|
48376
|
+
});
|
|
48377
|
+
var remoteProfileSchema = agentProfileSchema.strict().refine((profile) => profile.grants.every((grant) => !REMOTE_BLOCKED_GRANTS.has(grant)), {
|
|
48378
|
+
message: "A remote member never holds the delegate or allocate grant.",
|
|
48379
|
+
path: ["grants"]
|
|
48380
|
+
});
|
|
48381
|
+
var credentialFreeUrl = external_exports.url().refine((value) => unsafeUrlPart(value) === void 0, {
|
|
48382
|
+
message: "A member bundle URL never carries a user name, password, query or fragment."
|
|
48383
|
+
});
|
|
48384
|
+
var memberBundleConfigSchema = external_exports.unknown().refine((value) => !hasForbiddenConfigKey(value), {
|
|
48385
|
+
message: "A member bundle never carries RPC URLs or API keys."
|
|
48386
|
+
}).pipe(
|
|
48387
|
+
external_exports.strictObject({
|
|
48388
|
+
discoveryUrl: credentialFreeUrl,
|
|
48389
|
+
marketplaceDiscoveryUrl: credentialFreeUrl,
|
|
48390
|
+
networks: external_exports.record(
|
|
48391
|
+
external_exports.string().refine(isMemberBundleNetwork, {
|
|
48392
|
+
message: "Expected a network with a public RPC default."
|
|
48393
|
+
}),
|
|
48394
|
+
external_exports.strictObject({ usdc: external_exports.string() })
|
|
48395
|
+
).refine(
|
|
48396
|
+
(networks) => Object.entries(networks).every(
|
|
48397
|
+
([id, network]) => isMemberBundleNetwork(id) && network.usdc === NETWORKS[id].usdc
|
|
48398
|
+
),
|
|
48399
|
+
{ message: "Expected the canonical USDC token of each network." }
|
|
48400
|
+
).refine((networks) => Object.keys(networks).length === 1, {
|
|
48401
|
+
message: "A member bundle carries exactly one network: the swarm's."
|
|
48402
|
+
})
|
|
48403
|
+
})
|
|
48404
|
+
);
|
|
48405
|
+
var memberBundleSchema = external_exports.strictObject({
|
|
48406
|
+
v: external_exports.literal(1),
|
|
48407
|
+
account: walletNameSchema,
|
|
48408
|
+
address: hexString(ADDRESS_PATTERN2, "Expected a 20-byte 0x address."),
|
|
48409
|
+
privateKey: hexString(PRIVATE_KEY_PATTERN, "Expected a 32-byte 0x private key."),
|
|
48410
|
+
swarm: external_exports.string().regex(SWARM_NAME_PATTERN),
|
|
48411
|
+
profile: remoteProfileSchema,
|
|
48412
|
+
link: linkSchema,
|
|
48413
|
+
credentials: credentialsSchema,
|
|
48414
|
+
caps: external_exports.strictObject(spendCapsSchema.shape),
|
|
48415
|
+
allowanceExpiresAt: external_exports.iso.datetime(),
|
|
48416
|
+
ceilingAtomic: external_exports.string().regex(ATOMIC_PATTERN, "Expected non-negative atomic units."),
|
|
48417
|
+
config: memberBundleConfigSchema,
|
|
48418
|
+
runId: external_exports.string().regex(RUN_ID_PATTERN),
|
|
48419
|
+
parentRunId: external_exports.string().regex(RUN_ID_PATTERN).optional()
|
|
48420
|
+
});
|
|
48421
|
+
function memberBundleConfig(owner, network) {
|
|
48422
|
+
const discoveryUrl = safeDiscoveryUrl("discoveryUrl", owner.discoveryUrl);
|
|
48423
|
+
const marketplaceDiscoveryUrl = safeDiscoveryUrl(
|
|
48424
|
+
"marketplaceDiscoveryUrl",
|
|
48425
|
+
owner.marketplaceDiscoveryUrl
|
|
48426
|
+
);
|
|
48427
|
+
if (!Object.hasOwn(owner.networks, network) || !isMemberBundleNetwork(network)) {
|
|
48428
|
+
throw new MemberBundleError(
|
|
48429
|
+
"unsupported_network",
|
|
48430
|
+
`A member bundle runs on the swarm network ${network}, which must be enabled in this config and have a public RPC default.`
|
|
48431
|
+
);
|
|
48432
|
+
}
|
|
48433
|
+
return {
|
|
48434
|
+
discoveryUrl,
|
|
48435
|
+
marketplaceDiscoveryUrl,
|
|
48436
|
+
networks: { [network]: { usdc: NETWORKS[network].usdc } }
|
|
48437
|
+
};
|
|
48438
|
+
}
|
|
48439
|
+
function headlessConfigFromBundle(config2) {
|
|
48440
|
+
const networks = {};
|
|
48441
|
+
for (const [id, network] of Object.entries(config2.networks)) {
|
|
48442
|
+
if (!isMemberBundleNetwork(id) || network === void 0) continue;
|
|
48443
|
+
networks[id] = { rpcUrl: NETWORKS[id].publicRpcUrl, usdc: network.usdc };
|
|
48444
|
+
}
|
|
48445
|
+
return configSchema.parse({
|
|
48446
|
+
discoveryUrl: config2.discoveryUrl,
|
|
48447
|
+
marketplaceDiscoveryUrl: config2.marketplaceDiscoveryUrl,
|
|
48448
|
+
networks,
|
|
48449
|
+
spendCaps: { ...DEFAULT_SPEND_CAPS }
|
|
48450
|
+
});
|
|
48451
|
+
}
|
|
48452
|
+
function createMemberBundle(input2) {
|
|
48453
|
+
const bundle = parseBundle({ ...input2, profile: withoutRemoteGrants(input2.profile), v: 1 });
|
|
48454
|
+
assertKeyMatchesAddress(bundle);
|
|
48455
|
+
const encoded = Buffer.from(JSON.stringify(bundle), "utf8").toString("base64url");
|
|
48456
|
+
if (encoded.length > MEMBER_BUNDLE_MAX_BYTES) {
|
|
48457
|
+
throw new MemberBundleError(
|
|
48458
|
+
"too_large",
|
|
48459
|
+
`The member bundle is larger than ${MEMBER_BUNDLE_MAX_BYTES} bytes.`
|
|
48460
|
+
);
|
|
48461
|
+
}
|
|
48462
|
+
return encoded;
|
|
48463
|
+
}
|
|
48464
|
+
function openMemberBundle(text) {
|
|
48465
|
+
if (typeof text !== "string") {
|
|
48466
|
+
throw new MemberBundleError("invalid", "The member bundle is not a string.");
|
|
48467
|
+
}
|
|
48468
|
+
if (text.length > MEMBER_BUNDLE_MAX_BYTES) {
|
|
48469
|
+
throw new MemberBundleError(
|
|
48470
|
+
"too_large",
|
|
48471
|
+
`The member bundle is larger than ${MEMBER_BUNDLE_MAX_BYTES} bytes.`
|
|
48472
|
+
);
|
|
48473
|
+
}
|
|
48474
|
+
if (!BASE64URL_PATTERN.test(text)) {
|
|
48475
|
+
throw new MemberBundleError("invalid", "The member bundle is not base64url text.");
|
|
48476
|
+
}
|
|
48477
|
+
let decoded;
|
|
48478
|
+
try {
|
|
48479
|
+
decoded = JSON.parse(Buffer.from(text, "base64url").toString("utf8"));
|
|
48480
|
+
} catch {
|
|
48481
|
+
throw new MemberBundleError("invalid", "The member bundle does not decode to JSON.");
|
|
48482
|
+
}
|
|
48483
|
+
const bundle = parseBundle(decoded);
|
|
48484
|
+
assertKeyMatchesAddress(bundle);
|
|
48485
|
+
return bundle;
|
|
48486
|
+
}
|
|
48487
|
+
async function readMemberCredentials(args) {
|
|
48488
|
+
if (!isWalletName(args.account)) {
|
|
48489
|
+
throw new MemberBundleError("invalid", "The member account name is not valid.");
|
|
48490
|
+
}
|
|
48491
|
+
const names = agentSecretAccounts(args.account);
|
|
48492
|
+
const storedTokens = await args.secrets.get(names.tokens);
|
|
48493
|
+
if (storedTokens === void 0 || storedTokens === "") {
|
|
48494
|
+
throw new MemberBundleError(
|
|
48495
|
+
"not_linked",
|
|
48496
|
+
`The account ${args.account} is not linked to vAPI. Link it with vapi login first.`
|
|
48497
|
+
);
|
|
48498
|
+
}
|
|
48499
|
+
const routerStake = await args.secrets.get(names.routerStake);
|
|
48500
|
+
const routerBalance = await args.secrets.get(names.routerBalance);
|
|
48501
|
+
const parsed = parseStoredTokens(storedTokens);
|
|
48502
|
+
if (parsed === void 0) {
|
|
48503
|
+
throw new MemberBundleError(
|
|
48504
|
+
"not_linked",
|
|
48505
|
+
`The account ${args.account}'s vAPI credentials cannot be exported safely. Run vapi login --account ${args.account} again.`
|
|
48506
|
+
);
|
|
48507
|
+
}
|
|
48508
|
+
const tokens = JSON.stringify({
|
|
48509
|
+
accessToken: parsed.accessToken,
|
|
48510
|
+
expiresAt: parsed.expiresAt,
|
|
48511
|
+
scopes: parsed.scopes,
|
|
48512
|
+
refreshable: false
|
|
48513
|
+
});
|
|
48514
|
+
return {
|
|
48515
|
+
tokens,
|
|
48516
|
+
...routerStake === void 0 || routerStake === "" ? {} : { routerStake },
|
|
48517
|
+
...routerBalance === void 0 || routerBalance === "" ? {} : { routerBalance }
|
|
48518
|
+
};
|
|
48519
|
+
}
|
|
48520
|
+
function isRemoteTokens(value) {
|
|
48521
|
+
try {
|
|
48522
|
+
return remoteTokensSchema.safeParse(JSON.parse(value)).success;
|
|
48523
|
+
} catch {
|
|
48524
|
+
return false;
|
|
48525
|
+
}
|
|
48526
|
+
}
|
|
48527
|
+
function parseStoredTokens(value) {
|
|
48528
|
+
try {
|
|
48529
|
+
const parsed = storedTokensSchema.safeParse(JSON.parse(value));
|
|
48530
|
+
return parsed.success ? parsed.data : void 0;
|
|
48531
|
+
} catch {
|
|
48532
|
+
return void 0;
|
|
48533
|
+
}
|
|
48534
|
+
}
|
|
48535
|
+
function isMemberBundleNetwork(id) {
|
|
48536
|
+
return Object.hasOwn(NETWORKS, id) && typeof NETWORKS[id].publicRpcUrl === "string";
|
|
48537
|
+
}
|
|
48538
|
+
function hasForbiddenConfigKey(value) {
|
|
48539
|
+
if (Array.isArray(value)) return value.some(hasForbiddenConfigKey);
|
|
48540
|
+
if (typeof value !== "object" || value === null) return false;
|
|
48541
|
+
return Object.entries(value).some(
|
|
48542
|
+
([key, item]) => FORBIDDEN_CONFIG_KEYS.has(key) || hasForbiddenConfigKey(item)
|
|
48543
|
+
);
|
|
48544
|
+
}
|
|
48545
|
+
function unsafeUrlPart(value) {
|
|
48546
|
+
let url2;
|
|
48547
|
+
try {
|
|
48548
|
+
url2 = new URL(value);
|
|
48549
|
+
} catch {
|
|
48550
|
+
return "an unparseable value";
|
|
48551
|
+
}
|
|
48552
|
+
if (url2.username !== "" || url2.password !== "") return "a user name or password";
|
|
48553
|
+
if (url2.search !== "" || value.includes("?")) return "a query string";
|
|
48554
|
+
if (url2.hash !== "" || value.includes("#")) return "a fragment";
|
|
48555
|
+
return void 0;
|
|
48556
|
+
}
|
|
48557
|
+
function safeDiscoveryUrl(field, value) {
|
|
48558
|
+
const part = unsafeUrlPart(value);
|
|
48559
|
+
if (part !== void 0) {
|
|
48560
|
+
throw new MemberBundleError(
|
|
48561
|
+
"unsafe_config",
|
|
48562
|
+
`The owner config's ${field} has ${part}, which can carry a credential, so it never goes into a member bundle. Point ${field} at a plain URL (check VAPI_DISCOVERY_URL, VAPI_MARKETPLACE_DISCOVERY_URL and config.json).`
|
|
48563
|
+
);
|
|
48564
|
+
}
|
|
48565
|
+
return value;
|
|
48566
|
+
}
|
|
48567
|
+
function withoutRemoteGrants(profile) {
|
|
48568
|
+
if (typeof profile !== "object" || profile === null || !Array.isArray(profile.grants)) {
|
|
48569
|
+
return profile;
|
|
48570
|
+
}
|
|
48571
|
+
return {
|
|
48572
|
+
...profile,
|
|
48573
|
+
grants: profile.grants.filter((grant) => !REMOTE_BLOCKED_GRANTS.has(grant))
|
|
48574
|
+
};
|
|
48575
|
+
}
|
|
48576
|
+
function parseBundle(value) {
|
|
48577
|
+
const parsed = memberBundleSchema.safeParse(value);
|
|
48578
|
+
if (!parsed.success) {
|
|
48579
|
+
const fields = [
|
|
48580
|
+
...new Set(parsed.error.issues.map((issue2) => issue2.path.map(String).join(".") || "(root)"))
|
|
48581
|
+
];
|
|
48582
|
+
throw new MemberBundleError(
|
|
48583
|
+
"invalid",
|
|
48584
|
+
`The member bundle is not valid (fields: ${fields.join(", ")}).`
|
|
48585
|
+
);
|
|
48586
|
+
}
|
|
48587
|
+
return parsed.data;
|
|
48588
|
+
}
|
|
48589
|
+
function assertKeyMatchesAddress(bundle) {
|
|
48590
|
+
let derived;
|
|
48591
|
+
try {
|
|
48592
|
+
derived = privateKeyToAccount(bundle.privateKey).address;
|
|
48593
|
+
} catch {
|
|
48594
|
+
throw new MemberBundleError("key_mismatch", "The member bundle's key is not a valid key.");
|
|
48595
|
+
}
|
|
48596
|
+
if (derived.toLowerCase() !== bundle.address.toLowerCase()) {
|
|
48597
|
+
throw new MemberBundleError(
|
|
48598
|
+
"key_mismatch",
|
|
48599
|
+
"The member bundle's key does not match its address."
|
|
48600
|
+
);
|
|
48601
|
+
}
|
|
48602
|
+
}
|
|
47777
48603
|
export {
|
|
48604
|
+
MEMBER_BUNDLE_MAX_BYTES,
|
|
48605
|
+
MemberBundleError,
|
|
47778
48606
|
createKeystoreWithPhrase,
|
|
48607
|
+
createMemberBundle,
|
|
47779
48608
|
decryptPrivateKey,
|
|
47780
48609
|
exportKeystoreKeys,
|
|
48610
|
+
exportMemberKey,
|
|
47781
48611
|
exportRecoveryPhrase,
|
|
47782
48612
|
exportVaultAccountKey,
|
|
47783
|
-
exportVaultPhrase
|
|
48613
|
+
exportVaultPhrase,
|
|
48614
|
+
headlessConfigFromBundle,
|
|
48615
|
+
memberBundleConfig,
|
|
48616
|
+
memberBundleConfigSchema,
|
|
48617
|
+
memberBundleSchema,
|
|
48618
|
+
openMemberBundle,
|
|
48619
|
+
readMemberCredentials
|
|
47784
48620
|
};
|
|
47785
48621
|
//# sourceMappingURL=secrets.js.map
|