@vapi-network/cli 0.9.0 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1779 -943
- package/dist/cli.js.map +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1772 -937
- package/dist/index.js.map +3 -3
- package/dist/setup.d.ts +2 -1
- package/dist/task.d.ts +3 -2
- package/dist/update-check.d.ts +13 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10116,11 +10116,9 @@ var init_call = __esm({
|
|
|
10116
10116
|
}
|
|
10117
10117
|
});
|
|
10118
10118
|
|
|
10119
|
-
// src/
|
|
10120
|
-
import {
|
|
10121
|
-
import {
|
|
10122
|
-
import { join as join28 } from "node:path";
|
|
10123
|
-
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
10119
|
+
// src/update-check.ts
|
|
10120
|
+
import { lookup } from "node:dns/promises";
|
|
10121
|
+
import { mkdir as mkdir21, readFile as readFile29, writeFile as writeFile12 } from "node:fs/promises";
|
|
10124
10122
|
|
|
10125
10123
|
// ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
|
|
10126
10124
|
var external_exports = {};
|
|
@@ -28988,365 +28986,6 @@ function date4(params) {
|
|
|
28988
28986
|
return _coercedDate(ZodDate, params);
|
|
28989
28987
|
}
|
|
28990
28988
|
|
|
28991
|
-
// ../core/src/marketplace-contracts.ts
|
|
28992
|
-
var MARKETPLACE_DISCOVERY_PROTOCOL = "vapi.marketplace.discovery/1";
|
|
28993
|
-
var MARKETPLACE_RANKING_VERSION = "marketplace-ranking-v1";
|
|
28994
|
-
var MARKETPLACE_KINDS = ["api", "service_offer", "open_request"];
|
|
28995
|
-
var MARKETPLACE_EXECUTION_METHODS = [
|
|
28996
|
-
"GET",
|
|
28997
|
-
"HEAD",
|
|
28998
|
-
"POST",
|
|
28999
|
-
"PUT",
|
|
29000
|
-
"PATCH",
|
|
29001
|
-
"DELETE"
|
|
29002
|
-
];
|
|
29003
|
-
var marketplaceExecutionMethodSchema = external_exports.enum(MARKETPLACE_EXECUTION_METHODS);
|
|
29004
|
-
var marketplaceKindSchema = external_exports.enum(MARKETPLACE_KINDS);
|
|
29005
|
-
var EXECUTION_MODES = ["direct", "gateway"];
|
|
29006
|
-
var executionModeSchema = external_exports.enum(EXECUTION_MODES);
|
|
29007
|
-
var PROVENANCES = ["indexed", "self_listed", "partner"];
|
|
29008
|
-
var provenanceSchema = external_exports.enum(PROVENANCES);
|
|
29009
|
-
var FIRST_PARTY_PROVENANCES = ["self_listed", "partner"];
|
|
29010
|
-
var firstPartyProvenanceSchema = external_exports.enum(FIRST_PARTY_PROVENANCES);
|
|
29011
|
-
var LISTING_GROUPS = ["vapi", "added", "partner", "external"];
|
|
29012
|
-
var listingGroupSchema = external_exports.enum(LISTING_GROUPS);
|
|
29013
|
-
var listingFeeSchema = external_exports.looseObject({
|
|
29014
|
-
bps: external_exports.number().int().min(0),
|
|
29015
|
-
label: external_exports.string()
|
|
29016
|
-
});
|
|
29017
|
-
var LISTING_VERIFICATIONS = ["none", "requested", "verified"];
|
|
29018
|
-
var listingVerificationSchema = external_exports.enum(LISTING_VERIFICATIONS);
|
|
29019
|
-
var listingVerificationFieldSchema = listingVerificationSchema.default("none").catch("none");
|
|
29020
|
-
var listingLivenessSchema = external_exports.looseObject({
|
|
29021
|
-
uptime7d: external_exports.number().min(0).max(1),
|
|
29022
|
-
latencyP50Ms: external_exports.number().nonnegative().nullable(),
|
|
29023
|
-
latencyP95Ms: external_exports.number().nonnegative().nullable(),
|
|
29024
|
-
checks7d: external_exports.number().int().nonnegative()
|
|
29025
|
-
});
|
|
29026
|
-
var listingConformanceSchema = external_exports.looseObject({
|
|
29027
|
-
declaredVersion: external_exports.union([external_exports.literal(1), external_exports.literal(2)]).nullable(),
|
|
29028
|
-
versionConformant: external_exports.boolean(),
|
|
29029
|
-
offerTransport: external_exports.enum(["body", "header", "both"]),
|
|
29030
|
-
issues: external_exports.array(external_exports.string())
|
|
29031
|
-
});
|
|
29032
|
-
var listingIdentitySchema = external_exports.looseObject({
|
|
29033
|
-
erc8004Id: external_exports.string().trim().min(1),
|
|
29034
|
-
reputation: external_exports.looseObject({
|
|
29035
|
-
score: external_exports.number().finite(),
|
|
29036
|
-
count: external_exports.number().int().nonnegative()
|
|
29037
|
-
}).optional().catch(void 0)
|
|
29038
|
-
});
|
|
29039
|
-
var listingDisclosureShape = {
|
|
29040
|
-
group: listingGroupSchema.optional(),
|
|
29041
|
-
fee: listingFeeSchema.optional(),
|
|
29042
|
-
verification: listingVerificationFieldSchema,
|
|
29043
|
-
liveness: listingLivenessSchema.optional().catch(void 0),
|
|
29044
|
-
conformance: listingConformanceSchema.optional().catch(void 0),
|
|
29045
|
-
identity: listingIdentitySchema.optional().catch(void 0)
|
|
29046
|
-
};
|
|
29047
|
-
var marketplaceBadgeCodeSchema = external_exports.enum([
|
|
29048
|
-
"live_x402",
|
|
29049
|
-
"partner",
|
|
29050
|
-
"payout_wallet_confirmed",
|
|
29051
|
-
"vapi_verified",
|
|
29052
|
-
"external_catalog",
|
|
29053
|
-
"approved_vendor"
|
|
29054
|
-
]);
|
|
29055
|
-
var marketplaceBadgeSchema = external_exports.looseObject({
|
|
29056
|
-
code: marketplaceBadgeCodeSchema,
|
|
29057
|
-
label: external_exports.string().trim().min(1).max(80)
|
|
29058
|
-
});
|
|
29059
|
-
var marketplacePublicFactSchema = external_exports.looseObject({
|
|
29060
|
-
label: external_exports.string().trim().min(1).max(80),
|
|
29061
|
-
value: external_exports.string().trim().min(1).max(160)
|
|
29062
|
-
});
|
|
29063
|
-
var marketplaceHrefSchema = external_exports.union([
|
|
29064
|
-
external_exports.string().trim().min(1).max(2048).regex(/^\/(?!\/)/),
|
|
29065
|
-
external_exports.url().max(2048).regex(/^https:\/\//)
|
|
29066
|
-
]);
|
|
29067
|
-
var marketplaceCardSchema = external_exports.looseObject({
|
|
29068
|
-
title: external_exports.string().trim().min(1).max(160),
|
|
29069
|
-
summary: external_exports.string().trim().min(1).max(1e3),
|
|
29070
|
-
byline: external_exports.string().trim().min(1).max(160).optional(),
|
|
29071
|
-
bylineHref: marketplaceHrefSchema.optional(),
|
|
29072
|
-
badges: external_exports.array(marketplaceBadgeSchema).max(8),
|
|
29073
|
-
facts: external_exports.array(marketplacePublicFactSchema).max(12)
|
|
29074
|
-
});
|
|
29075
|
-
var marketplaceHitBase = {
|
|
29076
|
-
ref: external_exports.string().trim().min(1).max(512),
|
|
29077
|
-
card: marketplaceCardSchema,
|
|
29078
|
-
...listingDisclosureShape
|
|
29079
|
-
};
|
|
29080
|
-
var invokeApiActionSchema = external_exports.looseObject({
|
|
29081
|
-
type: external_exports.literal("invoke_api"),
|
|
29082
|
-
href: marketplaceHrefSchema
|
|
29083
|
-
});
|
|
29084
|
-
var firstPartyApiMarketplaceHitSchema = external_exports.looseObject({
|
|
29085
|
-
...marketplaceHitBase,
|
|
29086
|
-
kind: external_exports.literal("api"),
|
|
29087
|
-
provenance: firstPartyProvenanceSchema,
|
|
29088
|
-
execution: external_exports.looseObject({
|
|
29089
|
-
mode: executionModeSchema
|
|
29090
|
-
}),
|
|
29091
|
-
action: invokeApiActionSchema
|
|
29092
|
-
});
|
|
29093
|
-
var mirroredApiMarketplaceHitSchema = external_exports.looseObject({
|
|
29094
|
-
...marketplaceHitBase,
|
|
29095
|
-
kind: external_exports.literal("api"),
|
|
29096
|
-
provenance: external_exports.literal("indexed"),
|
|
29097
|
-
execution: external_exports.looseObject({
|
|
29098
|
-
mode: external_exports.literal("direct"),
|
|
29099
|
-
url: external_exports.url().max(2048).regex(/^https:\/\/(?![^/?#]*@)/),
|
|
29100
|
-
method: marketplaceExecutionMethodSchema.nullable(),
|
|
29101
|
-
network: external_exports.string().trim().max(160).regex(/^eip155:[1-9]\d*$/)
|
|
29102
|
-
}),
|
|
29103
|
-
action: invokeApiActionSchema
|
|
29104
|
-
});
|
|
29105
|
-
var apiMarketplaceHitSchema = external_exports.discriminatedUnion("provenance", [
|
|
29106
|
-
firstPartyApiMarketplaceHitSchema,
|
|
29107
|
-
mirroredApiMarketplaceHitSchema
|
|
29108
|
-
]);
|
|
29109
|
-
var serviceOfferMarketplaceHitSchema = external_exports.looseObject({
|
|
29110
|
-
...marketplaceHitBase,
|
|
29111
|
-
kind: external_exports.literal("service_offer"),
|
|
29112
|
-
action: external_exports.looseObject({
|
|
29113
|
-
type: external_exports.literal("start_engagement"),
|
|
29114
|
-
href: marketplaceHrefSchema
|
|
29115
|
-
})
|
|
29116
|
-
});
|
|
29117
|
-
var openRequestMarketplaceHitSchema = external_exports.looseObject({
|
|
29118
|
-
...marketplaceHitBase,
|
|
29119
|
-
kind: external_exports.literal("open_request"),
|
|
29120
|
-
action: external_exports.looseObject({
|
|
29121
|
-
type: external_exports.literal("propose_to_request"),
|
|
29122
|
-
href: marketplaceHrefSchema
|
|
29123
|
-
})
|
|
29124
|
-
});
|
|
29125
|
-
var marketplaceHitSchema = external_exports.union([
|
|
29126
|
-
apiMarketplaceHitSchema,
|
|
29127
|
-
serviceOfferMarketplaceHitSchema,
|
|
29128
|
-
openRequestMarketplaceHitSchema
|
|
29129
|
-
]);
|
|
29130
|
-
var marketplaceDiscoveryInputSchema = external_exports.strictObject({
|
|
29131
|
-
q: external_exports.string().trim().max(200).optional(),
|
|
29132
|
-
kinds: external_exports.array(marketplaceKindSchema).min(1).max(MARKETPLACE_KINDS.length).optional(),
|
|
29133
|
-
network: external_exports.string().trim().min(1).max(160).optional(),
|
|
29134
|
-
cursor: external_exports.string().trim().min(1).max(4096).optional(),
|
|
29135
|
-
limit: external_exports.number().int().min(1).max(50).optional(),
|
|
29136
|
-
includeUnverified: external_exports.boolean().optional()
|
|
29137
|
-
}).superRefine((input2, context) => {
|
|
29138
|
-
if (input2.kinds && new Set(input2.kinds).size !== input2.kinds.length) {
|
|
29139
|
-
context.addIssue({
|
|
29140
|
-
code: "custom",
|
|
29141
|
-
path: ["kinds"],
|
|
29142
|
-
message: "Marketplace kinds must be unique"
|
|
29143
|
-
});
|
|
29144
|
-
}
|
|
29145
|
-
});
|
|
29146
|
-
function isMirroredHit(hit) {
|
|
29147
|
-
return hit.kind === "api" && hit.provenance === "indexed";
|
|
29148
|
-
}
|
|
29149
|
-
var marketplaceDiscoveryPageSchema = external_exports.looseObject({
|
|
29150
|
-
protocol: external_exports.literal(MARKETPLACE_DISCOVERY_PROTOCOL),
|
|
29151
|
-
items: external_exports.array(marketplaceHitSchema),
|
|
29152
|
-
nextCursor: external_exports.string().min(1).max(4096).nullable(),
|
|
29153
|
-
unavailableKinds: external_exports.array(marketplaceKindSchema).max(MARKETPLACE_KINDS.length),
|
|
29154
|
-
rankingVersion: external_exports.literal(MARKETPLACE_RANKING_VERSION)
|
|
29155
|
-
});
|
|
29156
|
-
|
|
29157
|
-
// ../core/src/call-contracts-wire.ts
|
|
29158
|
-
var CALLABLE_CATEGORIES = ["ai", "data", "crypto", "compute", "search"];
|
|
29159
|
-
var callableCategorySchema = external_exports.enum(CALLABLE_CATEGORIES);
|
|
29160
|
-
var DISCOVERY_CATEGORIES = [...CALLABLE_CATEGORIES, "other"];
|
|
29161
|
-
var discoveryCategorySchema = external_exports.enum(DISCOVERY_CATEGORIES);
|
|
29162
|
-
var CALLABLE_CATEGORY_SET = new Set(CALLABLE_CATEGORIES);
|
|
29163
|
-
var serviceTierSchema = external_exports.enum(["listed", "verified", "partner"]);
|
|
29164
|
-
var discoveryEndpointSchema = external_exports.looseObject({
|
|
29165
|
-
name: external_exports.string(),
|
|
29166
|
-
method: external_exports.string(),
|
|
29167
|
-
url: external_exports.url(),
|
|
29168
|
-
price: external_exports.string(),
|
|
29169
|
-
description: external_exports.string(),
|
|
29170
|
-
operationId: external_exports.string().trim().min(1).optional(),
|
|
29171
|
-
requestContentType: external_exports.string().trim().min(1).optional(),
|
|
29172
|
-
requestSchema: external_exports.json().optional(),
|
|
29173
|
-
responseContentType: external_exports.string().trim().min(1).optional(),
|
|
29174
|
-
pathTemplate: external_exports.string().trim().min(1).optional(),
|
|
29175
|
-
pathParameters: external_exports.array(external_exports.string().trim().min(1)).optional(),
|
|
29176
|
-
payment: external_exports.looseObject({
|
|
29177
|
-
scheme: external_exports.literal("exact"),
|
|
29178
|
-
network: external_exports.string().regex(/^eip155:\d+$/),
|
|
29179
|
-
asset: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
|
|
29180
|
-
payTo: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
|
|
29181
|
-
checkedAt: external_exports.iso.datetime()
|
|
29182
|
-
}).optional()
|
|
29183
|
-
});
|
|
29184
|
-
var serviceSummarySchema = external_exports.looseObject({
|
|
29185
|
-
id: external_exports.string(),
|
|
29186
|
-
name: external_exports.string(),
|
|
29187
|
-
description: external_exports.string(),
|
|
29188
|
-
category: discoveryCategorySchema,
|
|
29189
|
-
tier: serviceTierSchema,
|
|
29190
|
-
...listingDisclosureShape,
|
|
29191
|
-
verified: external_exports.boolean(),
|
|
29192
|
-
wrapped: external_exports.boolean(),
|
|
29193
|
-
price: external_exports.string(),
|
|
29194
|
-
networks: external_exports.array(external_exports.string()),
|
|
29195
|
-
endpoints: external_exports.array(discoveryEndpointSchema)
|
|
29196
|
-
});
|
|
29197
|
-
var searchServicesResponseSchema = external_exports.looseObject({
|
|
29198
|
-
services: external_exports.array(serviceSummarySchema)
|
|
29199
|
-
});
|
|
29200
|
-
var discoveryResponseSchema = searchServicesResponseSchema;
|
|
29201
|
-
|
|
29202
|
-
// ../core/src/call-contracts.ts
|
|
29203
|
-
var DiscoveryCatalogError = class extends Error {
|
|
29204
|
-
name = "DiscoveryCatalogError";
|
|
29205
|
-
code;
|
|
29206
|
-
serviceId;
|
|
29207
|
-
constructor(code, message, serviceId) {
|
|
29208
|
-
super(message);
|
|
29209
|
-
this.code = code;
|
|
29210
|
-
this.serviceId = serviceId;
|
|
29211
|
-
}
|
|
29212
|
-
};
|
|
29213
|
-
function parseDiscovery(raw) {
|
|
29214
|
-
const parsed = discoveryResponseSchema.safeParse(raw);
|
|
29215
|
-
if (!parsed.success) {
|
|
29216
|
-
const malformedUrl = parsed.error.issues.find(
|
|
29217
|
-
(issue2) => issue2.path.at(-1) === "url" && issue2.path.includes("endpoints")
|
|
29218
|
-
);
|
|
29219
|
-
if (malformedUrl) {
|
|
29220
|
-
const serviceIndex = pathIndexAfter(malformedUrl.path, "services");
|
|
29221
|
-
const serviceId = rawServiceId(raw, serviceIndex);
|
|
29222
|
-
throw new DiscoveryCatalogError(
|
|
29223
|
-
"malformed_url",
|
|
29224
|
-
`Service ${JSON.stringify(serviceId ?? "unknown")} has a malformed endpoint URL.`,
|
|
29225
|
-
serviceId
|
|
29226
|
-
);
|
|
29227
|
-
}
|
|
29228
|
-
throw new DiscoveryCatalogError("invalid_discovery", "Discovery response is malformed.");
|
|
29229
|
-
}
|
|
29230
|
-
for (const service of parsed.data.services) {
|
|
29231
|
-
buildTargets(service);
|
|
29232
|
-
}
|
|
29233
|
-
const resolveListing = (serviceId, endpointName) => {
|
|
29234
|
-
const service = parsed.data.services.find((candidate) => candidate.id === serviceId);
|
|
29235
|
-
if (!service) {
|
|
29236
|
-
throw new DiscoveryCatalogError(
|
|
29237
|
-
"service_not_found",
|
|
29238
|
-
`No payable endpoint found for service ${JSON.stringify(serviceId)}.`,
|
|
29239
|
-
serviceId
|
|
29240
|
-
);
|
|
29241
|
-
}
|
|
29242
|
-
return { service, endpoint: resolveTarget(service, endpointName) };
|
|
29243
|
-
};
|
|
29244
|
-
return {
|
|
29245
|
-
services: parsed.data.services,
|
|
29246
|
-
resolve: (serviceId, endpointName) => resolveListing(serviceId, endpointName).endpoint,
|
|
29247
|
-
resolveListing
|
|
29248
|
-
};
|
|
29249
|
-
}
|
|
29250
|
-
function resolveTarget(service, endpointName) {
|
|
29251
|
-
const { targets, targetsByName } = buildTargets(service);
|
|
29252
|
-
if (endpointName !== void 0) {
|
|
29253
|
-
const selected = targetsByName.get(endpointName.trim());
|
|
29254
|
-
if (!selected) {
|
|
29255
|
-
throw new DiscoveryCatalogError(
|
|
29256
|
-
"endpoint_not_found",
|
|
29257
|
-
`Service ${JSON.stringify(service.id)} has no endpoint ${JSON.stringify(endpointName)}. Available endpoints: ${[...targetsByName.keys()].join(", ")}.`,
|
|
29258
|
-
service.id
|
|
29259
|
-
);
|
|
29260
|
-
}
|
|
29261
|
-
return { ...selected };
|
|
29262
|
-
}
|
|
29263
|
-
if (targets.size !== 1) {
|
|
29264
|
-
throw new DiscoveryCatalogError(
|
|
29265
|
-
"ambiguous_default",
|
|
29266
|
-
`Service ${JSON.stringify(service.id)} has ${targets.size} distinct payable endpoints. Choose one with endpoint: ${[...targetsByName.keys()].join(", ")}.`,
|
|
29267
|
-
service.id
|
|
29268
|
-
);
|
|
29269
|
-
}
|
|
29270
|
-
return targets.values().next().value;
|
|
29271
|
-
}
|
|
29272
|
-
function buildTargets(service) {
|
|
29273
|
-
if (service.endpoints.length === 0) {
|
|
29274
|
-
throw new DiscoveryCatalogError(
|
|
29275
|
-
"no_endpoint",
|
|
29276
|
-
`Service ${JSON.stringify(service.id)} has no payable endpoint.`,
|
|
29277
|
-
service.id
|
|
29278
|
-
);
|
|
29279
|
-
}
|
|
29280
|
-
const namedEndpoints = [...service.endpoints].sort(
|
|
29281
|
-
(left, right) => compareNames(left.name.trim(), right.name.trim())
|
|
29282
|
-
);
|
|
29283
|
-
const names = /* @__PURE__ */ new Set();
|
|
29284
|
-
const targets = /* @__PURE__ */ new Map();
|
|
29285
|
-
const targetsByName = /* @__PURE__ */ new Map();
|
|
29286
|
-
for (const endpoint of namedEndpoints) {
|
|
29287
|
-
const name = endpoint.name.trim();
|
|
29288
|
-
if (!name) {
|
|
29289
|
-
throw new DiscoveryCatalogError(
|
|
29290
|
-
"invalid_endpoint_name",
|
|
29291
|
-
`Service ${JSON.stringify(service.id)} has a blank endpoint name.`,
|
|
29292
|
-
service.id
|
|
29293
|
-
);
|
|
29294
|
-
}
|
|
29295
|
-
if (names.has(name)) {
|
|
29296
|
-
throw new DiscoveryCatalogError(
|
|
29297
|
-
"duplicate_endpoint_name",
|
|
29298
|
-
`Service ${JSON.stringify(service.id)} has duplicate endpoint name ${JSON.stringify(name)}.`,
|
|
29299
|
-
service.id
|
|
29300
|
-
);
|
|
29301
|
-
}
|
|
29302
|
-
names.add(name);
|
|
29303
|
-
const method = endpoint.method.trim().toUpperCase();
|
|
29304
|
-
if (!method) {
|
|
29305
|
-
throw new DiscoveryCatalogError(
|
|
29306
|
-
"blank_method",
|
|
29307
|
-
`Service ${JSON.stringify(service.id)} has a blank endpoint method.`,
|
|
29308
|
-
service.id
|
|
29309
|
-
);
|
|
29310
|
-
}
|
|
29311
|
-
const url2 = new URL(endpoint.url);
|
|
29312
|
-
if (url2.protocol !== "http:" && url2.protocol !== "https:") {
|
|
29313
|
-
throw new DiscoveryCatalogError(
|
|
29314
|
-
"malformed_url",
|
|
29315
|
-
`Service ${JSON.stringify(service.id)} has a non-HTTP endpoint URL.`,
|
|
29316
|
-
service.id
|
|
29317
|
-
);
|
|
29318
|
-
}
|
|
29319
|
-
const transportKey = `${method}\0${endpoint.url}`;
|
|
29320
|
-
const normalized = { ...endpoint, name, method };
|
|
29321
|
-
targetsByName.set(name, normalized);
|
|
29322
|
-
if (!targets.has(transportKey)) targets.set(transportKey, normalized);
|
|
29323
|
-
}
|
|
29324
|
-
return { targets, targetsByName };
|
|
29325
|
-
}
|
|
29326
|
-
function compareNames(left, right) {
|
|
29327
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
29328
|
-
}
|
|
29329
|
-
function pathIndexAfter(path, key2) {
|
|
29330
|
-
const keyIndex = path.indexOf(key2);
|
|
29331
|
-
const candidate = path[keyIndex + 1];
|
|
29332
|
-
return typeof candidate === "number" ? candidate : void 0;
|
|
29333
|
-
}
|
|
29334
|
-
function rawServiceId(raw, serviceIndex) {
|
|
29335
|
-
if (serviceIndex === void 0 || typeof raw !== "object" || raw === null) {
|
|
29336
|
-
return void 0;
|
|
29337
|
-
}
|
|
29338
|
-
const services = Reflect.get(raw, "services");
|
|
29339
|
-
if (!Array.isArray(services)) {
|
|
29340
|
-
return void 0;
|
|
29341
|
-
}
|
|
29342
|
-
const service = services[serviceIndex];
|
|
29343
|
-
if (typeof service !== "object" || service === null) {
|
|
29344
|
-
return void 0;
|
|
29345
|
-
}
|
|
29346
|
-
const id2 = Reflect.get(service, "id");
|
|
29347
|
-
return typeof id2 === "string" ? id2 : void 0;
|
|
29348
|
-
}
|
|
29349
|
-
|
|
29350
28989
|
// ../../node_modules/.pnpm/viem@2.56.1_typescript@6.0.3_zod@4.5.4/node_modules/viem/_esm/index.js
|
|
29351
28990
|
init_exports();
|
|
29352
28991
|
|
|
@@ -39623,6 +39262,7 @@ var ARC_MAINNET_CAIP2 = "eip155:5042";
|
|
|
39623
39262
|
var ARC_TESTNET_CAIP2 = "eip155:5042002";
|
|
39624
39263
|
var SOLANA_MAINNET_CAIP2 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
39625
39264
|
var X402_SOLANA_MAINNET_CAIP2 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
39265
|
+
var SOLANA_DEVNET_CAIP2 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
|
|
39626
39266
|
var SOLANA_MAINNET_USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
39627
39267
|
function canonicalIdentity(usdc, eip712Domain) {
|
|
39628
39268
|
return Object.freeze({
|
|
@@ -39666,375 +39306,194 @@ var BROWSER_ENABLED_X402_NETWORK_CONFIG = Object.freeze({
|
|
|
39666
39306
|
[ARC_TESTNET_CAIP2]: browserNetwork(arcTestnetUsdc)
|
|
39667
39307
|
});
|
|
39668
39308
|
|
|
39669
|
-
// ../core/src/
|
|
39670
|
-
|
|
39671
|
-
|
|
39672
|
-
|
|
39673
|
-
|
|
39674
|
-
|
|
39675
|
-
|
|
39676
|
-
|
|
39677
|
-
|
|
39309
|
+
// ../core/src/marketplace-contracts.ts
|
|
39310
|
+
var MARKETPLACE_DISCOVERY_PROTOCOL = "vapi.marketplace.discovery/1";
|
|
39311
|
+
var MARKETPLACE_RANKING_VERSION = "marketplace-ranking-v1";
|
|
39312
|
+
var MARKETPLACE_KINDS = ["api", "service_offer", "open_request"];
|
|
39313
|
+
var MARKETPLACE_EXECUTION_METHODS = [
|
|
39314
|
+
"GET",
|
|
39315
|
+
"HEAD",
|
|
39316
|
+
"POST",
|
|
39317
|
+
"PUT",
|
|
39318
|
+
"PATCH",
|
|
39319
|
+
"DELETE"
|
|
39320
|
+
];
|
|
39321
|
+
var marketplaceExecutionMethodSchema = external_exports.enum(MARKETPLACE_EXECUTION_METHODS);
|
|
39322
|
+
var marketplaceKindSchema = external_exports.enum(MARKETPLACE_KINDS);
|
|
39323
|
+
var EXECUTION_MODES = ["direct", "gateway"];
|
|
39324
|
+
var executionModeSchema = external_exports.enum(EXECUTION_MODES);
|
|
39325
|
+
var PROVENANCES = ["indexed", "self_listed", "partner"];
|
|
39326
|
+
var provenanceSchema = external_exports.enum(PROVENANCES);
|
|
39327
|
+
var FIRST_PARTY_PROVENANCES = ["self_listed", "partner"];
|
|
39328
|
+
var firstPartyProvenanceSchema = external_exports.enum(FIRST_PARTY_PROVENANCES);
|
|
39329
|
+
var LISTING_GROUPS = ["vapi", "added", "partner", "external"];
|
|
39330
|
+
var listingGroupSchema = external_exports.enum(LISTING_GROUPS);
|
|
39331
|
+
var listingFeeSchema = external_exports.looseObject({
|
|
39332
|
+
bps: external_exports.number().int().min(0),
|
|
39333
|
+
label: external_exports.string()
|
|
39334
|
+
});
|
|
39335
|
+
var LISTING_VERIFICATIONS = ["none", "requested", "verified"];
|
|
39336
|
+
var listingVerificationSchema = external_exports.enum(LISTING_VERIFICATIONS);
|
|
39337
|
+
var listingVerificationFieldSchema = listingVerificationSchema.default("none").catch("none");
|
|
39338
|
+
var listingLivenessSchema = external_exports.looseObject({
|
|
39339
|
+
uptime7d: external_exports.number().min(0).max(1),
|
|
39340
|
+
latencyP50Ms: external_exports.number().nonnegative().nullable(),
|
|
39341
|
+
latencyP95Ms: external_exports.number().nonnegative().nullable(),
|
|
39342
|
+
checks7d: external_exports.number().int().nonnegative()
|
|
39343
|
+
});
|
|
39344
|
+
var listingConformanceSchema = external_exports.looseObject({
|
|
39345
|
+
declaredVersion: external_exports.union([external_exports.literal(1), external_exports.literal(2)]).nullable(),
|
|
39346
|
+
versionConformant: external_exports.boolean(),
|
|
39347
|
+
offerTransport: external_exports.enum(["body", "header", "both"]),
|
|
39348
|
+
issues: external_exports.array(external_exports.string())
|
|
39349
|
+
});
|
|
39350
|
+
var listingIdentitySchema = external_exports.looseObject({
|
|
39351
|
+
erc8004Id: external_exports.string().trim().min(1),
|
|
39352
|
+
reputation: external_exports.looseObject({
|
|
39353
|
+
score: external_exports.number().finite(),
|
|
39354
|
+
count: external_exports.number().int().nonnegative()
|
|
39355
|
+
}).optional().catch(void 0)
|
|
39356
|
+
});
|
|
39357
|
+
var listingDisclosureShape = {
|
|
39358
|
+
// Presentation metadata must not make an otherwise executable row vanish
|
|
39359
|
+
// when the registry adds a new group or changes the fee display shape.
|
|
39360
|
+
group: listingGroupSchema.optional().catch(void 0),
|
|
39361
|
+
fee: listingFeeSchema.optional().catch(void 0),
|
|
39362
|
+
verification: listingVerificationFieldSchema,
|
|
39363
|
+
liveness: listingLivenessSchema.optional().catch(void 0),
|
|
39364
|
+
conformance: listingConformanceSchema.optional().catch(void 0),
|
|
39365
|
+
identity: listingIdentitySchema.optional().catch(void 0)
|
|
39678
39366
|
};
|
|
39679
|
-
|
|
39680
|
-
|
|
39681
|
-
|
|
39682
|
-
|
|
39683
|
-
|
|
39684
|
-
|
|
39685
|
-
|
|
39686
|
-
|
|
39687
|
-
|
|
39688
|
-
|
|
39689
|
-
|
|
39690
|
-
|
|
39691
|
-
|
|
39692
|
-
|
|
39693
|
-
|
|
39694
|
-
|
|
39695
|
-
|
|
39696
|
-
|
|
39697
|
-
|
|
39698
|
-
|
|
39699
|
-
|
|
39700
|
-
|
|
39701
|
-
|
|
39702
|
-
|
|
39703
|
-
|
|
39704
|
-
|
|
39705
|
-
|
|
39706
|
-
|
|
39707
|
-
|
|
39708
|
-
|
|
39709
|
-
|
|
39710
|
-
|
|
39711
|
-
|
|
39712
|
-
|
|
39713
|
-
|
|
39714
|
-
|
|
39715
|
-
|
|
39716
|
-
|
|
39717
|
-
|
|
39718
|
-
|
|
39719
|
-
lookup: lookupFn,
|
|
39720
|
-
timeoutMs: 5e3
|
|
39721
|
-
});
|
|
39722
|
-
const normalized = new Request(input2, init);
|
|
39723
|
-
const bytes = normalized.body ? Buffer.from(await normalized.arrayBuffer()) : null;
|
|
39724
|
-
return await new Promise((resolve2, reject) => {
|
|
39725
|
-
const requestOptions2 = {
|
|
39726
|
-
method: normalized.method,
|
|
39727
|
-
headers: Object.fromEntries(normalized.headers),
|
|
39728
|
-
signal: normalized.signal,
|
|
39729
|
-
...options.allowPrivateNetwork ? {} : { lookup: pinnedLookup(lookupFn) }
|
|
39730
|
-
};
|
|
39731
|
-
const onResponse = (incoming) => {
|
|
39732
|
-
try {
|
|
39733
|
-
const headers = new Headers();
|
|
39734
|
-
for (const [name, value] of Object.entries(incoming.headers)) {
|
|
39735
|
-
if (Array.isArray(value)) {
|
|
39736
|
-
for (const item of value) headers.append(name, item);
|
|
39737
|
-
} else if (value !== void 0) {
|
|
39738
|
-
headers.set(name, value);
|
|
39739
|
-
}
|
|
39740
|
-
}
|
|
39741
|
-
const status = incoming.statusCode ?? 500;
|
|
39742
|
-
const bodyForbidden = normalized.method === "HEAD" || [204, 205, 304].includes(status);
|
|
39743
|
-
if (bodyForbidden) incoming.resume();
|
|
39744
|
-
const response = new Response(
|
|
39745
|
-
bodyForbidden ? null : Readable.toWeb(incoming),
|
|
39746
|
-
{ status, statusText: incoming.statusMessage, headers }
|
|
39747
|
-
);
|
|
39748
|
-
Object.defineProperty(response, "url", { value: url2.toString() });
|
|
39749
|
-
resolve2(response);
|
|
39750
|
-
} catch (error61) {
|
|
39751
|
-
incoming.destroy();
|
|
39752
|
-
reject(error61);
|
|
39753
|
-
}
|
|
39754
|
-
};
|
|
39755
|
-
const request = url2.protocol === "https:" ? httpsRequest(url2, requestOptions2, onResponse) : httpRequest(url2, requestOptions2, onResponse);
|
|
39756
|
-
request.on("error", reject);
|
|
39757
|
-
if (bytes) request.write(bytes);
|
|
39758
|
-
request.end();
|
|
39759
|
-
});
|
|
39760
|
-
});
|
|
39761
|
-
}
|
|
39762
|
-
function pinnedLookup(lookup) {
|
|
39763
|
-
return (hostname3, dnsOptions, callback) => {
|
|
39764
|
-
void lookup(normalizeHostname(hostname3)).then((addresses) => {
|
|
39765
|
-
if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
|
|
39766
|
-
callback(guardError(new URL(`https://${hostname3}`)), "");
|
|
39767
|
-
return;
|
|
39768
|
-
}
|
|
39769
|
-
const address4 = addresses[0];
|
|
39770
|
-
const family = isIP(address4);
|
|
39771
|
-
callback(
|
|
39772
|
-
null,
|
|
39773
|
-
dnsOptions.all ? [{ address: address4, family }] : address4,
|
|
39774
|
-
dnsOptions.all ? void 0 : family
|
|
39775
|
-
);
|
|
39776
|
-
}).catch(
|
|
39777
|
-
(error61) => callback(error61 instanceof Error ? error61 : new Error("DNS lookup failed."), "")
|
|
39778
|
-
);
|
|
39779
|
-
};
|
|
39780
|
-
}
|
|
39781
|
-
async function withTimeout2(operation, timeoutMs) {
|
|
39782
|
-
let timeout;
|
|
39783
|
-
try {
|
|
39784
|
-
return await Promise.race([
|
|
39785
|
-
operation,
|
|
39786
|
-
new Promise((_resolve, reject) => {
|
|
39787
|
-
timeout = setTimeout(() => reject(new Error("DNS lookup timed out.")), timeoutMs);
|
|
39788
|
-
})
|
|
39789
|
-
]);
|
|
39790
|
-
} finally {
|
|
39791
|
-
if (timeout) clearTimeout(timeout);
|
|
39792
|
-
}
|
|
39793
|
-
}
|
|
39794
|
-
function normalizeHostname(hostname3) {
|
|
39795
|
-
const unbracketed = hostname3.startsWith("[") && hostname3.endsWith("]") ? hostname3.slice(1, -1) : hostname3;
|
|
39796
|
-
return unbracketed.endsWith(".") ? unbracketed.slice(0, -1) : unbracketed;
|
|
39797
|
-
}
|
|
39798
|
-
function isNonPublicAddress(address4) {
|
|
39799
|
-
const normalized = normalizeHostname(address4);
|
|
39800
|
-
const version5 = isIP(normalized);
|
|
39801
|
-
if (version5 === 4) {
|
|
39802
|
-
return isNonPublicIpv4(parseIpv4(normalized));
|
|
39803
|
-
}
|
|
39804
|
-
if (version5 === 6) {
|
|
39805
|
-
return isNonPublicIpv6(parseIpv6(normalized));
|
|
39806
|
-
}
|
|
39807
|
-
return true;
|
|
39808
|
-
}
|
|
39809
|
-
function parseIpv4(address4) {
|
|
39810
|
-
const octets = address4.split(".").map(Number);
|
|
39811
|
-
return [octets[0], octets[1], octets[2], octets[3]];
|
|
39812
|
-
}
|
|
39813
|
-
function isNonPublicIpv4([first, second, third]) {
|
|
39814
|
-
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;
|
|
39815
|
-
}
|
|
39816
|
-
function parseIpv6(address4) {
|
|
39817
|
-
let normalized = address4.toLowerCase();
|
|
39818
|
-
const lastColon = normalized.lastIndexOf(":");
|
|
39819
|
-
const dottedTail = normalized.slice(lastColon + 1);
|
|
39820
|
-
if (dottedTail.includes(".")) {
|
|
39821
|
-
const [first, second, third, fourth] = parseIpv4(dottedTail);
|
|
39822
|
-
normalized = `${normalized.slice(0, lastColon + 1)}${(first << 8 | second).toString(16)}:${(third << 8 | fourth).toString(16)}`;
|
|
39823
|
-
}
|
|
39824
|
-
const halves = normalized.split("::");
|
|
39825
|
-
const left = halves[0] ? halves[0].split(":").map(parseHex) : [];
|
|
39826
|
-
const right = halves[1] ? halves[1].split(":").map(parseHex) : [];
|
|
39827
|
-
const omittedCount = 8 - left.length - right.length;
|
|
39828
|
-
return halves.length === 2 ? [...left, ...Array.from({ length: omittedCount }, () => 0), ...right] : left;
|
|
39829
|
-
}
|
|
39830
|
-
function parseHex(value) {
|
|
39831
|
-
return Number.parseInt(value, 16);
|
|
39832
|
-
}
|
|
39833
|
-
function isNonPublicIpv6(hextets) {
|
|
39834
|
-
if (hextets.slice(0, 5).every((hextet) => hextet === 0) && hextets[5] === 65535) {
|
|
39835
|
-
const embeddedIpv4 = [
|
|
39836
|
-
hextets[6] >> 8,
|
|
39837
|
-
hextets[6] & 255,
|
|
39838
|
-
hextets[7] >> 8,
|
|
39839
|
-
hextets[7] & 255
|
|
39840
|
-
];
|
|
39841
|
-
return isNonPublicIpv4(embeddedIpv4);
|
|
39842
|
-
}
|
|
39843
|
-
if (hextets.slice(0, 6).every((hextet) => hextet === 0)) {
|
|
39844
|
-
const compatibleIpv4 = [
|
|
39845
|
-
hextets[6] >> 8,
|
|
39846
|
-
hextets[6] & 255,
|
|
39847
|
-
hextets[7] >> 8,
|
|
39848
|
-
hextets[7] & 255
|
|
39849
|
-
];
|
|
39850
|
-
if (isNonPublicIpv4(compatibleIpv4)) return true;
|
|
39851
|
-
}
|
|
39852
|
-
const isUnspecified = hextets.every((hextet) => hextet === 0);
|
|
39853
|
-
const isLoopback = hextets.slice(0, 7).every((hextet) => hextet === 0) && hextets[7] === 1;
|
|
39854
|
-
const first = hextets[0];
|
|
39855
|
-
const isUniqueLocal = first >= 64512 && first <= 65023;
|
|
39856
|
-
const isLinkLocal = first >= 65152 && first <= 65215;
|
|
39857
|
-
const isSiteLocal = first >= 65216 && first <= 65279;
|
|
39858
|
-
const isMulticast = first >= 65280;
|
|
39859
|
-
const isDocumentation = first === 8193 && hextets[1] === 3512;
|
|
39860
|
-
return isUnspecified || isLoopback || isUniqueLocal || isLinkLocal || isSiteLocal || isMulticast || isDocumentation;
|
|
39861
|
-
}
|
|
39862
|
-
function guardError(url2) {
|
|
39863
|
-
return new Error(
|
|
39864
|
-
`URL hostname ${JSON.stringify(url2.hostname)} is not allowed; private or internal destinations require allowPrivateNetwork true in the vAPI config.`
|
|
39865
|
-
);
|
|
39866
|
-
}
|
|
39867
|
-
|
|
39868
|
-
// ../core/src/networks.ts
|
|
39869
|
-
var USDC_DECIMALS = 6;
|
|
39870
|
-
var DEFAULT_ARC_GAS_HEADROOM_ATOMIC = 50000n;
|
|
39871
|
-
var NETWORKS = {
|
|
39872
|
-
[BASE_MAINNET_CAIP2]: {
|
|
39873
|
-
family: "evm",
|
|
39874
|
-
chainId: 8453,
|
|
39875
|
-
name: "Base mainnet",
|
|
39876
|
-
usdc: CANONICAL_X402_USDC_NETWORKS[BASE_MAINNET_CAIP2].usdc,
|
|
39877
|
-
gasToken: "ETH",
|
|
39878
|
-
rpcEnv: "BASE_RPC_URL",
|
|
39879
|
-
publicRpcUrl: "https://mainnet.base.org",
|
|
39880
|
-
explorerUrl: "https://basescan.org"
|
|
39881
|
-
},
|
|
39882
|
-
[ARC_MAINNET_CAIP2]: {
|
|
39883
|
-
family: "evm",
|
|
39884
|
-
chainId: 5042,
|
|
39885
|
-
name: "Arc mainnet",
|
|
39886
|
-
usdc: CANONICAL_X402_USDC_NETWORKS[ARC_MAINNET_CAIP2].usdc,
|
|
39887
|
-
gasToken: "USDC",
|
|
39888
|
-
rpcEnv: "ARC_RPC_URL",
|
|
39889
|
-
publicRpcUrl: "https://rpc.mainnet.arc.io",
|
|
39890
|
-
explorerUrl: "https://explorer.arc.io"
|
|
39891
|
-
},
|
|
39892
|
-
[ARC_TESTNET_CAIP2]: {
|
|
39893
|
-
family: "evm",
|
|
39894
|
-
chainId: 5042002,
|
|
39895
|
-
name: "Arc testnet",
|
|
39896
|
-
usdc: CANONICAL_X402_USDC_NETWORKS[ARC_TESTNET_CAIP2].usdc,
|
|
39897
|
-
gasToken: "USDC",
|
|
39898
|
-
rpcEnv: "ARC_TESTNET_RPC_URL"
|
|
39899
|
-
},
|
|
39900
|
-
[SOLANA_MAINNET_CAIP2]: {
|
|
39901
|
-
family: "svm",
|
|
39902
|
-
name: "Solana mainnet",
|
|
39903
|
-
usdc: SOLANA_MAINNET_USDC,
|
|
39904
|
-
gasToken: "SOL",
|
|
39905
|
-
rpcEnv: "SOLANA_RPC_URL",
|
|
39906
|
-
publicRpcUrl: "https://api.mainnet-beta.solana.com"
|
|
39907
|
-
},
|
|
39908
|
-
[X402_SOLANA_MAINNET_CAIP2]: {
|
|
39909
|
-
family: "svm",
|
|
39910
|
-
name: "Solana mainnet",
|
|
39911
|
-
usdc: SOLANA_MAINNET_USDC,
|
|
39912
|
-
gasToken: "SOL",
|
|
39913
|
-
rpcEnv: "SOLANA_RPC_URL",
|
|
39914
|
-
publicRpcUrl: "https://api.mainnet-beta.solana.com"
|
|
39915
|
-
}
|
|
39367
|
+
var marketplaceBadgeCodeSchema = external_exports.enum([
|
|
39368
|
+
"live_x402",
|
|
39369
|
+
"mpp",
|
|
39370
|
+
"partner",
|
|
39371
|
+
"payout_wallet_confirmed",
|
|
39372
|
+
"vapi_verified",
|
|
39373
|
+
"external_catalog",
|
|
39374
|
+
"approved_vendor",
|
|
39375
|
+
"unverified"
|
|
39376
|
+
]);
|
|
39377
|
+
var marketplaceBadgeSchema = external_exports.looseObject({
|
|
39378
|
+
code: marketplaceBadgeCodeSchema,
|
|
39379
|
+
label: external_exports.string().trim().min(1).max(80)
|
|
39380
|
+
});
|
|
39381
|
+
var marketplacePublicFactSchema = external_exports.looseObject({
|
|
39382
|
+
label: external_exports.string().trim().min(1).max(80),
|
|
39383
|
+
value: external_exports.string().trim().min(1).max(160)
|
|
39384
|
+
});
|
|
39385
|
+
var marketplaceHrefSchema = external_exports.union([
|
|
39386
|
+
external_exports.string().trim().min(1).max(2048).regex(/^\/(?!\/)/),
|
|
39387
|
+
external_exports.url().max(2048).regex(/^https:\/\//)
|
|
39388
|
+
]);
|
|
39389
|
+
var marketplaceCardSchema = external_exports.looseObject({
|
|
39390
|
+
title: external_exports.string().trim().min(1).max(160),
|
|
39391
|
+
summary: external_exports.string().trim().min(1).max(1e3),
|
|
39392
|
+
byline: external_exports.string().trim().min(1).max(160).optional(),
|
|
39393
|
+
bylineHref: marketplaceHrefSchema.optional(),
|
|
39394
|
+
badges: external_exports.preprocess(
|
|
39395
|
+
(badges) => Array.isArray(badges) ? badges.flatMap((badge) => {
|
|
39396
|
+
const parsed = marketplaceBadgeSchema.safeParse(badge);
|
|
39397
|
+
return parsed.success ? [parsed.data] : [];
|
|
39398
|
+
}) : badges,
|
|
39399
|
+
external_exports.array(marketplaceBadgeSchema).max(8)
|
|
39400
|
+
),
|
|
39401
|
+
facts: external_exports.array(marketplacePublicFactSchema).max(12)
|
|
39402
|
+
});
|
|
39403
|
+
var marketplaceHitBase = {
|
|
39404
|
+
ref: external_exports.string().trim().min(1).max(512),
|
|
39405
|
+
card: marketplaceCardSchema,
|
|
39406
|
+
...listingDisclosureShape
|
|
39916
39407
|
};
|
|
39917
|
-
|
|
39918
|
-
|
|
39919
|
-
|
|
39920
|
-
|
|
39921
|
-
|
|
39922
|
-
|
|
39923
|
-
|
|
39924
|
-
|
|
39925
|
-
|
|
39926
|
-
|
|
39927
|
-
}
|
|
39928
|
-
|
|
39929
|
-
|
|
39930
|
-
|
|
39931
|
-
|
|
39932
|
-
|
|
39933
|
-
|
|
39934
|
-
|
|
39935
|
-
|
|
39936
|
-
|
|
39937
|
-
|
|
39938
|
-
|
|
39939
|
-
|
|
39940
|
-
|
|
39941
|
-
|
|
39942
|
-
|
|
39943
|
-
|
|
39944
|
-
|
|
39945
|
-
|
|
39946
|
-
|
|
39947
|
-
|
|
39948
|
-
|
|
39949
|
-
|
|
39950
|
-
|
|
39951
|
-
|
|
39952
|
-
|
|
39953
|
-
|
|
39954
|
-
|
|
39955
|
-
|
|
39956
|
-
|
|
39957
|
-
|
|
39958
|
-
|
|
39959
|
-
|
|
39960
|
-
|
|
39961
|
-
|
|
39962
|
-
}
|
|
39963
|
-
|
|
39964
|
-
|
|
39965
|
-
|
|
39966
|
-
|
|
39967
|
-
|
|
39968
|
-
|
|
39969
|
-
|
|
39970
|
-
|
|
39971
|
-
|
|
39972
|
-
|
|
39973
|
-
|
|
39974
|
-
|
|
39975
|
-
|
|
39976
|
-
|
|
39977
|
-
|
|
39978
|
-
|
|
39979
|
-
|
|
39980
|
-
|
|
39981
|
-
|
|
39982
|
-
|
|
39983
|
-
|
|
39984
|
-
|
|
39985
|
-
|
|
39986
|
-
|
|
39987
|
-
|
|
39988
|
-
|
|
39989
|
-
|
|
39990
|
-
|
|
39991
|
-
const rpcUrl = envUrl || configured.rpcUrl.trim();
|
|
39992
|
-
if (rpcUrl) {
|
|
39993
|
-
return rpcUrl;
|
|
39994
|
-
}
|
|
39995
|
-
if (network === ARC_TESTNET_CAIP2) {
|
|
39996
|
-
throw new Error(
|
|
39997
|
-
"Arc testnet RPC is required. Set ARC_TESTNET_RPC_URL or add rpcUrl for eip155:5042002 in config.json."
|
|
39998
|
-
);
|
|
39999
|
-
}
|
|
40000
|
-
throw new Error(`RPC URL is required for ${network}.`);
|
|
40001
|
-
}
|
|
40002
|
-
function createChain(network, rpcUrl) {
|
|
40003
|
-
const definition = getNetworkDefinition(network);
|
|
40004
|
-
if (definition.family !== "evm" || definition.chainId === void 0) {
|
|
40005
|
-
throw new Error(`Network ${network} is not an EVM chain.`);
|
|
39408
|
+
var invokeApiActionSchema = external_exports.looseObject({
|
|
39409
|
+
type: external_exports.literal("invoke_api"),
|
|
39410
|
+
href: marketplaceHrefSchema
|
|
39411
|
+
});
|
|
39412
|
+
var firstPartyApiMarketplaceHitSchema = external_exports.looseObject({
|
|
39413
|
+
...marketplaceHitBase,
|
|
39414
|
+
kind: external_exports.literal("api"),
|
|
39415
|
+
provenance: firstPartyProvenanceSchema,
|
|
39416
|
+
execution: external_exports.looseObject({
|
|
39417
|
+
mode: executionModeSchema
|
|
39418
|
+
}),
|
|
39419
|
+
action: invokeApiActionSchema
|
|
39420
|
+
});
|
|
39421
|
+
var mirroredApiMarketplaceHitSchema = external_exports.looseObject({
|
|
39422
|
+
...marketplaceHitBase,
|
|
39423
|
+
kind: external_exports.literal("api"),
|
|
39424
|
+
provenance: external_exports.literal("indexed"),
|
|
39425
|
+
execution: external_exports.looseObject({
|
|
39426
|
+
mode: external_exports.literal("direct"),
|
|
39427
|
+
url: external_exports.url().max(2048).regex(/^https:\/\/(?![^/?#]*@)/),
|
|
39428
|
+
method: marketplaceExecutionMethodSchema.nullable(),
|
|
39429
|
+
network: external_exports.string().trim().max(160).transform((network) => {
|
|
39430
|
+
if (network === "solana") return X402_SOLANA_MAINNET_CAIP2;
|
|
39431
|
+
if (network === "solana-devnet") return SOLANA_DEVNET_CAIP2;
|
|
39432
|
+
return network;
|
|
39433
|
+
}).pipe(
|
|
39434
|
+
external_exports.union([
|
|
39435
|
+
external_exports.string().regex(/^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$/),
|
|
39436
|
+
// Persisted mainnet configs also use the full genesis hash.
|
|
39437
|
+
external_exports.literal(SOLANA_MAINNET_CAIP2)
|
|
39438
|
+
])
|
|
39439
|
+
)
|
|
39440
|
+
}),
|
|
39441
|
+
action: invokeApiActionSchema
|
|
39442
|
+
});
|
|
39443
|
+
var apiMarketplaceHitSchema = external_exports.discriminatedUnion("provenance", [
|
|
39444
|
+
firstPartyApiMarketplaceHitSchema,
|
|
39445
|
+
mirroredApiMarketplaceHitSchema
|
|
39446
|
+
]);
|
|
39447
|
+
var serviceOfferMarketplaceHitSchema = external_exports.looseObject({
|
|
39448
|
+
...marketplaceHitBase,
|
|
39449
|
+
kind: external_exports.literal("service_offer"),
|
|
39450
|
+
action: external_exports.looseObject({
|
|
39451
|
+
type: external_exports.literal("start_engagement"),
|
|
39452
|
+
href: marketplaceHrefSchema
|
|
39453
|
+
})
|
|
39454
|
+
});
|
|
39455
|
+
var openRequestMarketplaceHitSchema = external_exports.looseObject({
|
|
39456
|
+
...marketplaceHitBase,
|
|
39457
|
+
kind: external_exports.literal("open_request"),
|
|
39458
|
+
action: external_exports.looseObject({
|
|
39459
|
+
type: external_exports.literal("propose_to_request"),
|
|
39460
|
+
href: marketplaceHrefSchema
|
|
39461
|
+
})
|
|
39462
|
+
});
|
|
39463
|
+
var marketplaceHitSchema = external_exports.union([
|
|
39464
|
+
apiMarketplaceHitSchema,
|
|
39465
|
+
serviceOfferMarketplaceHitSchema,
|
|
39466
|
+
openRequestMarketplaceHitSchema
|
|
39467
|
+
]);
|
|
39468
|
+
var marketplaceDiscoveryInputSchema = external_exports.strictObject({
|
|
39469
|
+
q: external_exports.string().trim().max(200).optional(),
|
|
39470
|
+
kinds: external_exports.array(marketplaceKindSchema).min(1).max(MARKETPLACE_KINDS.length).optional(),
|
|
39471
|
+
network: external_exports.string().trim().min(1).max(160).optional(),
|
|
39472
|
+
cursor: external_exports.string().trim().min(1).max(4096).optional(),
|
|
39473
|
+
limit: external_exports.number().int().min(1).max(50).optional(),
|
|
39474
|
+
includeUnverified: external_exports.boolean().optional()
|
|
39475
|
+
}).superRefine((input2, context) => {
|
|
39476
|
+
if (input2.kinds && new Set(input2.kinds).size !== input2.kinds.length) {
|
|
39477
|
+
context.addIssue({
|
|
39478
|
+
code: "custom",
|
|
39479
|
+
path: ["kinds"],
|
|
39480
|
+
message: "Marketplace kinds must be unique"
|
|
39481
|
+
});
|
|
40006
39482
|
}
|
|
40007
|
-
|
|
40008
|
-
|
|
40009
|
-
|
|
40010
|
-
nativeCurrency: definition.gasToken === "USDC" ? { name: "USDC", symbol: "USDC", decimals: USDC_DECIMALS } : { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
40011
|
-
rpcUrls: {
|
|
40012
|
-
default: { http: [rpcUrl] }
|
|
40013
|
-
},
|
|
40014
|
-
...definition.explorerUrl ? {
|
|
40015
|
-
blockExplorers: {
|
|
40016
|
-
default: { name: `${definition.name} explorer`, url: definition.explorerUrl }
|
|
40017
|
-
}
|
|
40018
|
-
} : {}
|
|
40019
|
-
});
|
|
40020
|
-
}
|
|
40021
|
-
function createNetworkPublicClient(network, configured, options = {}) {
|
|
40022
|
-
const rpcUrl = requireRpcUrl(network, configured);
|
|
40023
|
-
return createPublicClient({
|
|
40024
|
-
chain: createChain(network, rpcUrl),
|
|
40025
|
-
transport: createNetworkHttpTransport(rpcUrl, options)
|
|
40026
|
-
});
|
|
40027
|
-
}
|
|
40028
|
-
function createNetworkHttpTransport(rpcUrl, options = {}) {
|
|
40029
|
-
const fetchFn = options.fetch ?? createPublicFetch({
|
|
40030
|
-
allowPrivateNetwork: options.allowPrivateNetwork ?? false,
|
|
40031
|
-
...options.lookup ? { lookup: options.lookup } : {}
|
|
40032
|
-
});
|
|
40033
|
-
return http(rpcUrl, { fetchFn, fetchOptions: { redirect: "manual" } });
|
|
40034
|
-
}
|
|
40035
|
-
function formatUsdc(amountAtomic2) {
|
|
40036
|
-
return formatUnits(amountAtomic2, USDC_DECIMALS);
|
|
39483
|
+
});
|
|
39484
|
+
function isMirroredHit(hit) {
|
|
39485
|
+
return hit.kind === "api" && hit.provenance === "indexed";
|
|
40037
39486
|
}
|
|
39487
|
+
var marketplaceDiscoveryEnvelopeSchema = external_exports.looseObject({
|
|
39488
|
+
protocol: external_exports.literal(MARKETPLACE_DISCOVERY_PROTOCOL),
|
|
39489
|
+
items: external_exports.array(external_exports.unknown()),
|
|
39490
|
+
nextCursor: external_exports.string().min(1).max(4096).nullable(),
|
|
39491
|
+
unavailableKinds: external_exports.array(marketplaceKindSchema).max(MARKETPLACE_KINDS.length),
|
|
39492
|
+
rankingVersion: external_exports.literal(MARKETPLACE_RANKING_VERSION)
|
|
39493
|
+
});
|
|
39494
|
+
var marketplaceDiscoveryPageSchema = marketplaceDiscoveryEnvelopeSchema.extend({
|
|
39495
|
+
items: external_exports.array(marketplaceHitSchema)
|
|
39496
|
+
});
|
|
40038
39497
|
|
|
40039
39498
|
// ../../node_modules/.pnpm/@solana+errors@5.5.1_typescript@6.0.3/node_modules/@solana/errors/dist/index.node.mjs
|
|
40040
39499
|
var SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED = 1;
|
|
@@ -45016,16 +44475,16 @@ var DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;
|
|
|
45016
44475
|
var DEFAULT_COMPUTE_UNIT_LIMIT = 2e4;
|
|
45017
44476
|
var MAX_MEMO_BYTES = 256;
|
|
45018
44477
|
var SOLANA_MAINNET_CAIP22 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
45019
|
-
var
|
|
44478
|
+
var SOLANA_DEVNET_CAIP22 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
|
|
45020
44479
|
var SOLANA_TESTNET_CAIP2 = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";
|
|
45021
44480
|
var V1_TO_V2_NETWORK_MAP = {
|
|
45022
44481
|
solana: SOLANA_MAINNET_CAIP22,
|
|
45023
|
-
"solana-devnet":
|
|
44482
|
+
"solana-devnet": SOLANA_DEVNET_CAIP22,
|
|
45024
44483
|
"solana-testnet": SOLANA_TESTNET_CAIP2
|
|
45025
44484
|
};
|
|
45026
44485
|
function normalizeNetwork(network) {
|
|
45027
44486
|
if (network.includes(":")) {
|
|
45028
|
-
const supported = [SOLANA_MAINNET_CAIP22,
|
|
44487
|
+
const supported = [SOLANA_MAINNET_CAIP22, SOLANA_DEVNET_CAIP22, SOLANA_TESTNET_CAIP2];
|
|
45029
44488
|
if (!supported.includes(network)) {
|
|
45030
44489
|
throw new Error(`Unsupported SVM network: ${network}`);
|
|
45031
44490
|
}
|
|
@@ -45073,7 +44532,7 @@ var DEFAULT_ASSETS = {
|
|
|
45073
44532
|
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS2
|
|
45074
44533
|
}
|
|
45075
44534
|
],
|
|
45076
|
-
[
|
|
44535
|
+
[SOLANA_DEVNET_CAIP22]: [
|
|
45077
44536
|
{
|
|
45078
44537
|
asset: USDC_DEVNET_ADDRESS,
|
|
45079
44538
|
decimals: 6,
|
|
@@ -45128,7 +44587,7 @@ var findDefaultAsset = (asset, network) => {
|
|
|
45128
44587
|
function createRpcClient(network, customRpcUrl) {
|
|
45129
44588
|
const caip2Network = normalizeNetwork(network);
|
|
45130
44589
|
switch (caip2Network) {
|
|
45131
|
-
case
|
|
44590
|
+
case SOLANA_DEVNET_CAIP22: {
|
|
45132
44591
|
const url2 = customRpcUrl || DEVNET_RPC_URL;
|
|
45133
44592
|
return createSolanaRpc(devnet(url2));
|
|
45134
44593
|
}
|
|
@@ -45326,6 +44785,376 @@ var ExactSvmScheme = class {
|
|
|
45326
44785
|
var addressEncoder = getAddressEncoder();
|
|
45327
44786
|
var compiledMessageDecoder = getCompiledTransactionMessageDecoder();
|
|
45328
44787
|
|
|
44788
|
+
// ../core/src/net-guard.ts
|
|
44789
|
+
import { lookup as dnsLookup } from "node:dns/promises";
|
|
44790
|
+
import { request as httpRequest } from "node:http";
|
|
44791
|
+
import { request as httpsRequest } from "node:https";
|
|
44792
|
+
import { isIP } from "node:net";
|
|
44793
|
+
import { Readable } from "node:stream";
|
|
44794
|
+
var defaultLookup = async (hostname3) => {
|
|
44795
|
+
const addresses = await dnsLookup(hostname3, { all: true });
|
|
44796
|
+
return addresses.map(({ address: address4 }) => address4);
|
|
44797
|
+
};
|
|
44798
|
+
async function assertPublicUrl(url2, options) {
|
|
44799
|
+
if (url2.username || url2.password) {
|
|
44800
|
+
throw guardError(url2);
|
|
44801
|
+
}
|
|
44802
|
+
if (url2.protocol !== "http:" && url2.protocol !== "https:") {
|
|
44803
|
+
throw guardError(url2);
|
|
44804
|
+
}
|
|
44805
|
+
if (options.allowPrivateNetwork) {
|
|
44806
|
+
return;
|
|
44807
|
+
}
|
|
44808
|
+
const hostname3 = normalizeHostname(url2.hostname);
|
|
44809
|
+
const lowercaseHostname = hostname3.toLowerCase();
|
|
44810
|
+
if (!lowercaseHostname || lowercaseHostname === "localhost" || lowercaseHostname.endsWith(".localhost") || lowercaseHostname.endsWith(".local") || lowercaseHostname.endsWith(".internal")) {
|
|
44811
|
+
throw guardError(url2);
|
|
44812
|
+
}
|
|
44813
|
+
if (isIP(hostname3)) {
|
|
44814
|
+
if (isNonPublicAddress(hostname3)) {
|
|
44815
|
+
throw guardError(url2);
|
|
44816
|
+
}
|
|
44817
|
+
return;
|
|
44818
|
+
}
|
|
44819
|
+
let addresses;
|
|
44820
|
+
try {
|
|
44821
|
+
addresses = await withTimeout2(
|
|
44822
|
+
(options.lookup ?? defaultLookup)(hostname3),
|
|
44823
|
+
options.timeoutMs ?? 5e3
|
|
44824
|
+
);
|
|
44825
|
+
} catch {
|
|
44826
|
+
throw guardError(url2);
|
|
44827
|
+
}
|
|
44828
|
+
if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
|
|
44829
|
+
throw guardError(url2);
|
|
44830
|
+
}
|
|
44831
|
+
}
|
|
44832
|
+
function createPublicFetch(options) {
|
|
44833
|
+
const lookupFn = options.lookup ?? defaultLookup;
|
|
44834
|
+
return (async (input2, init) => {
|
|
44835
|
+
const url2 = new URL(input2 instanceof Request ? input2.url : input2);
|
|
44836
|
+
await assertPublicUrl(url2, {
|
|
44837
|
+
allowPrivateNetwork: options.allowPrivateNetwork,
|
|
44838
|
+
lookup: lookupFn,
|
|
44839
|
+
timeoutMs: 5e3
|
|
44840
|
+
});
|
|
44841
|
+
const normalized = new Request(input2, init);
|
|
44842
|
+
const bytes = normalized.body ? Buffer.from(await normalized.arrayBuffer()) : null;
|
|
44843
|
+
return await new Promise((resolve2, reject) => {
|
|
44844
|
+
const requestOptions2 = {
|
|
44845
|
+
method: normalized.method,
|
|
44846
|
+
headers: Object.fromEntries(normalized.headers),
|
|
44847
|
+
signal: normalized.signal,
|
|
44848
|
+
...options.allowPrivateNetwork ? {} : { lookup: pinnedLookup(lookupFn) }
|
|
44849
|
+
};
|
|
44850
|
+
const onResponse = (incoming) => {
|
|
44851
|
+
try {
|
|
44852
|
+
const headers = new Headers();
|
|
44853
|
+
for (const [name, value] of Object.entries(incoming.headers)) {
|
|
44854
|
+
if (Array.isArray(value)) {
|
|
44855
|
+
for (const item of value) headers.append(name, item);
|
|
44856
|
+
} else if (value !== void 0) {
|
|
44857
|
+
headers.set(name, value);
|
|
44858
|
+
}
|
|
44859
|
+
}
|
|
44860
|
+
const status = incoming.statusCode ?? 500;
|
|
44861
|
+
const bodyForbidden = normalized.method === "HEAD" || [204, 205, 304].includes(status);
|
|
44862
|
+
if (bodyForbidden) incoming.resume();
|
|
44863
|
+
const response = new Response(
|
|
44864
|
+
bodyForbidden ? null : Readable.toWeb(incoming),
|
|
44865
|
+
{ status, statusText: incoming.statusMessage, headers }
|
|
44866
|
+
);
|
|
44867
|
+
Object.defineProperty(response, "url", { value: url2.toString() });
|
|
44868
|
+
resolve2(response);
|
|
44869
|
+
} catch (error61) {
|
|
44870
|
+
incoming.destroy();
|
|
44871
|
+
reject(error61);
|
|
44872
|
+
}
|
|
44873
|
+
};
|
|
44874
|
+
const request = url2.protocol === "https:" ? httpsRequest(url2, requestOptions2, onResponse) : httpRequest(url2, requestOptions2, onResponse);
|
|
44875
|
+
request.on("error", reject);
|
|
44876
|
+
if (bytes) request.write(bytes);
|
|
44877
|
+
request.end();
|
|
44878
|
+
});
|
|
44879
|
+
});
|
|
44880
|
+
}
|
|
44881
|
+
function pinnedLookup(lookup2) {
|
|
44882
|
+
return (hostname3, dnsOptions, callback) => {
|
|
44883
|
+
void lookup2(normalizeHostname(hostname3)).then((addresses) => {
|
|
44884
|
+
if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
|
|
44885
|
+
callback(guardError(new URL(`https://${hostname3}`)), "");
|
|
44886
|
+
return;
|
|
44887
|
+
}
|
|
44888
|
+
const address4 = addresses[0];
|
|
44889
|
+
const family = isIP(address4);
|
|
44890
|
+
callback(
|
|
44891
|
+
null,
|
|
44892
|
+
dnsOptions.all ? [{ address: address4, family }] : address4,
|
|
44893
|
+
dnsOptions.all ? void 0 : family
|
|
44894
|
+
);
|
|
44895
|
+
}).catch(
|
|
44896
|
+
(error61) => callback(error61 instanceof Error ? error61 : new Error("DNS lookup failed."), "")
|
|
44897
|
+
);
|
|
44898
|
+
};
|
|
44899
|
+
}
|
|
44900
|
+
async function withTimeout2(operation, timeoutMs) {
|
|
44901
|
+
let timeout;
|
|
44902
|
+
try {
|
|
44903
|
+
return await Promise.race([
|
|
44904
|
+
operation,
|
|
44905
|
+
new Promise((_resolve, reject) => {
|
|
44906
|
+
timeout = setTimeout(() => reject(new Error("DNS lookup timed out.")), timeoutMs);
|
|
44907
|
+
})
|
|
44908
|
+
]);
|
|
44909
|
+
} finally {
|
|
44910
|
+
if (timeout) clearTimeout(timeout);
|
|
44911
|
+
}
|
|
44912
|
+
}
|
|
44913
|
+
function normalizeHostname(hostname3) {
|
|
44914
|
+
const unbracketed = hostname3.startsWith("[") && hostname3.endsWith("]") ? hostname3.slice(1, -1) : hostname3;
|
|
44915
|
+
return unbracketed.endsWith(".") ? unbracketed.slice(0, -1) : unbracketed;
|
|
44916
|
+
}
|
|
44917
|
+
function isNonPublicAddress(address4) {
|
|
44918
|
+
const normalized = normalizeHostname(address4);
|
|
44919
|
+
const version5 = isIP(normalized);
|
|
44920
|
+
if (version5 === 4) {
|
|
44921
|
+
return isNonPublicIpv4(parseIpv4(normalized));
|
|
44922
|
+
}
|
|
44923
|
+
if (version5 === 6) {
|
|
44924
|
+
return isNonPublicIpv6(parseIpv6(normalized));
|
|
44925
|
+
}
|
|
44926
|
+
return true;
|
|
44927
|
+
}
|
|
44928
|
+
function parseIpv4(address4) {
|
|
44929
|
+
const octets = address4.split(".").map(Number);
|
|
44930
|
+
return [octets[0], octets[1], octets[2], octets[3]];
|
|
44931
|
+
}
|
|
44932
|
+
function isNonPublicIpv4([first, second, third]) {
|
|
44933
|
+
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;
|
|
44934
|
+
}
|
|
44935
|
+
function parseIpv6(address4) {
|
|
44936
|
+
let normalized = address4.toLowerCase();
|
|
44937
|
+
const lastColon = normalized.lastIndexOf(":");
|
|
44938
|
+
const dottedTail = normalized.slice(lastColon + 1);
|
|
44939
|
+
if (dottedTail.includes(".")) {
|
|
44940
|
+
const [first, second, third, fourth] = parseIpv4(dottedTail);
|
|
44941
|
+
normalized = `${normalized.slice(0, lastColon + 1)}${(first << 8 | second).toString(16)}:${(third << 8 | fourth).toString(16)}`;
|
|
44942
|
+
}
|
|
44943
|
+
const halves = normalized.split("::");
|
|
44944
|
+
const left = halves[0] ? halves[0].split(":").map(parseHex) : [];
|
|
44945
|
+
const right = halves[1] ? halves[1].split(":").map(parseHex) : [];
|
|
44946
|
+
const omittedCount = 8 - left.length - right.length;
|
|
44947
|
+
return halves.length === 2 ? [...left, ...Array.from({ length: omittedCount }, () => 0), ...right] : left;
|
|
44948
|
+
}
|
|
44949
|
+
function parseHex(value) {
|
|
44950
|
+
return Number.parseInt(value, 16);
|
|
44951
|
+
}
|
|
44952
|
+
function isNonPublicIpv6(hextets) {
|
|
44953
|
+
if (hextets.slice(0, 5).every((hextet) => hextet === 0) && hextets[5] === 65535) {
|
|
44954
|
+
const embeddedIpv4 = [
|
|
44955
|
+
hextets[6] >> 8,
|
|
44956
|
+
hextets[6] & 255,
|
|
44957
|
+
hextets[7] >> 8,
|
|
44958
|
+
hextets[7] & 255
|
|
44959
|
+
];
|
|
44960
|
+
return isNonPublicIpv4(embeddedIpv4);
|
|
44961
|
+
}
|
|
44962
|
+
if (hextets.slice(0, 6).every((hextet) => hextet === 0)) {
|
|
44963
|
+
const compatibleIpv4 = [
|
|
44964
|
+
hextets[6] >> 8,
|
|
44965
|
+
hextets[6] & 255,
|
|
44966
|
+
hextets[7] >> 8,
|
|
44967
|
+
hextets[7] & 255
|
|
44968
|
+
];
|
|
44969
|
+
if (isNonPublicIpv4(compatibleIpv4)) return true;
|
|
44970
|
+
}
|
|
44971
|
+
const isUnspecified = hextets.every((hextet) => hextet === 0);
|
|
44972
|
+
const isLoopback = hextets.slice(0, 7).every((hextet) => hextet === 0) && hextets[7] === 1;
|
|
44973
|
+
const first = hextets[0];
|
|
44974
|
+
const isUniqueLocal = first >= 64512 && first <= 65023;
|
|
44975
|
+
const isLinkLocal = first >= 65152 && first <= 65215;
|
|
44976
|
+
const isSiteLocal = first >= 65216 && first <= 65279;
|
|
44977
|
+
const isMulticast = first >= 65280;
|
|
44978
|
+
const isDocumentation = first === 8193 && hextets[1] === 3512;
|
|
44979
|
+
return isUnspecified || isLoopback || isUniqueLocal || isLinkLocal || isSiteLocal || isMulticast || isDocumentation;
|
|
44980
|
+
}
|
|
44981
|
+
function guardError(url2) {
|
|
44982
|
+
return new Error(
|
|
44983
|
+
`URL hostname ${JSON.stringify(url2.hostname)} is not allowed; private or internal destinations require allowPrivateNetwork true in the vAPI config.`
|
|
44984
|
+
);
|
|
44985
|
+
}
|
|
44986
|
+
|
|
44987
|
+
// ../core/src/networks.ts
|
|
44988
|
+
var USDC_DECIMALS = 6;
|
|
44989
|
+
var DEFAULT_ARC_GAS_HEADROOM_ATOMIC = 50000n;
|
|
44990
|
+
var NETWORKS2 = {
|
|
44991
|
+
[BASE_MAINNET_CAIP2]: {
|
|
44992
|
+
family: "evm",
|
|
44993
|
+
chainId: 8453,
|
|
44994
|
+
name: "Base mainnet",
|
|
44995
|
+
usdc: CANONICAL_X402_USDC_NETWORKS[BASE_MAINNET_CAIP2].usdc,
|
|
44996
|
+
gasToken: "ETH",
|
|
44997
|
+
rpcEnv: "BASE_RPC_URL",
|
|
44998
|
+
publicRpcUrl: "https://mainnet.base.org",
|
|
44999
|
+
explorerUrl: "https://basescan.org"
|
|
45000
|
+
},
|
|
45001
|
+
[ARC_MAINNET_CAIP2]: {
|
|
45002
|
+
family: "evm",
|
|
45003
|
+
chainId: 5042,
|
|
45004
|
+
name: "Arc mainnet",
|
|
45005
|
+
usdc: CANONICAL_X402_USDC_NETWORKS[ARC_MAINNET_CAIP2].usdc,
|
|
45006
|
+
gasToken: "USDC",
|
|
45007
|
+
rpcEnv: "ARC_RPC_URL",
|
|
45008
|
+
publicRpcUrl: "https://rpc.mainnet.arc.io",
|
|
45009
|
+
explorerUrl: "https://explorer.arc.io"
|
|
45010
|
+
},
|
|
45011
|
+
[ARC_TESTNET_CAIP2]: {
|
|
45012
|
+
family: "evm",
|
|
45013
|
+
chainId: 5042002,
|
|
45014
|
+
name: "Arc testnet",
|
|
45015
|
+
usdc: CANONICAL_X402_USDC_NETWORKS[ARC_TESTNET_CAIP2].usdc,
|
|
45016
|
+
gasToken: "USDC",
|
|
45017
|
+
rpcEnv: "ARC_TESTNET_RPC_URL"
|
|
45018
|
+
},
|
|
45019
|
+
[SOLANA_MAINNET_CAIP2]: {
|
|
45020
|
+
family: "svm",
|
|
45021
|
+
name: "Solana mainnet",
|
|
45022
|
+
usdc: SOLANA_MAINNET_USDC,
|
|
45023
|
+
gasToken: "SOL",
|
|
45024
|
+
rpcEnv: "SOLANA_RPC_URL",
|
|
45025
|
+
publicRpcUrl: "https://api.mainnet-beta.solana.com"
|
|
45026
|
+
},
|
|
45027
|
+
[X402_SOLANA_MAINNET_CAIP2]: {
|
|
45028
|
+
family: "svm",
|
|
45029
|
+
name: "Solana mainnet",
|
|
45030
|
+
usdc: SOLANA_MAINNET_USDC,
|
|
45031
|
+
gasToken: "SOL",
|
|
45032
|
+
rpcEnv: "SOLANA_RPC_URL",
|
|
45033
|
+
publicRpcUrl: "https://api.mainnet-beta.solana.com"
|
|
45034
|
+
}
|
|
45035
|
+
};
|
|
45036
|
+
function parseEip155ChainId(network) {
|
|
45037
|
+
const match = /^eip155:(\d+)$/.exec(network);
|
|
45038
|
+
if (!match) {
|
|
45039
|
+
throw new Error(`Unsupported network ${network}; expected eip155:<chainId>.`);
|
|
45040
|
+
}
|
|
45041
|
+
const chainId = Number(match[1]);
|
|
45042
|
+
if (!Number.isSafeInteger(chainId) || chainId <= 0) {
|
|
45043
|
+
throw new Error(`Invalid EVM chain ID in network ${network}.`);
|
|
45044
|
+
}
|
|
45045
|
+
return chainId;
|
|
45046
|
+
}
|
|
45047
|
+
function isSolanaNetwork(network) {
|
|
45048
|
+
return network === SOLANA_MAINNET_CAIP2 || network === X402_SOLANA_MAINNET_CAIP2;
|
|
45049
|
+
}
|
|
45050
|
+
function usesUsdcGas(network) {
|
|
45051
|
+
try {
|
|
45052
|
+
return getNetworkDefinition(network).gasToken === "USDC";
|
|
45053
|
+
} catch {
|
|
45054
|
+
return false;
|
|
45055
|
+
}
|
|
45056
|
+
}
|
|
45057
|
+
function explorerTransactionUrl(network, hash5) {
|
|
45058
|
+
try {
|
|
45059
|
+
const explorerUrl = getNetworkDefinition(network).explorerUrl;
|
|
45060
|
+
return explorerUrl ? `${explorerUrl}/tx/${hash5}` : void 0;
|
|
45061
|
+
} catch {
|
|
45062
|
+
return void 0;
|
|
45063
|
+
}
|
|
45064
|
+
}
|
|
45065
|
+
function explorerAddressUrl(network, address4) {
|
|
45066
|
+
try {
|
|
45067
|
+
const explorerUrl = getNetworkDefinition(network).explorerUrl;
|
|
45068
|
+
return explorerUrl ? `${explorerUrl}/address/${address4}` : void 0;
|
|
45069
|
+
} catch {
|
|
45070
|
+
return void 0;
|
|
45071
|
+
}
|
|
45072
|
+
}
|
|
45073
|
+
function areSamePaymentNetwork(left, right) {
|
|
45074
|
+
return left === right || isSolanaNetwork(left) && isSolanaNetwork(right);
|
|
45075
|
+
}
|
|
45076
|
+
function isSupportedPaymentNetwork(network) {
|
|
45077
|
+
if (isSolanaNetwork(network)) return true;
|
|
45078
|
+
try {
|
|
45079
|
+
parseEip155ChainId(network);
|
|
45080
|
+
return true;
|
|
45081
|
+
} catch {
|
|
45082
|
+
return false;
|
|
45083
|
+
}
|
|
45084
|
+
}
|
|
45085
|
+
function configuredNetworkFor(networks, network) {
|
|
45086
|
+
const configured = networks[network];
|
|
45087
|
+
if (configured) return configured;
|
|
45088
|
+
if (network === X402_SOLANA_MAINNET_CAIP2) return networks[SOLANA_MAINNET_CAIP2];
|
|
45089
|
+
if (network === SOLANA_MAINNET_CAIP2) return networks[X402_SOLANA_MAINNET_CAIP2];
|
|
45090
|
+
return void 0;
|
|
45091
|
+
}
|
|
45092
|
+
function getNetworkDefinition(network) {
|
|
45093
|
+
const known = NETWORKS2[network];
|
|
45094
|
+
if (known) {
|
|
45095
|
+
return known;
|
|
45096
|
+
}
|
|
45097
|
+
const chainId = parseEip155ChainId(network);
|
|
45098
|
+
return {
|
|
45099
|
+
family: "evm",
|
|
45100
|
+
chainId,
|
|
45101
|
+
name: network,
|
|
45102
|
+
usdc: getAddress("0x0000000000000000000000000000000000000000"),
|
|
45103
|
+
gasToken: "ETH",
|
|
45104
|
+
rpcEnv: ""
|
|
45105
|
+
};
|
|
45106
|
+
}
|
|
45107
|
+
function requireRpcUrl(network, configured) {
|
|
45108
|
+
const definition = getNetworkDefinition(network);
|
|
45109
|
+
const envUrl = definition.rpcEnv ? process.env[definition.rpcEnv]?.trim() : void 0;
|
|
45110
|
+
const rpcUrl = envUrl || configured.rpcUrl.trim();
|
|
45111
|
+
if (rpcUrl) {
|
|
45112
|
+
return rpcUrl;
|
|
45113
|
+
}
|
|
45114
|
+
if (network === ARC_TESTNET_CAIP2) {
|
|
45115
|
+
throw new Error(
|
|
45116
|
+
"Arc testnet RPC is required. Set ARC_TESTNET_RPC_URL or add rpcUrl for eip155:5042002 in config.json."
|
|
45117
|
+
);
|
|
45118
|
+
}
|
|
45119
|
+
throw new Error(`RPC URL is required for ${network}.`);
|
|
45120
|
+
}
|
|
45121
|
+
function createChain(network, rpcUrl) {
|
|
45122
|
+
const definition = getNetworkDefinition(network);
|
|
45123
|
+
if (definition.family !== "evm" || definition.chainId === void 0) {
|
|
45124
|
+
throw new Error(`Network ${network} is not an EVM chain.`);
|
|
45125
|
+
}
|
|
45126
|
+
return defineChain({
|
|
45127
|
+
id: definition.chainId,
|
|
45128
|
+
name: definition.name,
|
|
45129
|
+
nativeCurrency: definition.gasToken === "USDC" ? { name: "USDC", symbol: "USDC", decimals: USDC_DECIMALS } : { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
45130
|
+
rpcUrls: {
|
|
45131
|
+
default: { http: [rpcUrl] }
|
|
45132
|
+
},
|
|
45133
|
+
...definition.explorerUrl ? {
|
|
45134
|
+
blockExplorers: {
|
|
45135
|
+
default: { name: `${definition.name} explorer`, url: definition.explorerUrl }
|
|
45136
|
+
}
|
|
45137
|
+
} : {}
|
|
45138
|
+
});
|
|
45139
|
+
}
|
|
45140
|
+
function createNetworkPublicClient(network, configured, options = {}) {
|
|
45141
|
+
const rpcUrl = requireRpcUrl(network, configured);
|
|
45142
|
+
return createPublicClient({
|
|
45143
|
+
chain: createChain(network, rpcUrl),
|
|
45144
|
+
transport: createNetworkHttpTransport(rpcUrl, options)
|
|
45145
|
+
});
|
|
45146
|
+
}
|
|
45147
|
+
function createNetworkHttpTransport(rpcUrl, options = {}) {
|
|
45148
|
+
const fetchFn = options.fetch ?? createPublicFetch({
|
|
45149
|
+
allowPrivateNetwork: options.allowPrivateNetwork ?? false,
|
|
45150
|
+
...options.lookup ? { lookup: options.lookup } : {}
|
|
45151
|
+
});
|
|
45152
|
+
return http(rpcUrl, { fetchFn, fetchOptions: { redirect: "manual" } });
|
|
45153
|
+
}
|
|
45154
|
+
function formatUsdc(amountAtomic2) {
|
|
45155
|
+
return formatUnits(amountAtomic2, USDC_DECIMALS);
|
|
45156
|
+
}
|
|
45157
|
+
|
|
45329
45158
|
// ../core/src/x402.ts
|
|
45330
45159
|
var MAX_CHALLENGE_BYTES = 1048576;
|
|
45331
45160
|
var MAX_UINT256 = (1n << 256n) - 1n;
|
|
@@ -46185,6 +46014,242 @@ function isRecord2(value) {
|
|
|
46185
46014
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46186
46015
|
}
|
|
46187
46016
|
|
|
46017
|
+
// ../core/src/call-contracts-wire.ts
|
|
46018
|
+
var CALLABLE_CATEGORIES = ["ai", "data", "crypto", "compute", "search"];
|
|
46019
|
+
var callableCategorySchema = external_exports.enum(CALLABLE_CATEGORIES);
|
|
46020
|
+
var DISCOVERY_CATEGORIES = [...CALLABLE_CATEGORIES, "other"];
|
|
46021
|
+
var discoveryCategorySchema = external_exports.string().trim().min(1);
|
|
46022
|
+
var CALLABLE_CATEGORY_SET = new Set(CALLABLE_CATEGORIES);
|
|
46023
|
+
var serviceTierSchema = external_exports.string().trim().min(1);
|
|
46024
|
+
var discoveryEndpointSchema = external_exports.looseObject({
|
|
46025
|
+
name: external_exports.string(),
|
|
46026
|
+
method: external_exports.string(),
|
|
46027
|
+
url: external_exports.url(),
|
|
46028
|
+
price: external_exports.string(),
|
|
46029
|
+
description: external_exports.string(),
|
|
46030
|
+
operationId: external_exports.string().trim().min(1).optional(),
|
|
46031
|
+
requestContentType: external_exports.string().trim().min(1).optional(),
|
|
46032
|
+
requestSchema: external_exports.json().optional(),
|
|
46033
|
+
responseContentType: external_exports.string().trim().min(1).optional(),
|
|
46034
|
+
pathTemplate: external_exports.string().trim().min(1).optional(),
|
|
46035
|
+
pathParameters: external_exports.array(external_exports.string().trim().min(1)).optional(),
|
|
46036
|
+
payment: external_exports.union([
|
|
46037
|
+
external_exports.looseObject({
|
|
46038
|
+
scheme: external_exports.literal("exact"),
|
|
46039
|
+
network: external_exports.string().regex(/^eip155:\d+$/),
|
|
46040
|
+
asset: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
|
|
46041
|
+
payTo: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
|
|
46042
|
+
checkedAt: external_exports.iso.datetime()
|
|
46043
|
+
}),
|
|
46044
|
+
external_exports.looseObject({
|
|
46045
|
+
scheme: external_exports.literal("exact"),
|
|
46046
|
+
network: external_exports.union([
|
|
46047
|
+
external_exports.string().regex(/^solana:[-_a-zA-Z0-9]{1,32}$/),
|
|
46048
|
+
external_exports.literal(SOLANA_MAINNET_CAIP2)
|
|
46049
|
+
]),
|
|
46050
|
+
asset: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
|
|
46051
|
+
payTo: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
|
|
46052
|
+
checkedAt: external_exports.iso.datetime()
|
|
46053
|
+
}),
|
|
46054
|
+
external_exports.looseObject({
|
|
46055
|
+
protocol: external_exports.literal("mpp"),
|
|
46056
|
+
intent: external_exports.enum(["charge", "authorize", "subscription"]).nullable(),
|
|
46057
|
+
method: external_exports.string().trim().min(1).max(40).nullable(),
|
|
46058
|
+
checkedAt: external_exports.iso.datetime(),
|
|
46059
|
+
// Keep common x402 properties readable on the union while making it
|
|
46060
|
+
// impossible for MPP metadata to masquerade as executable x402 terms.
|
|
46061
|
+
network: external_exports.never().optional(),
|
|
46062
|
+
payTo: external_exports.never().optional()
|
|
46063
|
+
}),
|
|
46064
|
+
external_exports.looseObject({
|
|
46065
|
+
// Future payment protocols remain visible to callers so the payment
|
|
46066
|
+
// layer can refuse them explicitly instead of discovery losing the row.
|
|
46067
|
+
protocol: external_exports.string().trim().min(1).max(40),
|
|
46068
|
+
checkedAt: external_exports.iso.datetime(),
|
|
46069
|
+
network: external_exports.never().optional(),
|
|
46070
|
+
payTo: external_exports.never().optional()
|
|
46071
|
+
})
|
|
46072
|
+
]).optional()
|
|
46073
|
+
});
|
|
46074
|
+
var serviceSummarySchema = external_exports.looseObject({
|
|
46075
|
+
id: external_exports.string(),
|
|
46076
|
+
name: external_exports.string(),
|
|
46077
|
+
description: external_exports.string(),
|
|
46078
|
+
category: discoveryCategorySchema,
|
|
46079
|
+
tier: serviceTierSchema,
|
|
46080
|
+
...listingDisclosureShape,
|
|
46081
|
+
verified: external_exports.boolean(),
|
|
46082
|
+
wrapped: external_exports.boolean(),
|
|
46083
|
+
price: external_exports.string(),
|
|
46084
|
+
networks: external_exports.array(external_exports.string()),
|
|
46085
|
+
endpoints: external_exports.array(discoveryEndpointSchema)
|
|
46086
|
+
});
|
|
46087
|
+
var searchServicesResponseSchema = external_exports.looseObject({
|
|
46088
|
+
services: external_exports.array(serviceSummarySchema)
|
|
46089
|
+
});
|
|
46090
|
+
var discoveryResponseSchema = searchServicesResponseSchema;
|
|
46091
|
+
|
|
46092
|
+
// ../core/src/call-contracts.ts
|
|
46093
|
+
var DiscoveryCatalogError = class extends Error {
|
|
46094
|
+
constructor(code, message, serviceId, paymentNetworks) {
|
|
46095
|
+
super(message);
|
|
46096
|
+
this.paymentNetworks = paymentNetworks;
|
|
46097
|
+
this.code = code;
|
|
46098
|
+
this.serviceId = serviceId;
|
|
46099
|
+
}
|
|
46100
|
+
paymentNetworks;
|
|
46101
|
+
name = "DiscoveryCatalogError";
|
|
46102
|
+
code;
|
|
46103
|
+
serviceId;
|
|
46104
|
+
};
|
|
46105
|
+
function isDiscoveryCatalogError(error61) {
|
|
46106
|
+
if (!(error61 instanceof Error) || error61.name !== "DiscoveryCatalogError" || !("code" in error61) || typeof error61.code !== "string") {
|
|
46107
|
+
return false;
|
|
46108
|
+
}
|
|
46109
|
+
const networks = Reflect.get(error61, "paymentNetworks");
|
|
46110
|
+
return networks === void 0 || Array.isArray(networks) && networks.every((network) => typeof network === "string");
|
|
46111
|
+
}
|
|
46112
|
+
function parseDiscovery(raw) {
|
|
46113
|
+
const parsed = discoveryResponseSchema.safeParse(raw);
|
|
46114
|
+
if (!parsed.success) {
|
|
46115
|
+
const malformedUrl = parsed.error.issues.find(
|
|
46116
|
+
(issue2) => issue2.path.at(-1) === "url" && issue2.path.includes("endpoints")
|
|
46117
|
+
);
|
|
46118
|
+
if (malformedUrl) {
|
|
46119
|
+
const serviceIndex = pathIndexAfter(malformedUrl.path, "services");
|
|
46120
|
+
const serviceId = rawServiceId(raw, serviceIndex);
|
|
46121
|
+
throw new DiscoveryCatalogError(
|
|
46122
|
+
"malformed_url",
|
|
46123
|
+
`Service ${JSON.stringify(serviceId ?? "unknown")} has a malformed endpoint URL.`,
|
|
46124
|
+
serviceId
|
|
46125
|
+
);
|
|
46126
|
+
}
|
|
46127
|
+
throw new DiscoveryCatalogError("invalid_discovery", "Discovery response is malformed.");
|
|
46128
|
+
}
|
|
46129
|
+
for (const service of parsed.data.services) {
|
|
46130
|
+
buildTargets(service);
|
|
46131
|
+
}
|
|
46132
|
+
const resolveListing = (serviceId, endpointName) => {
|
|
46133
|
+
const service = parsed.data.services.find((candidate) => candidate.id === serviceId);
|
|
46134
|
+
if (!service) {
|
|
46135
|
+
throw new DiscoveryCatalogError(
|
|
46136
|
+
"service_not_found",
|
|
46137
|
+
`No payable endpoint found for service ${JSON.stringify(serviceId)}.`,
|
|
46138
|
+
serviceId
|
|
46139
|
+
);
|
|
46140
|
+
}
|
|
46141
|
+
return { service, endpoint: resolveTarget(service, endpointName) };
|
|
46142
|
+
};
|
|
46143
|
+
return {
|
|
46144
|
+
services: parsed.data.services,
|
|
46145
|
+
resolve: (serviceId, endpointName) => resolveListing(serviceId, endpointName).endpoint,
|
|
46146
|
+
resolveListing
|
|
46147
|
+
};
|
|
46148
|
+
}
|
|
46149
|
+
function resolveTarget(service, endpointName) {
|
|
46150
|
+
const { targets, targetsByName } = buildTargets(service);
|
|
46151
|
+
if (endpointName !== void 0) {
|
|
46152
|
+
const selected = targetsByName.get(endpointName.trim());
|
|
46153
|
+
if (!selected) {
|
|
46154
|
+
throw new DiscoveryCatalogError(
|
|
46155
|
+
"endpoint_not_found",
|
|
46156
|
+
`Service ${JSON.stringify(service.id)} has no endpoint ${JSON.stringify(endpointName)}. Available endpoints: ${[...targetsByName.keys()].join(", ")}.`,
|
|
46157
|
+
service.id
|
|
46158
|
+
);
|
|
46159
|
+
}
|
|
46160
|
+
return { ...selected };
|
|
46161
|
+
}
|
|
46162
|
+
if (targets.size !== 1) {
|
|
46163
|
+
const paymentNetworks = service.endpoints.flatMap(
|
|
46164
|
+
(endpoint) => typeof endpoint.payment?.network === "string" ? [endpoint.payment.network] : []
|
|
46165
|
+
);
|
|
46166
|
+
throw new DiscoveryCatalogError(
|
|
46167
|
+
"ambiguous_default",
|
|
46168
|
+
`Service ${JSON.stringify(service.id)} has ${targets.size} distinct payable endpoints. Choose one with endpoint: ${[...targetsByName.keys()].join(", ")}.`,
|
|
46169
|
+
service.id,
|
|
46170
|
+
paymentNetworks.length === service.endpoints.length ? paymentNetworks : void 0
|
|
46171
|
+
);
|
|
46172
|
+
}
|
|
46173
|
+
return targets.values().next().value;
|
|
46174
|
+
}
|
|
46175
|
+
function buildTargets(service) {
|
|
46176
|
+
if (service.endpoints.length === 0) {
|
|
46177
|
+
throw new DiscoveryCatalogError(
|
|
46178
|
+
"no_endpoint",
|
|
46179
|
+
`Service ${JSON.stringify(service.id)} has no payable endpoint.`,
|
|
46180
|
+
service.id
|
|
46181
|
+
);
|
|
46182
|
+
}
|
|
46183
|
+
const namedEndpoints = [...service.endpoints].sort(
|
|
46184
|
+
(left, right) => compareNames(left.name.trim(), right.name.trim())
|
|
46185
|
+
);
|
|
46186
|
+
const names = /* @__PURE__ */ new Set();
|
|
46187
|
+
const targets = /* @__PURE__ */ new Map();
|
|
46188
|
+
const targetsByName = /* @__PURE__ */ new Map();
|
|
46189
|
+
for (const endpoint of namedEndpoints) {
|
|
46190
|
+
const name = endpoint.name.trim();
|
|
46191
|
+
if (!name) {
|
|
46192
|
+
throw new DiscoveryCatalogError(
|
|
46193
|
+
"invalid_endpoint_name",
|
|
46194
|
+
`Service ${JSON.stringify(service.id)} has a blank endpoint name.`,
|
|
46195
|
+
service.id
|
|
46196
|
+
);
|
|
46197
|
+
}
|
|
46198
|
+
if (names.has(name)) {
|
|
46199
|
+
throw new DiscoveryCatalogError(
|
|
46200
|
+
"duplicate_endpoint_name",
|
|
46201
|
+
`Service ${JSON.stringify(service.id)} has duplicate endpoint name ${JSON.stringify(name)}.`,
|
|
46202
|
+
service.id
|
|
46203
|
+
);
|
|
46204
|
+
}
|
|
46205
|
+
names.add(name);
|
|
46206
|
+
const method = endpoint.method.trim().toUpperCase();
|
|
46207
|
+
if (!method) {
|
|
46208
|
+
throw new DiscoveryCatalogError(
|
|
46209
|
+
"blank_method",
|
|
46210
|
+
`Service ${JSON.stringify(service.id)} has a blank endpoint method.`,
|
|
46211
|
+
service.id
|
|
46212
|
+
);
|
|
46213
|
+
}
|
|
46214
|
+
const url2 = new URL(endpoint.url);
|
|
46215
|
+
if (url2.protocol !== "http:" && url2.protocol !== "https:") {
|
|
46216
|
+
throw new DiscoveryCatalogError(
|
|
46217
|
+
"malformed_url",
|
|
46218
|
+
`Service ${JSON.stringify(service.id)} has a non-HTTP endpoint URL.`,
|
|
46219
|
+
service.id
|
|
46220
|
+
);
|
|
46221
|
+
}
|
|
46222
|
+
const transportKey = `${method}\0${endpoint.url}`;
|
|
46223
|
+
const normalized = { ...endpoint, name, method };
|
|
46224
|
+
targetsByName.set(name, normalized);
|
|
46225
|
+
if (!targets.has(transportKey)) targets.set(transportKey, normalized);
|
|
46226
|
+
}
|
|
46227
|
+
return { targets, targetsByName };
|
|
46228
|
+
}
|
|
46229
|
+
function compareNames(left, right) {
|
|
46230
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
46231
|
+
}
|
|
46232
|
+
function pathIndexAfter(path, key2) {
|
|
46233
|
+
const keyIndex = path.indexOf(key2);
|
|
46234
|
+
const candidate = path[keyIndex + 1];
|
|
46235
|
+
return typeof candidate === "number" ? candidate : void 0;
|
|
46236
|
+
}
|
|
46237
|
+
function rawServiceId(raw, serviceIndex) {
|
|
46238
|
+
if (serviceIndex === void 0 || typeof raw !== "object" || raw === null) {
|
|
46239
|
+
return void 0;
|
|
46240
|
+
}
|
|
46241
|
+
const services = Reflect.get(raw, "services");
|
|
46242
|
+
if (!Array.isArray(services)) {
|
|
46243
|
+
return void 0;
|
|
46244
|
+
}
|
|
46245
|
+
const service = services[serviceIndex];
|
|
46246
|
+
if (typeof service !== "object" || service === null) {
|
|
46247
|
+
return void 0;
|
|
46248
|
+
}
|
|
46249
|
+
const id2 = Reflect.get(service, "id");
|
|
46250
|
+
return typeof id2 === "string" ? id2 : void 0;
|
|
46251
|
+
}
|
|
46252
|
+
|
|
46188
46253
|
// ../core/src/sweep.ts
|
|
46189
46254
|
var ERC20_ABI = [
|
|
46190
46255
|
{
|
|
@@ -47033,7 +47098,7 @@ var configSchema = external_exports.object({
|
|
|
47033
47098
|
}
|
|
47034
47099
|
for (const [network, configured] of Object.entries(config2.networks)) {
|
|
47035
47100
|
if (isSolanaNetwork(network)) {
|
|
47036
|
-
if (configured.usdc !==
|
|
47101
|
+
if (configured.usdc !== NETWORKS2[SOLANA_MAINNET_CAIP2].usdc) {
|
|
47037
47102
|
context.addIssue({
|
|
47038
47103
|
code: "custom",
|
|
47039
47104
|
path: ["networks", network, "usdc"],
|
|
@@ -47044,7 +47109,7 @@ var configSchema = external_exports.object({
|
|
|
47044
47109
|
}
|
|
47045
47110
|
try {
|
|
47046
47111
|
const usdc = getAddress(configured.usdc);
|
|
47047
|
-
if ((network === ARC_MAINNET_CAIP2 || network === ARC_TESTNET_CAIP2) && usdc !== getAddress(
|
|
47112
|
+
if ((network === ARC_MAINNET_CAIP2 || network === ARC_TESTNET_CAIP2) && usdc !== getAddress(NETWORKS2[network].usdc)) {
|
|
47048
47113
|
context.addIssue({
|
|
47049
47114
|
code: "custom",
|
|
47050
47115
|
path: ["networks", network, "usdc"],
|
|
@@ -47071,7 +47136,8 @@ function getVapiPaths(directory = process.env.VAPI_HOME?.trim() || join2(homedir
|
|
|
47071
47136
|
keystore: join2(directory, "keystore.json"),
|
|
47072
47137
|
receipts: join2(directory, "receipts.jsonl"),
|
|
47073
47138
|
searches: join2(directory, "searches.jsonl"),
|
|
47074
|
-
ledger: join2(directory, "spend-ledger.json")
|
|
47139
|
+
ledger: join2(directory, "spend-ledger.json"),
|
|
47140
|
+
updateCheck: join2(directory, "update-check.json")
|
|
47075
47141
|
};
|
|
47076
47142
|
}
|
|
47077
47143
|
var getAgentCashPaths = getVapiPaths;
|
|
@@ -47196,15 +47262,15 @@ function getDefaultConfig(source = process.env, options = {}) {
|
|
|
47196
47262
|
const tasksEscrowFactoryOverrides = tasksFactoryOverridesFromEnv(source);
|
|
47197
47263
|
if (requested.has("base") || requested.has(BASE_MAINNET_CAIP2)) {
|
|
47198
47264
|
networks[BASE_MAINNET_CAIP2] = {
|
|
47199
|
-
rpcUrl: source.BASE_RPC_URL?.trim() ||
|
|
47200
|
-
usdc:
|
|
47265
|
+
rpcUrl: source.BASE_RPC_URL?.trim() || NETWORKS2[BASE_MAINNET_CAIP2].publicRpcUrl,
|
|
47266
|
+
usdc: NETWORKS2[BASE_MAINNET_CAIP2].usdc
|
|
47201
47267
|
};
|
|
47202
47268
|
}
|
|
47203
47269
|
const arcMainnetRpcUrl = source.ARC_RPC_URL?.trim();
|
|
47204
47270
|
if (arcMainnetRpcUrl || requested.has("arc") || requested.has(ARC_MAINNET_CAIP2)) {
|
|
47205
47271
|
networks[ARC_MAINNET_CAIP2] = {
|
|
47206
|
-
rpcUrl: arcMainnetRpcUrl ||
|
|
47207
|
-
usdc:
|
|
47272
|
+
rpcUrl: arcMainnetRpcUrl || NETWORKS2[ARC_MAINNET_CAIP2].publicRpcUrl,
|
|
47273
|
+
usdc: NETWORKS2[ARC_MAINNET_CAIP2].usdc
|
|
47208
47274
|
};
|
|
47209
47275
|
}
|
|
47210
47276
|
const arcTestnetRpcUrl = source.ARC_TESTNET_RPC_URL?.trim();
|
|
@@ -47216,14 +47282,14 @@ function getDefaultConfig(source = process.env, options = {}) {
|
|
|
47216
47282
|
}
|
|
47217
47283
|
networks[ARC_TESTNET_CAIP2] = {
|
|
47218
47284
|
rpcUrl: arcTestnetRpcUrl,
|
|
47219
|
-
usdc:
|
|
47285
|
+
usdc: NETWORKS2[ARC_TESTNET_CAIP2].usdc
|
|
47220
47286
|
};
|
|
47221
47287
|
}
|
|
47222
47288
|
const solanaRpcUrl = source.SOLANA_RPC_URL?.trim();
|
|
47223
47289
|
if (solanaRpcUrl || requested.has("solana") || requested.has(SOLANA_MAINNET_CAIP2)) {
|
|
47224
47290
|
networks[SOLANA_MAINNET_CAIP2] = {
|
|
47225
|
-
rpcUrl: solanaRpcUrl ||
|
|
47226
|
-
usdc:
|
|
47291
|
+
rpcUrl: solanaRpcUrl || NETWORKS2[SOLANA_MAINNET_CAIP2].publicRpcUrl,
|
|
47292
|
+
usdc: NETWORKS2[SOLANA_MAINNET_CAIP2].usdc
|
|
47227
47293
|
};
|
|
47228
47294
|
}
|
|
47229
47295
|
return {
|
|
@@ -47281,21 +47347,21 @@ Run vapi init to write the new URLs to ${path}.`
|
|
|
47281
47347
|
if (arcMainnetRpcUrl) {
|
|
47282
47348
|
const existing = config2.networks[ARC_MAINNET_CAIP2];
|
|
47283
47349
|
config2.networks[ARC_MAINNET_CAIP2] = {
|
|
47284
|
-
...existing ?? { usdc:
|
|
47350
|
+
...existing ?? { usdc: NETWORKS2[ARC_MAINNET_CAIP2].usdc },
|
|
47285
47351
|
rpcUrl: arcMainnetRpcUrl
|
|
47286
47352
|
};
|
|
47287
47353
|
}
|
|
47288
47354
|
if (arcTestnetRpcUrl) {
|
|
47289
47355
|
const existing = config2.networks[ARC_TESTNET_CAIP2];
|
|
47290
47356
|
config2.networks[ARC_TESTNET_CAIP2] = {
|
|
47291
|
-
...existing ?? { usdc:
|
|
47357
|
+
...existing ?? { usdc: NETWORKS2[ARC_TESTNET_CAIP2].usdc },
|
|
47292
47358
|
rpcUrl: arcTestnetRpcUrl
|
|
47293
47359
|
};
|
|
47294
47360
|
}
|
|
47295
47361
|
if (solanaRpcUrl) {
|
|
47296
47362
|
config2.networks[SOLANA_MAINNET_CAIP2] = {
|
|
47297
47363
|
rpcUrl: solanaRpcUrl,
|
|
47298
|
-
usdc: config2.networks[SOLANA_MAINNET_CAIP2]?.usdc ??
|
|
47364
|
+
usdc: config2.networks[SOLANA_MAINNET_CAIP2]?.usdc ?? NETWORKS2[SOLANA_MAINNET_CAIP2].usdc
|
|
47299
47365
|
};
|
|
47300
47366
|
}
|
|
47301
47367
|
if (registryUrl) {
|
|
@@ -47308,7 +47374,7 @@ Run vapi init to write the new URLs to ${path}.`
|
|
|
47308
47374
|
for (const [network, configured] of Object.entries(config2.networks)) {
|
|
47309
47375
|
configured.rpcUrl = configured.rpcUrl.trim();
|
|
47310
47376
|
configured.usdc = configured.usdc.trim();
|
|
47311
|
-
if (isSolanaNetwork(network) && configured.usdc !==
|
|
47377
|
+
if (isSolanaNetwork(network) && configured.usdc !== NETWORKS2[SOLANA_MAINNET_CAIP2].usdc) {
|
|
47312
47378
|
throw new Error(`Network ${network} must use canonical Solana mainnet USDC.`);
|
|
47313
47379
|
}
|
|
47314
47380
|
if (!configured.rpcUrl) delete config2.networks[network];
|
|
@@ -47364,14 +47430,14 @@ async function enableDefaultNetwork(network, path = getVapiPaths().config, sourc
|
|
|
47364
47430
|
const config2 = await loadConfig(path, source);
|
|
47365
47431
|
if (network === "solana") {
|
|
47366
47432
|
config2.networks[SOLANA_MAINNET_CAIP2] = {
|
|
47367
|
-
rpcUrl: source.SOLANA_RPC_URL?.trim() ||
|
|
47368
|
-
usdc:
|
|
47433
|
+
rpcUrl: source.SOLANA_RPC_URL?.trim() || NETWORKS2[SOLANA_MAINNET_CAIP2].publicRpcUrl,
|
|
47434
|
+
usdc: NETWORKS2[SOLANA_MAINNET_CAIP2].usdc
|
|
47369
47435
|
};
|
|
47370
47436
|
} else {
|
|
47371
47437
|
const existing = config2.networks[ARC_MAINNET_CAIP2];
|
|
47372
47438
|
config2.networks[ARC_MAINNET_CAIP2] = {
|
|
47373
|
-
...existing ?? { usdc:
|
|
47374
|
-
rpcUrl: source.ARC_RPC_URL?.trim() ||
|
|
47439
|
+
...existing ?? { usdc: NETWORKS2[ARC_MAINNET_CAIP2].usdc },
|
|
47440
|
+
rpcUrl: source.ARC_RPC_URL?.trim() || NETWORKS2[ARC_MAINNET_CAIP2].publicRpcUrl
|
|
47375
47441
|
};
|
|
47376
47442
|
}
|
|
47377
47443
|
await writeConfigFile(path, config2);
|
|
@@ -70335,7 +70401,7 @@ function windowsDataProtectionStore(platform2, run, env, installed) {
|
|
|
70335
70401
|
};
|
|
70336
70402
|
}
|
|
70337
70403
|
function libsecretStore(platform2, run, installed) {
|
|
70338
|
-
const
|
|
70404
|
+
const lookup2 = async (name) => {
|
|
70339
70405
|
const result = await run(SECRET_TOOL_BINARY, [
|
|
70340
70406
|
"lookup",
|
|
70341
70407
|
"service",
|
|
@@ -70354,9 +70420,9 @@ function libsecretStore(platform2, run, installed) {
|
|
|
70354
70420
|
available: installed(SECRET_TOOL_BINARY),
|
|
70355
70421
|
platform: platform2,
|
|
70356
70422
|
description: "the libsecret keyring",
|
|
70357
|
-
get:
|
|
70423
|
+
get: lookup2,
|
|
70358
70424
|
async has(name) {
|
|
70359
|
-
return await
|
|
70425
|
+
return await lookup2(name) !== void 0;
|
|
70360
70426
|
},
|
|
70361
70427
|
async set(name, passphrase) {
|
|
70362
70428
|
requirePassphrase(passphrase);
|
|
@@ -70378,7 +70444,7 @@ function libsecretStore(platform2, run, installed) {
|
|
|
70378
70444
|
requireSuccess(result, `store the passphrase of ${name} in the secret service`);
|
|
70379
70445
|
},
|
|
70380
70446
|
async remove(name) {
|
|
70381
|
-
const existed = await
|
|
70447
|
+
const existed = await lookup2(name) !== void 0;
|
|
70382
70448
|
const result = await run(SECRET_TOOL_BINARY, [
|
|
70383
70449
|
"clear",
|
|
70384
70450
|
"service",
|
|
@@ -71441,6 +71507,8 @@ var VAULT_KEY_ACCOUNT = "vault-key";
|
|
|
71441
71507
|
var VAULT_SESSION_ACCOUNT = "vault-session";
|
|
71442
71508
|
var DEVICE_KEY_LENGTH = 32;
|
|
71443
71509
|
var DEFAULT_SESSION_HOURS = 8;
|
|
71510
|
+
var RESTORE_GAP_LIMIT = 5;
|
|
71511
|
+
var MAX_RESTORE_ACCOUNTS = 1e4;
|
|
71444
71512
|
var BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
|
|
71445
71513
|
var deviceKeyOperations = Promise.resolve();
|
|
71446
71514
|
var sessionSchema = external_exports.object({
|
|
@@ -71590,26 +71658,41 @@ async function restoreVault(args) {
|
|
|
71590
71658
|
throw new VaultError("corrupt", "That recovery phrase is not valid.", { cause: error61 });
|
|
71591
71659
|
}
|
|
71592
71660
|
let seed;
|
|
71593
|
-
|
|
71661
|
+
if (args.accountCount !== void 0 && (!Number.isSafeInteger(args.accountCount) || args.accountCount < 1 || args.accountCount > MAX_RESTORE_ACCOUNTS)) {
|
|
71662
|
+
throw new VaultError(
|
|
71663
|
+
"corrupt",
|
|
71664
|
+
`Account count must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
71665
|
+
);
|
|
71666
|
+
}
|
|
71667
|
+
let discoveredAccounts = args.accountCount ?? 0;
|
|
71668
|
+
let scannedAddresses = 0;
|
|
71594
71669
|
try {
|
|
71595
71670
|
seed = phraseToSeed(phrase);
|
|
71596
71671
|
} catch (error61) {
|
|
71597
71672
|
throw asVaultError2(error61, "Unable to derive an account while restoring the vault.");
|
|
71598
71673
|
}
|
|
71599
71674
|
try {
|
|
71600
|
-
for (let index2 = 0; ; index2 += 1) {
|
|
71675
|
+
for (let index2 = 0, emptyRun = 0; args.accountCount === void 0; index2 += 1) {
|
|
71601
71676
|
let address4;
|
|
71602
71677
|
try {
|
|
71603
71678
|
address4 = privateKeyToAccount(deriveEvmPrivateKey(seed, `m/44'/60'/0'/0/${index2}`)).address;
|
|
71604
71679
|
} catch (error61) {
|
|
71605
71680
|
throw asVaultError2(error61, "Unable to derive an account while restoring the vault.");
|
|
71606
71681
|
}
|
|
71607
|
-
|
|
71608
|
-
|
|
71682
|
+
const funded = await args.probe(address4);
|
|
71683
|
+
scannedAddresses += 1;
|
|
71684
|
+
if (funded) {
|
|
71685
|
+
discoveredAccounts = index2 + 1;
|
|
71686
|
+
emptyRun = 0;
|
|
71687
|
+
} else {
|
|
71688
|
+
emptyRun += 1;
|
|
71689
|
+
if (emptyRun === RESTORE_GAP_LIMIT) break;
|
|
71690
|
+
}
|
|
71609
71691
|
}
|
|
71610
71692
|
} finally {
|
|
71611
71693
|
seed.fill(0);
|
|
71612
71694
|
}
|
|
71695
|
+
args.onScanComplete?.(scannedAddresses);
|
|
71613
71696
|
let vault;
|
|
71614
71697
|
try {
|
|
71615
71698
|
vault = await createVault({ path: args.path, key: args.key, phrase, now: args.now });
|
|
@@ -72098,6 +72181,26 @@ var WalletStore = class _WalletStore {
|
|
|
72098
72181
|
}
|
|
72099
72182
|
);
|
|
72100
72183
|
}
|
|
72184
|
+
/** Checks a cached signer's current vault session without decrypting its account again. */
|
|
72185
|
+
async assertSigningAuthority(name) {
|
|
72186
|
+
const stored = await this.readVaultUnlocked();
|
|
72187
|
+
if (!stored?.protected || !stored.accounts.some((account) => account.name === name)) return;
|
|
72188
|
+
try {
|
|
72189
|
+
const key2 = await unlockProtectedVault({
|
|
72190
|
+
path: this.vaultPath,
|
|
72191
|
+
secrets: this.secrets,
|
|
72192
|
+
env: this.environment,
|
|
72193
|
+
now: () => this.now()
|
|
72194
|
+
});
|
|
72195
|
+
key2.fill(0);
|
|
72196
|
+
} catch (error61) {
|
|
72197
|
+
this.dropVaultCache();
|
|
72198
|
+
if (error61 instanceof VaultError && error61.code === "password_required") {
|
|
72199
|
+
throw new KeystoreError(VAULT_LOCKED_MESSAGE, { cause: error61 });
|
|
72200
|
+
}
|
|
72201
|
+
throw error61;
|
|
72202
|
+
}
|
|
72203
|
+
}
|
|
72101
72204
|
/** Returns one wallet's vault signer, migrating its legacy keystore if needed. */
|
|
72102
72205
|
async unlock(name, passphrase) {
|
|
72103
72206
|
const wallet = this.resolve({ name });
|
|
@@ -77484,7 +77587,7 @@ function createRunBudget(args) {
|
|
|
77484
77587
|
import { mkdir as mkdir15, writeFile as writeFile8 } from "node:fs/promises";
|
|
77485
77588
|
import { arch, platform, release } from "node:os";
|
|
77486
77589
|
import { join as join13 } from "node:path";
|
|
77487
|
-
var VAPI_CLIENT_VERSION = "0.9.
|
|
77590
|
+
var VAPI_CLIENT_VERSION = "0.9.4";
|
|
77488
77591
|
async function createSupportReport(options) {
|
|
77489
77592
|
const message = options.message.trim();
|
|
77490
77593
|
if (!message) throw new Error("Support report message must not be empty.");
|
|
@@ -77757,7 +77860,7 @@ async function completeX402Payment(args) {
|
|
|
77757
77860
|
let paidAttempt;
|
|
77758
77861
|
const requestStarted = nowMs();
|
|
77759
77862
|
try {
|
|
77760
|
-
paidAttempt = await args.send(paidRequest);
|
|
77863
|
+
paidAttempt = await args.send(paidRequest, quote);
|
|
77761
77864
|
} catch (error61) {
|
|
77762
77865
|
if (trace) trace.phases.requestMs = elapsed(nowMs, requestStarted);
|
|
77763
77866
|
throw settlementUnknown(
|
|
@@ -77775,7 +77878,7 @@ async function completeX402Payment(args) {
|
|
|
77775
77878
|
const settleStarted = nowMs();
|
|
77776
77879
|
const settlement = parseSettlementResponse(paidResponse.headers);
|
|
77777
77880
|
const settlementOutcome = classifySettlement(settlement);
|
|
77778
|
-
const receiptSettlement =
|
|
77881
|
+
const receiptSettlement = sanitizeReturnedValue(settlement, receiptSecrets);
|
|
77779
77882
|
if (trace) {
|
|
77780
77883
|
const transaction2 = settlementTransaction(receiptSettlement);
|
|
77781
77884
|
const explorerUrl = transaction2 ? explorerTransactionUrl(quote.accepted.network, transaction2) : void 0;
|
|
@@ -77852,6 +77955,7 @@ async function completeX402Payment(args) {
|
|
|
77852
77955
|
trace.phases.requestMs = (trace.phases.requestMs ?? 0) + elapsed(nowMs, bodyStarted);
|
|
77853
77956
|
}
|
|
77854
77957
|
}
|
|
77958
|
+
body = sanitizeReturnedValue(body, receiptSecrets);
|
|
77855
77959
|
}
|
|
77856
77960
|
const result = {
|
|
77857
77961
|
response: paidResponse,
|
|
@@ -77860,7 +77964,11 @@ async function completeX402Payment(args) {
|
|
|
77860
77964
|
quote,
|
|
77861
77965
|
payer,
|
|
77862
77966
|
...payment.paymentId ? { paymentId: payment.paymentId } : {},
|
|
77863
|
-
|
|
77967
|
+
paymentProof: sanitizeReturnedValue(
|
|
77968
|
+
paidResponse.headers.get("x-vapi-payment-proof"),
|
|
77969
|
+
receiptSecrets
|
|
77970
|
+
),
|
|
77971
|
+
settlement: receiptSettlement,
|
|
77864
77972
|
settlementOutcome
|
|
77865
77973
|
};
|
|
77866
77974
|
if (settlementOutcome === "succeeded" && args.ceilingSweep) {
|
|
@@ -77997,19 +78105,70 @@ function sanitizeThrownError(error61, secrets) {
|
|
|
77997
78105
|
}
|
|
77998
78106
|
return new Error(message, cause === void 0 ? void 0 : { cause });
|
|
77999
78107
|
}
|
|
78000
|
-
function
|
|
78108
|
+
function sanitizeReturnedValue(value, secrets) {
|
|
78001
78109
|
if (typeof value === "string") return redactKnownSecrets(value, secrets);
|
|
78002
|
-
if (value
|
|
78003
|
-
|
|
78004
|
-
|
|
78005
|
-
|
|
78110
|
+
if (!isPlainReturnedContainer(value)) return value;
|
|
78111
|
+
const nodes = /* @__PURE__ */ new WeakMap();
|
|
78112
|
+
const ordered = [];
|
|
78113
|
+
const nodeFor = (source) => {
|
|
78114
|
+
const existing = nodes.get(source);
|
|
78115
|
+
if (existing) return existing;
|
|
78116
|
+
const copy = Array.isArray(source) ? new Array(source.length) : Object.create(Object.getPrototypeOf(source));
|
|
78117
|
+
const node2 = { source, copy, parents: /* @__PURE__ */ new Set(), changed: false };
|
|
78118
|
+
nodes.set(source, node2);
|
|
78119
|
+
ordered.push(node2);
|
|
78120
|
+
return node2;
|
|
78121
|
+
};
|
|
78122
|
+
const root = nodeFor(value);
|
|
78123
|
+
for (let index2 = 0; index2 < ordered.length; index2 += 1) {
|
|
78124
|
+
const node2 = ordered[index2];
|
|
78125
|
+
for (const [key2, item] of Object.entries(node2.source)) {
|
|
78126
|
+
const safeKey = Array.isArray(node2.source) ? key2 : redactKnownSecrets(key2, secrets);
|
|
78127
|
+
if (safeKey !== key2) node2.changed = true;
|
|
78128
|
+
if (typeof item === "string") {
|
|
78129
|
+
const safeItem = redactKnownSecrets(item, secrets);
|
|
78130
|
+
defineReturnedProperty(node2.copy, safeKey, safeItem);
|
|
78131
|
+
if (safeItem !== item) node2.changed = true;
|
|
78132
|
+
} else if (isPlainReturnedContainer(item)) {
|
|
78133
|
+
const child = nodeFor(item);
|
|
78134
|
+
child.parents.add(node2);
|
|
78135
|
+
defineReturnedProperty(node2.copy, safeKey, child.copy);
|
|
78136
|
+
} else {
|
|
78137
|
+
defineReturnedProperty(node2.copy, safeKey, item);
|
|
78138
|
+
}
|
|
78139
|
+
}
|
|
78006
78140
|
}
|
|
78007
|
-
|
|
78008
|
-
|
|
78009
|
-
|
|
78010
|
-
|
|
78011
|
-
|
|
78012
|
-
|
|
78141
|
+
const changed = ordered.filter((node2) => node2.changed);
|
|
78142
|
+
for (let index2 = 0; index2 < changed.length; index2 += 1) {
|
|
78143
|
+
for (const parent of changed[index2].parents) {
|
|
78144
|
+
if (parent.changed) continue;
|
|
78145
|
+
parent.changed = true;
|
|
78146
|
+
changed.push(parent);
|
|
78147
|
+
}
|
|
78148
|
+
}
|
|
78149
|
+
for (const node2 of ordered) {
|
|
78150
|
+
for (const [key2, item] of Object.entries(node2.source)) {
|
|
78151
|
+
if (!isPlainReturnedContainer(item)) continue;
|
|
78152
|
+
const safeKey = Array.isArray(node2.source) ? key2 : redactKnownSecrets(key2, secrets);
|
|
78153
|
+
const child = nodes.get(item);
|
|
78154
|
+
defineReturnedProperty(node2.copy, safeKey, child.changed ? child.copy : item);
|
|
78155
|
+
}
|
|
78156
|
+
}
|
|
78157
|
+
return root.changed ? root.copy : value;
|
|
78158
|
+
}
|
|
78159
|
+
function defineReturnedProperty(target, key2, value) {
|
|
78160
|
+
Object.defineProperty(target, key2, {
|
|
78161
|
+
value,
|
|
78162
|
+
enumerable: true,
|
|
78163
|
+
configurable: true,
|
|
78164
|
+
writable: true
|
|
78165
|
+
});
|
|
78166
|
+
}
|
|
78167
|
+
function isPlainReturnedContainer(value) {
|
|
78168
|
+
if (Array.isArray(value)) return true;
|
|
78169
|
+
if (value === null || typeof value !== "object") return false;
|
|
78170
|
+
const prototype = Object.getPrototypeOf(value);
|
|
78171
|
+
return prototype === Object.prototype || prototype === null;
|
|
78013
78172
|
}
|
|
78014
78173
|
function redactKnownSecrets(value, secrets) {
|
|
78015
78174
|
let redacted = value;
|
|
@@ -78044,9 +78203,7 @@ function possibleSettlement(quote, payment, payer, receipt) {
|
|
|
78044
78203
|
payTo: quote.accepted.payTo,
|
|
78045
78204
|
payer,
|
|
78046
78205
|
...payment.paymentId ? { paymentId: payment.paymentId } : {},
|
|
78047
|
-
...isSvmPaymentRequirements(quote.accepted) ? {
|
|
78048
|
-
authorizationTransaction: "transaction" in payment.payload.payload ? payment.payload.payload.transaction : ""
|
|
78049
|
-
} : "authorization" in payment.payload.payload ? {
|
|
78206
|
+
...isSvmPaymentRequirements(quote.accepted) ? {} : "authorization" in payment.payload.payload ? {
|
|
78050
78207
|
authorizationNonce: payment.payload.payload.authorization.nonce,
|
|
78051
78208
|
authorizationExpiresAt: payment.payload.payload.authorization.validBefore
|
|
78052
78209
|
} : {},
|
|
@@ -78424,13 +78581,22 @@ async function sendRouterChat(deps, routerBaseUrl, routerKey, request, keyUsed)
|
|
|
78424
78581
|
}
|
|
78425
78582
|
const body = await responseText(response);
|
|
78426
78583
|
if (!response.ok) {
|
|
78427
|
-
if (
|
|
78584
|
+
if (/budget (?:has been )?exceeded|exceededbudget/iu.test(body)) {
|
|
78428
78585
|
throw new RouterClientError(
|
|
78429
78586
|
"budget_exhausted",
|
|
78430
78587
|
"The Router key has no remaining budget.",
|
|
78431
78588
|
response.status
|
|
78432
78589
|
);
|
|
78433
78590
|
}
|
|
78591
|
+
if (response.status === 429) {
|
|
78592
|
+
const retryAfter = response.headers.get("retry-after")?.trim();
|
|
78593
|
+
const retrySeconds = retryAfter !== void 0 && /^\d+$/u.test(retryAfter) ? Number(retryAfter) : void 0;
|
|
78594
|
+
throw new RouterClientError(
|
|
78595
|
+
"rate_limited",
|
|
78596
|
+
`The vAPI Router is rate limited. ${retrySeconds !== void 0 && Number.isFinite(retrySeconds) ? `Retry after ${retrySeconds} seconds.` : "Wait and retry shortly."}`,
|
|
78597
|
+
response.status
|
|
78598
|
+
);
|
|
78599
|
+
}
|
|
78434
78600
|
if (response.status === 401) {
|
|
78435
78601
|
throw new RouterClientError(
|
|
78436
78602
|
"no_router_key",
|
|
@@ -78997,6 +79163,7 @@ var missingTasksChain = {
|
|
|
78997
79163
|
|
|
78998
79164
|
// ../core/src/tasks/types.ts
|
|
78999
79165
|
var uuidSchema = external_exports.uuid();
|
|
79166
|
+
var profileIdSchema = external_exports.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
79000
79167
|
var isoDateTimeSchema = external_exports.iso.datetime();
|
|
79001
79168
|
var addressSchema5 = external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/).transform((value) => value.toLowerCase());
|
|
79002
79169
|
var bytes32Schema = external_exports.string().regex(/^0x[0-9a-fA-F]{64}$/).transform((value) => value.toLowerCase());
|
|
@@ -79334,7 +79501,7 @@ var deliveryResponseSchema = external_exports.looseObject({
|
|
|
79334
79501
|
version: external_exports.number().int().positive(),
|
|
79335
79502
|
manifest: manifestResponseSchema,
|
|
79336
79503
|
manifestHash: bytes32Schema,
|
|
79337
|
-
submittedByProfileId:
|
|
79504
|
+
submittedByProfileId: profileIdSchema,
|
|
79338
79505
|
createdAt: isoDateTimeSchema
|
|
79339
79506
|
});
|
|
79340
79507
|
var orderDeliveryResponseSchema = external_exports.looseObject({
|
|
@@ -79440,7 +79607,7 @@ var reviewResponseSchema = external_exports.looseObject({
|
|
|
79440
79607
|
id: uuidSchema,
|
|
79441
79608
|
workOrderId: uuidSchema,
|
|
79442
79609
|
clientAddress: addressSchema5,
|
|
79443
|
-
vendorProfileId:
|
|
79610
|
+
vendorProfileId: profileIdSchema,
|
|
79444
79611
|
rating: external_exports.number().int().min(1).max(5),
|
|
79445
79612
|
body: external_exports.string(),
|
|
79446
79613
|
subRatings: external_exports.json().nullable(),
|
|
@@ -79983,12 +80150,15 @@ function createTasksClient(options) {
|
|
|
79983
80150
|
const parsed2 = serverErrorSchema.safeParse(errorBody);
|
|
79984
80151
|
const server = parsed2.success ? parsed2.data : void 0;
|
|
79985
80152
|
const nested = typeof server?.error === "object" ? server.error : void 0;
|
|
79986
|
-
const
|
|
80153
|
+
const serverCode = nested?.code ?? server?.code;
|
|
80154
|
+
const serverMessage = (typeof server?.error === "string" ? server.error : nested?.message) || server?.message;
|
|
80155
|
+
const fallback = response.statusText || `HTTP ${response.status}`;
|
|
80156
|
+
const message = response.status === 401 || response.status === 403 ? serverCode ?? fallback : serverMessage || (errorBody === void 0 && raw.trim() ? raw.replace(/\s+/gu, " ").trim().slice(0, 300) : fallback);
|
|
79987
80157
|
throw new TasksClientError(
|
|
79988
80158
|
"http",
|
|
79989
80159
|
message,
|
|
79990
80160
|
response.status,
|
|
79991
|
-
|
|
80161
|
+
serverCode,
|
|
79992
80162
|
response.headers.get("Retry-After") ?? void 0
|
|
79993
80163
|
);
|
|
79994
80164
|
}
|
|
@@ -80391,9 +80561,10 @@ function safeTasksChainError(cause, broadcast, authorizationExposed, txHash) {
|
|
|
80391
80561
|
let message = "Task chain operation failed.";
|
|
80392
80562
|
if (cause instanceof TasksValidationError || cause instanceof TasksChainError)
|
|
80393
80563
|
message = cause.message;
|
|
80394
|
-
else if (cause instanceof TasksClientError)
|
|
80395
|
-
|
|
80396
|
-
|
|
80564
|
+
else if (cause instanceof TasksClientError) {
|
|
80565
|
+
const code = cause.serverCode ?? (cause.status ? `http_${cause.status}` : cause.code);
|
|
80566
|
+
message = cause.status === 401 || cause.status === 403 ? `${code} (status ${cause.status})` : `${code}: ${cause.message}`;
|
|
80567
|
+
} else if (cause instanceof Error) {
|
|
80397
80568
|
const short = "shortMessage" in cause && typeof cause.shortMessage === "string" ? cause.shortMessage : void 0;
|
|
80398
80569
|
let statusCode;
|
|
80399
80570
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -81201,6 +81372,44 @@ function createTasksChain(options) {
|
|
|
81201
81372
|
return idempotencyKey;
|
|
81202
81373
|
});
|
|
81203
81374
|
}
|
|
81375
|
+
async function prepareOrResume(prepare, expected, idempotencyKey, kind, steps, authorizationExposed = false, beforeSign) {
|
|
81376
|
+
let prepared;
|
|
81377
|
+
let resumedFromServer = false;
|
|
81378
|
+
try {
|
|
81379
|
+
prepared = await prepare();
|
|
81380
|
+
} catch (error61) {
|
|
81381
|
+
if (!uncertainPreparation(error61)) throw error61;
|
|
81382
|
+
const fresh = await order(expected.milestone.workOrderId);
|
|
81383
|
+
const matches = fresh.milestones.filter((item) => item.id === expected.milestone.id);
|
|
81384
|
+
if (matches.length !== 1 || matches[0].workOrderId !== fresh.id)
|
|
81385
|
+
throw new TasksValidationError("The task milestone does not match its parent order.");
|
|
81386
|
+
const selected = matches[0];
|
|
81387
|
+
const operation = selected.chainOperation;
|
|
81388
|
+
if (expected.verb === "deliver" && selected.delivery && !operation)
|
|
81389
|
+
throw new TasksValidationError(
|
|
81390
|
+
"The server recorded this delivery but has no chain operation for it; open the task in the console to continue."
|
|
81391
|
+
);
|
|
81392
|
+
if (!operation || operation.kind !== kind || !(typeof steps === "string" ? [steps] : steps).includes(operation.step) || !["prepared", "submitted", "confirmed"].includes(operation.state))
|
|
81393
|
+
throw error61;
|
|
81394
|
+
if (expected.verb === "deliver" && selected.delivery && selected.delivery.manifestHash !== expected.manifestHash)
|
|
81395
|
+
throw new TasksValidationError(
|
|
81396
|
+
"The server recorded a different delivery manifest; refusing to continue."
|
|
81397
|
+
);
|
|
81398
|
+
prepared = {
|
|
81399
|
+
operation,
|
|
81400
|
+
milestone: { id: selected.id, workOrderId: selected.workOrderId }
|
|
81401
|
+
};
|
|
81402
|
+
resumedFromServer = true;
|
|
81403
|
+
}
|
|
81404
|
+
const result = await execute(
|
|
81405
|
+
prepared,
|
|
81406
|
+
expected,
|
|
81407
|
+
idempotencyKey,
|
|
81408
|
+
authorizationExposed,
|
|
81409
|
+
beforeSign
|
|
81410
|
+
);
|
|
81411
|
+
return resumedFromServer ? { ...result, resumedFromServer: true } : result;
|
|
81412
|
+
}
|
|
81204
81413
|
async function verifyReceipt(operation, expected, hash5) {
|
|
81205
81414
|
const rpc = rpcFor(expected.deployment.chainId);
|
|
81206
81415
|
const receipt = await rpc.waitForTransactionReceipt({ hash: hash5, confirmations });
|
|
@@ -81242,6 +81451,7 @@ function createTasksChain(options) {
|
|
|
81242
81451
|
throw new TasksValidationError(
|
|
81243
81452
|
"The RPC transaction input does not match the verified task plan."
|
|
81244
81453
|
);
|
|
81454
|
+
return receipt.blockNumber.toString();
|
|
81245
81455
|
}
|
|
81246
81456
|
async function retryConflict(call2) {
|
|
81247
81457
|
let waited = 0;
|
|
@@ -81269,6 +81479,7 @@ function createTasksChain(options) {
|
|
|
81269
81479
|
current = { ...initial, operation: live };
|
|
81270
81480
|
let broadcast = current.operation.state === "submitted";
|
|
81271
81481
|
let txHash = current.operation.transactionHash ?? void 0;
|
|
81482
|
+
let blockNumber;
|
|
81272
81483
|
const operationId = initial.operation.id;
|
|
81273
81484
|
function checkTransition(previous, next) {
|
|
81274
81485
|
if (previous !== next && !(previous === "approve-usdc" && next === afterApproval))
|
|
@@ -81304,7 +81515,7 @@ function createTasksChain(options) {
|
|
|
81304
81515
|
if (!operation.transactionHash)
|
|
81305
81516
|
throw new TasksValidationError("The confirmed task operation has no transaction hash.");
|
|
81306
81517
|
if (!checkpoint) {
|
|
81307
|
-
await verifyReceipt(operation, expected, operation.transactionHash);
|
|
81518
|
+
blockNumber = await verifyReceipt(operation, expected, operation.transactionHash);
|
|
81308
81519
|
await pending.complete(operation.id, operation.step, current);
|
|
81309
81520
|
}
|
|
81310
81521
|
const fresh = await order(expected.milestone.workOrderId);
|
|
@@ -81313,7 +81524,12 @@ function createTasksChain(options) {
|
|
|
81313
81524
|
);
|
|
81314
81525
|
if (!resultMilestone)
|
|
81315
81526
|
throw new TasksValidationError("The reconciled task milestone is unavailable.");
|
|
81316
|
-
return {
|
|
81527
|
+
return {
|
|
81528
|
+
txHash: operation.transactionHash,
|
|
81529
|
+
operation,
|
|
81530
|
+
milestone: resultMilestone,
|
|
81531
|
+
blockNumber
|
|
81532
|
+
};
|
|
81317
81533
|
}
|
|
81318
81534
|
const rpc = rpcFor(expected.deployment.chainId);
|
|
81319
81535
|
if (operation.state === "prepared") {
|
|
@@ -81509,7 +81725,7 @@ function createTasksChain(options) {
|
|
|
81509
81725
|
}
|
|
81510
81726
|
if (operation.state !== "submitted" || !operation.transactionHash)
|
|
81511
81727
|
throw new TasksValidationError("The task operation has no submitted transaction.");
|
|
81512
|
-
await verifyReceipt(operation, expected, operation.transactionHash);
|
|
81728
|
+
blockNumber = await verifyReceipt(operation, expected, operation.transactionHash);
|
|
81513
81729
|
const reconciled = await retryConflict(
|
|
81514
81730
|
() => client.reconcileOperation(
|
|
81515
81731
|
operation.id,
|
|
@@ -81532,6 +81748,7 @@ function createTasksChain(options) {
|
|
|
81532
81748
|
if (reconciled.operation.state !== "confirmed" && !(operation.step === "approve-usdc" && reconciled.operation.state === "prepared" && reconciled.operation.step === afterApproval))
|
|
81533
81749
|
throw new TasksValidationError("The task transaction was not reconciled.");
|
|
81534
81750
|
await pending.complete(operation.id, operation.step, reconciled);
|
|
81751
|
+
if (reconciled.operation.step !== operation.step) blockNumber = void 0;
|
|
81535
81752
|
current = reconciled;
|
|
81536
81753
|
}
|
|
81537
81754
|
throw new TasksValidationError("The task operation exceeded its allowed step transitions.");
|
|
@@ -81566,14 +81783,16 @@ function createTasksChain(options) {
|
|
|
81566
81783
|
);
|
|
81567
81784
|
const prepareKey = await preparation(input2, verb, { evidenceHash: input2.evidenceHash });
|
|
81568
81785
|
const call2 = verb === "dispute" ? client.disputeEscrow.bind(client) : client.counterEvidenceEscrow.bind(client);
|
|
81569
|
-
return await
|
|
81570
|
-
|
|
81786
|
+
return await prepareOrResume(
|
|
81787
|
+
() => call2(
|
|
81571
81788
|
input2.escrowId,
|
|
81572
81789
|
{ evidenceHash: input2.evidenceHash },
|
|
81573
81790
|
{ idempotencyKey: prepareKey }
|
|
81574
81791
|
),
|
|
81575
81792
|
{ ...expected, evidenceHash: input2.evidenceHash },
|
|
81576
81793
|
prepareKey,
|
|
81794
|
+
verb === "dispute" ? "escrow-dispute" : "escrow-counter-evidence",
|
|
81795
|
+
expected.steps,
|
|
81577
81796
|
exposed,
|
|
81578
81797
|
input2.beforeSign
|
|
81579
81798
|
);
|
|
@@ -81593,11 +81812,34 @@ function createTasksChain(options) {
|
|
|
81593
81812
|
await options.bindings.put(binding);
|
|
81594
81813
|
},
|
|
81595
81814
|
createEscrow: (input2) => safe(async () => {
|
|
81596
|
-
|
|
81815
|
+
let workOrder = await order(input2.orderId);
|
|
81597
81816
|
const ready = await deployment();
|
|
81598
|
-
|
|
81599
|
-
|
|
81600
|
-
|
|
81817
|
+
let prepared;
|
|
81818
|
+
let resumedFromServer = false;
|
|
81819
|
+
try {
|
|
81820
|
+
prepared = await client.createEscrow(input2.orderId, {
|
|
81821
|
+
idempotencyKey: input2.idempotencyKey
|
|
81822
|
+
});
|
|
81823
|
+
} catch (error61) {
|
|
81824
|
+
if (!uncertainPreparation(error61)) throw error61;
|
|
81825
|
+
const fresh = await order(input2.orderId);
|
|
81826
|
+
const candidates = fresh.milestones.filter((item) => {
|
|
81827
|
+
const previous = workOrder.milestones.find((prior) => prior.id === item.id);
|
|
81828
|
+
const operation = item.chainOperation;
|
|
81829
|
+
return item.workOrderId === input2.orderId && previous && operation && operation.kind === "escrow-create" && operation.step === "create-escrow" && (previous.escrowState === null || previous.chainOperation?.id === operation.id);
|
|
81830
|
+
});
|
|
81831
|
+
if (candidates.length !== 1) throw error61;
|
|
81832
|
+
const selected2 = candidates[0];
|
|
81833
|
+
prepared = {
|
|
81834
|
+
operation: selected2.chainOperation,
|
|
81835
|
+
milestone: {
|
|
81836
|
+
id: selected2.id,
|
|
81837
|
+
workOrderId: selected2.workOrderId
|
|
81838
|
+
}
|
|
81839
|
+
};
|
|
81840
|
+
workOrder = fresh;
|
|
81841
|
+
resumedFromServer = true;
|
|
81842
|
+
}
|
|
81601
81843
|
const selected = workOrder.milestones.find((item) => item.id === prepared.milestone.id);
|
|
81602
81844
|
if (!selected || selected.workOrderId !== input2.orderId)
|
|
81603
81845
|
throw new TasksValidationError(
|
|
@@ -81607,11 +81849,12 @@ function createTasksChain(options) {
|
|
|
81607
81849
|
{ escrowId: selected.id, idempotencyKey: input2.idempotencyKey },
|
|
81608
81850
|
"createEscrow"
|
|
81609
81851
|
);
|
|
81610
|
-
|
|
81852
|
+
const result = await execute(
|
|
81611
81853
|
prepared,
|
|
81612
81854
|
await expectation(selected, ready, "createEscrow", ["create-escrow"], input2.counterparty),
|
|
81613
81855
|
prepareKey
|
|
81614
81856
|
);
|
|
81857
|
+
return resumedFromServer ? { ...result, resumedFromServer: true } : result;
|
|
81615
81858
|
}),
|
|
81616
81859
|
async fund(input2) {
|
|
81617
81860
|
let exposed = true;
|
|
@@ -81699,10 +81942,14 @@ function createTasksChain(options) {
|
|
|
81699
81942
|
}
|
|
81700
81943
|
exposed = true;
|
|
81701
81944
|
await pending.markExposure(selected.id);
|
|
81702
|
-
|
|
81703
|
-
idempotencyKey: prepareKey
|
|
81704
|
-
|
|
81705
|
-
|
|
81945
|
+
return await prepareOrResume(
|
|
81946
|
+
() => client.fundEscrow(input2.escrowId, body, { idempotencyKey: prepareKey }),
|
|
81947
|
+
expected,
|
|
81948
|
+
prepareKey,
|
|
81949
|
+
"escrow-funding",
|
|
81950
|
+
expected.steps,
|
|
81951
|
+
exposed
|
|
81952
|
+
);
|
|
81706
81953
|
} catch (cause) {
|
|
81707
81954
|
throw chainError(cause, false, exposed);
|
|
81708
81955
|
}
|
|
@@ -81727,22 +81974,26 @@ function createTasksChain(options) {
|
|
|
81727
81974
|
manifest: frozen.manifest,
|
|
81728
81975
|
note: input2.note
|
|
81729
81976
|
});
|
|
81730
|
-
|
|
81731
|
-
|
|
81732
|
-
|
|
81733
|
-
|
|
81734
|
-
|
|
81735
|
-
|
|
81736
|
-
|
|
81737
|
-
|
|
81738
|
-
|
|
81739
|
-
|
|
81740
|
-
|
|
81977
|
+
return await prepareOrResume(
|
|
81978
|
+
async () => {
|
|
81979
|
+
const prepared = await client.deliverEscrow(
|
|
81980
|
+
input2.escrowId,
|
|
81981
|
+
{ fileIds: frozen.manifest.files.map((file2) => file2.fileId), note: input2.note },
|
|
81982
|
+
{ idempotencyKey: prepareKey }
|
|
81983
|
+
);
|
|
81984
|
+
if (prepared.delivery.manifestHash !== frozen.manifestHash)
|
|
81985
|
+
throw new TasksValidationError(
|
|
81986
|
+
"The server task delivery manifest hash does not match the local manifest."
|
|
81987
|
+
);
|
|
81988
|
+
return prepared;
|
|
81989
|
+
},
|
|
81741
81990
|
{
|
|
81742
81991
|
...expected,
|
|
81743
81992
|
manifestHash: frozen.manifestHash
|
|
81744
81993
|
},
|
|
81745
|
-
prepareKey
|
|
81994
|
+
prepareKey,
|
|
81995
|
+
"escrow-delivery",
|
|
81996
|
+
"submit-delivery"
|
|
81746
81997
|
);
|
|
81747
81998
|
}),
|
|
81748
81999
|
release: (input2) => safe(async () => {
|
|
@@ -81756,10 +82007,12 @@ function createTasksChain(options) {
|
|
|
81756
82007
|
input2.counterparty
|
|
81757
82008
|
);
|
|
81758
82009
|
const prepareKey = await preparation(input2, "release");
|
|
81759
|
-
return await
|
|
81760
|
-
|
|
82010
|
+
return await prepareOrResume(
|
|
82011
|
+
() => client.releaseEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
|
|
81761
82012
|
expected,
|
|
81762
|
-
prepareKey
|
|
82013
|
+
prepareKey,
|
|
82014
|
+
"escrow-release",
|
|
82015
|
+
"release-funds"
|
|
81763
82016
|
);
|
|
81764
82017
|
}),
|
|
81765
82018
|
refund: (input2) => safe(async () => {
|
|
@@ -81773,10 +82026,12 @@ function createTasksChain(options) {
|
|
|
81773
82026
|
input2.counterparty
|
|
81774
82027
|
);
|
|
81775
82028
|
const prepareKey = await preparation(input2, "refund");
|
|
81776
|
-
return await
|
|
81777
|
-
|
|
82029
|
+
return await prepareOrResume(
|
|
82030
|
+
() => client.refundEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
|
|
81778
82031
|
expected,
|
|
81779
|
-
prepareKey
|
|
82032
|
+
prepareKey,
|
|
82033
|
+
"escrow-release",
|
|
82034
|
+
"refund-buyer"
|
|
81780
82035
|
);
|
|
81781
82036
|
}),
|
|
81782
82037
|
disputeFee: (input2) => safe(async () => {
|
|
@@ -81804,16 +82059,21 @@ function createTasksChain(options) {
|
|
|
81804
82059
|
input2.counterparty
|
|
81805
82060
|
);
|
|
81806
82061
|
const prepareKey = await preparation(input2, "resolve-unmatched");
|
|
81807
|
-
return
|
|
81808
|
-
|
|
82062
|
+
return prepareOrResume(
|
|
82063
|
+
() => client.resolveUnmatchedEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
|
|
81809
82064
|
expected,
|
|
81810
|
-
prepareKey
|
|
82065
|
+
prepareKey,
|
|
82066
|
+
"escrow-unmatched-resolution",
|
|
82067
|
+
"resolve-unmatched-dispute"
|
|
81811
82068
|
);
|
|
81812
82069
|
}),
|
|
81813
82070
|
signScopeMessage: (message) => safe(() => account.signMessage({ message }))
|
|
81814
82071
|
};
|
|
81815
82072
|
}
|
|
81816
82073
|
var chainError = safeTasksChainError;
|
|
82074
|
+
function uncertainPreparation(error61) {
|
|
82075
|
+
return error61 instanceof TasksClientError && ((error61.status ?? 0) >= 400 || error61.code === "network" || error61.code === "timeout");
|
|
82076
|
+
}
|
|
81817
82077
|
function retryDelay(header, now) {
|
|
81818
82078
|
if (/^\d+(?:\.\d+)?$/u.test(header.trim())) return Math.max(1, Math.ceil(Number(header) * 1e3));
|
|
81819
82079
|
const date5 = Date.parse(header);
|
|
@@ -81830,6 +82090,60 @@ function alreadySent(error61) {
|
|
|
81830
82090
|
return error61 instanceof Error && /already known|known transaction|nonce (?:is )?too low/iu.test(error61.message);
|
|
81831
82091
|
}
|
|
81832
82092
|
|
|
82093
|
+
// ../core/src/tasks/wait.ts
|
|
82094
|
+
async function waitForMilestone(client, input2) {
|
|
82095
|
+
const timeoutMs = input2.timeoutMs ?? 12e4;
|
|
82096
|
+
const intervalMs = input2.intervalMs ?? 3e3;
|
|
82097
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0)
|
|
82098
|
+
throw new RangeError("The milestone wait timeout must be non-negative and finite.");
|
|
82099
|
+
if (!Number.isFinite(intervalMs) || intervalMs <= 0)
|
|
82100
|
+
throw new RangeError("The milestone wait interval must be positive and finite.");
|
|
82101
|
+
const sleep = input2.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
|
|
82102
|
+
const now = input2.now ?? (() => /* @__PURE__ */ new Date());
|
|
82103
|
+
const started = now().getTime();
|
|
82104
|
+
const deadline = started + timeoutMs;
|
|
82105
|
+
let polls = 0;
|
|
82106
|
+
let milestone;
|
|
82107
|
+
function result(reached) {
|
|
82108
|
+
return { reached, milestone, polls, elapsedMs: now().getTime() - started };
|
|
82109
|
+
}
|
|
82110
|
+
for (; ; ) {
|
|
82111
|
+
const remaining = deadline - now().getTime();
|
|
82112
|
+
if (remaining <= 0) return result(false);
|
|
82113
|
+
const controller = new AbortController();
|
|
82114
|
+
const timer = setTimeout(() => controller.abort(), remaining);
|
|
82115
|
+
let response;
|
|
82116
|
+
polls++;
|
|
82117
|
+
try {
|
|
82118
|
+
response = await client.getOrder(input2.orderId, { signal: controller.signal });
|
|
82119
|
+
} catch (error61) {
|
|
82120
|
+
if (controller.signal.aborted) return result(false);
|
|
82121
|
+
throw error61;
|
|
82122
|
+
} finally {
|
|
82123
|
+
clearTimeout(timer);
|
|
82124
|
+
}
|
|
82125
|
+
if (controller.signal.aborted || now().getTime() >= deadline) return result(false);
|
|
82126
|
+
const { workOrder } = response;
|
|
82127
|
+
milestone = workOrder.id === input2.orderId && workOrder.version === "work-order-view-v1" ? workOrder.milestones.find(
|
|
82128
|
+
(item) => item.id === input2.milestoneId && item.workOrderId === input2.orderId
|
|
82129
|
+
) : void 0;
|
|
82130
|
+
if (milestone && reachedTarget(milestone, input2.target)) return result(true);
|
|
82131
|
+
await sleep(Math.min(intervalMs, deadline - now().getTime()));
|
|
82132
|
+
}
|
|
82133
|
+
}
|
|
82134
|
+
function reachedTarget(milestone, target) {
|
|
82135
|
+
switch (target) {
|
|
82136
|
+
case "created":
|
|
82137
|
+
return milestone.escrowState !== null;
|
|
82138
|
+
case "locked":
|
|
82139
|
+
return ["locked", "submitted", "disputed", "resolved"].includes(milestone.escrowState ?? "");
|
|
82140
|
+
case "delivered":
|
|
82141
|
+
return ["submitted", "disputed", "resolved"].includes(milestone.escrowState ?? "");
|
|
82142
|
+
case "released":
|
|
82143
|
+
return milestone.escrowState === "resolved";
|
|
82144
|
+
}
|
|
82145
|
+
}
|
|
82146
|
+
|
|
81833
82147
|
// ../core/src/tasks/rpc.ts
|
|
81834
82148
|
function createTasksRpcFor(config2, options = {}) {
|
|
81835
82149
|
const clients = /* @__PURE__ */ new Map();
|
|
@@ -82946,7 +83260,10 @@ async function taskRequest(verb, route, operation, options) {
|
|
|
82946
83260
|
"not_signed_in",
|
|
82947
83261
|
`${verb} needs sign-in. ${options.signInHint}`
|
|
82948
83262
|
);
|
|
82949
|
-
throw new TaskOperationError(
|
|
83263
|
+
throw new TaskOperationError(
|
|
83264
|
+
error61.serverCode ?? (error61.status ? `http_${error61.status}` : error61.code),
|
|
83265
|
+
error61.message
|
|
83266
|
+
);
|
|
82950
83267
|
}
|
|
82951
83268
|
throw error61;
|
|
82952
83269
|
}
|
|
@@ -83067,7 +83384,8 @@ function proposalTerms(id2, address4, deployment, terms) {
|
|
|
83067
83384
|
return {
|
|
83068
83385
|
version: "work-proposal-v1",
|
|
83069
83386
|
workOrderId: id2,
|
|
83070
|
-
|
|
83387
|
+
// The server lowercases addresses before canonicalizing the signed payload.
|
|
83388
|
+
providerAddress: address4.toLowerCase(),
|
|
83071
83389
|
pricingModel: "fixed",
|
|
83072
83390
|
milestones: [
|
|
83073
83391
|
{
|
|
@@ -83454,6 +83772,55 @@ async function showTask(context, input2) {
|
|
|
83454
83772
|
};
|
|
83455
83773
|
}
|
|
83456
83774
|
async function taskStatus(context, input2) {
|
|
83775
|
+
if (input2.signedIn) {
|
|
83776
|
+
const chainState = await taskRequest(
|
|
83777
|
+
"status",
|
|
83778
|
+
"chainState",
|
|
83779
|
+
async () => {
|
|
83780
|
+
try {
|
|
83781
|
+
return await context.client.chainState(input2.id);
|
|
83782
|
+
} catch (error61) {
|
|
83783
|
+
if (error61 instanceof TasksClientError && error61.status === 404) {
|
|
83784
|
+
if (isMissingTaskEntity(error61.serverCode, error61.message))
|
|
83785
|
+
throw new TaskOperationError("not_found", error61.message);
|
|
83786
|
+
throw new TaskOperationError(
|
|
83787
|
+
"not_available",
|
|
83788
|
+
"GET /v1/work-orders/:id/chain-state is not available on this server."
|
|
83789
|
+
);
|
|
83790
|
+
}
|
|
83791
|
+
throw error61;
|
|
83792
|
+
}
|
|
83793
|
+
},
|
|
83794
|
+
context
|
|
83795
|
+
);
|
|
83796
|
+
if (chainState.workOrderId !== input2.id)
|
|
83797
|
+
throw new TaskOperationError("invalid_response", "The response belongs to a different task.");
|
|
83798
|
+
const page = await taskRequest(
|
|
83799
|
+
"status",
|
|
83800
|
+
"events",
|
|
83801
|
+
async () => {
|
|
83802
|
+
try {
|
|
83803
|
+
return await context.client.events(input2.id, { wait: 0 });
|
|
83804
|
+
} catch (error61) {
|
|
83805
|
+
if (error61 instanceof TasksClientError && error61.status === 404) {
|
|
83806
|
+
if (isMissingTaskEntity(error61.serverCode, error61.message)) return null;
|
|
83807
|
+
throw new TaskOperationError(
|
|
83808
|
+
"not_available",
|
|
83809
|
+
"GET /v1/work-orders/:id/events is not available on this server."
|
|
83810
|
+
);
|
|
83811
|
+
}
|
|
83812
|
+
throw error61;
|
|
83813
|
+
}
|
|
83814
|
+
},
|
|
83815
|
+
context
|
|
83816
|
+
);
|
|
83817
|
+
return {
|
|
83818
|
+
task: { id: input2.id },
|
|
83819
|
+
chainState,
|
|
83820
|
+
events: page ? [...page.events].sort((a, b) => a.sequence - b.sequence) : null,
|
|
83821
|
+
nextAfter: page?.nextAfter ?? null
|
|
83822
|
+
};
|
|
83823
|
+
}
|
|
83457
83824
|
const task = await taskRequest(
|
|
83458
83825
|
"status",
|
|
83459
83826
|
"publicTask",
|
|
@@ -83809,6 +84176,7 @@ var searchEventSchema = external_exports.strictObject({
|
|
|
83809
84176
|
source: external_exports.string().min(1),
|
|
83810
84177
|
latencyMs: external_exports.number().nonnegative().finite(),
|
|
83811
84178
|
count: external_exports.number().int().nonnegative(),
|
|
84179
|
+
dropped: external_exports.number().int().nonnegative().optional(),
|
|
83812
84180
|
error: external_exports.string().optional()
|
|
83813
84181
|
})
|
|
83814
84182
|
),
|
|
@@ -86814,6 +87182,12 @@ function isRecord4(value) {
|
|
|
86814
87182
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
86815
87183
|
}
|
|
86816
87184
|
|
|
87185
|
+
// src/cli.ts
|
|
87186
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
87187
|
+
import { stat as stat16 } from "node:fs/promises";
|
|
87188
|
+
import { join as join28 } from "node:path";
|
|
87189
|
+
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
87190
|
+
|
|
86817
87191
|
// ../core/src/member-bundle.ts
|
|
86818
87192
|
var MEMBER_BUNDLE_MAX_BYTES = 32 * 1024;
|
|
86819
87193
|
var REMOTE_BLOCKED_GRANTS = /* @__PURE__ */ new Set([
|
|
@@ -86880,7 +87254,7 @@ var memberBundleConfigSchema = external_exports.unknown().refine((value) => !has
|
|
|
86880
87254
|
external_exports.strictObject({ usdc: external_exports.string() })
|
|
86881
87255
|
).refine(
|
|
86882
87256
|
(networks) => Object.entries(networks).every(
|
|
86883
|
-
([id2, network]) => isMemberBundleNetwork(id2) && network.usdc ===
|
|
87257
|
+
([id2, network]) => isMemberBundleNetwork(id2) && network.usdc === NETWORKS2[id2].usdc
|
|
86884
87258
|
),
|
|
86885
87259
|
{ message: "Expected the canonical USDC token of each network." }
|
|
86886
87260
|
).refine((networks) => Object.keys(networks).length === 1, {
|
|
@@ -86919,14 +87293,14 @@ function memberBundleConfig(owner, network) {
|
|
|
86919
87293
|
return {
|
|
86920
87294
|
discoveryUrl,
|
|
86921
87295
|
marketplaceDiscoveryUrl,
|
|
86922
|
-
networks: { [network]: { usdc:
|
|
87296
|
+
networks: { [network]: { usdc: NETWORKS2[network].usdc } }
|
|
86923
87297
|
};
|
|
86924
87298
|
}
|
|
86925
87299
|
function headlessConfigFromBundle(config2) {
|
|
86926
87300
|
const networks = {};
|
|
86927
87301
|
for (const [id2, network] of Object.entries(config2.networks)) {
|
|
86928
87302
|
if (!isMemberBundleNetwork(id2) || network === void 0) continue;
|
|
86929
|
-
networks[id2] = { rpcUrl:
|
|
87303
|
+
networks[id2] = { rpcUrl: NETWORKS2[id2].publicRpcUrl, usdc: network.usdc };
|
|
86930
87304
|
}
|
|
86931
87305
|
return configSchema.parse({
|
|
86932
87306
|
discoveryUrl: config2.discoveryUrl,
|
|
@@ -87019,7 +87393,7 @@ function parseStoredTokens(value) {
|
|
|
87019
87393
|
}
|
|
87020
87394
|
}
|
|
87021
87395
|
function isMemberBundleNetwork(id2) {
|
|
87022
|
-
return Object.hasOwn(
|
|
87396
|
+
return Object.hasOwn(NETWORKS2, id2) && typeof NETWORKS2[id2].publicRpcUrl === "string";
|
|
87023
87397
|
}
|
|
87024
87398
|
function hasForbiddenConfigKey(value) {
|
|
87025
87399
|
if (Array.isArray(value)) return value.some(hasForbiddenConfigKey);
|
|
@@ -87321,11 +87695,28 @@ async function searchMarketplace(input2, config2, fetchImpl, options = {}) {
|
|
|
87321
87695
|
}
|
|
87322
87696
|
}
|
|
87323
87697
|
});
|
|
87324
|
-
const
|
|
87325
|
-
|
|
87698
|
+
const envelope = marketplaceDiscoveryEnvelopeSchema.parse(await response.json());
|
|
87699
|
+
const items = [];
|
|
87700
|
+
let dropped = 0;
|
|
87701
|
+
for (const [index2, rawItem] of envelope.items.entries()) {
|
|
87702
|
+
const parsed = marketplaceHitSchema.safeParse(rawItem);
|
|
87703
|
+
if (parsed.success) {
|
|
87704
|
+
items.push(parsed.data);
|
|
87705
|
+
continue;
|
|
87706
|
+
}
|
|
87707
|
+
dropped += 1;
|
|
87708
|
+
try {
|
|
87709
|
+
options.debug?.(`vAPI marketplace discovery dropped invalid row at index ${index2}.`);
|
|
87710
|
+
} catch {
|
|
87711
|
+
}
|
|
87712
|
+
}
|
|
87713
|
+
mergedCount = items.length;
|
|
87326
87714
|
const attempt = attempts.at(-1);
|
|
87327
|
-
if (attempt)
|
|
87328
|
-
|
|
87715
|
+
if (attempt) {
|
|
87716
|
+
attempt.count = mergedCount;
|
|
87717
|
+
if (dropped > 0) attempt.dropped = dropped;
|
|
87718
|
+
}
|
|
87719
|
+
return { ...envelope, items };
|
|
87329
87720
|
} finally {
|
|
87330
87721
|
if (options.searchesPath) {
|
|
87331
87722
|
await appendSearchEvent(
|
|
@@ -87451,6 +87842,34 @@ var VapiCallError = class extends Error {
|
|
|
87451
87842
|
paymentRejection;
|
|
87452
87843
|
confirmedSettlement;
|
|
87453
87844
|
};
|
|
87845
|
+
var SOLANA_PAYMENTS_UNSUPPORTED_MESSAGE = "Solana payments are not supported in this version of vAPI yet; they arrive in a later release.";
|
|
87846
|
+
function isSolanaCaip2(network) {
|
|
87847
|
+
return network.startsWith("solana:");
|
|
87848
|
+
}
|
|
87849
|
+
function listingPaymentNetwork(endpointNetwork, serviceNetworks) {
|
|
87850
|
+
if (endpointNetwork !== void 0) return endpointNetwork;
|
|
87851
|
+
return serviceNetworks?.length && serviceNetworks.every(isSolanaCaip2) ? serviceNetworks[0] : void 0;
|
|
87852
|
+
}
|
|
87853
|
+
function assertSupportedListingNetwork(network) {
|
|
87854
|
+
if (network !== void 0 && isSolanaCaip2(network)) {
|
|
87855
|
+
throw new VapiCallError(
|
|
87856
|
+
"unsupported_network",
|
|
87857
|
+
`${SOLANA_PAYMENTS_UNSUPPORTED_MESSAGE} This listing pays on ${network}.`
|
|
87858
|
+
);
|
|
87859
|
+
}
|
|
87860
|
+
}
|
|
87861
|
+
function assertSupportedListingResolution(error61) {
|
|
87862
|
+
if (isDiscoveryCatalogError(error61) && error61.code === "ambiguous_default" && error61.paymentNetworks?.length && error61.paymentNetworks.every(isSolanaCaip2)) {
|
|
87863
|
+
assertSupportedListingNetwork(error61.paymentNetworks[0]);
|
|
87864
|
+
}
|
|
87865
|
+
}
|
|
87866
|
+
function payableConfig(config2, account) {
|
|
87867
|
+
if (account.solana !== void 0) return config2;
|
|
87868
|
+
const networks = Object.fromEntries(
|
|
87869
|
+
Object.entries(config2.networks).filter(([network]) => !isSolanaCaip2(network))
|
|
87870
|
+
);
|
|
87871
|
+
return { ...config2, networks };
|
|
87872
|
+
}
|
|
87454
87873
|
var MAX_RESPONSE_BYTES = 1048576;
|
|
87455
87874
|
var BODY_HEADER_NAMES = [
|
|
87456
87875
|
"content-encoding",
|
|
@@ -87460,12 +87879,15 @@ var BODY_HEADER_NAMES = [
|
|
|
87460
87879
|
"content-type"
|
|
87461
87880
|
];
|
|
87462
87881
|
async function callService(args) {
|
|
87882
|
+
validateTimeoutSeconds(args.input.timeoutSeconds);
|
|
87463
87883
|
const trace = createCallTrace(args);
|
|
87464
87884
|
let execution;
|
|
87465
87885
|
try {
|
|
87466
87886
|
execution = await executeCallService(args, trace);
|
|
87467
87887
|
} catch (error61) {
|
|
87468
|
-
|
|
87888
|
+
if (!(error61 instanceof VapiCallError && (error61.code === "unsupported_network" || error61.code === "unsupported_payment"))) {
|
|
87889
|
+
await recordCallError(args, error61, trace).catch(() => void 0);
|
|
87890
|
+
}
|
|
87469
87891
|
throw error61;
|
|
87470
87892
|
}
|
|
87471
87893
|
try {
|
|
@@ -87513,10 +87935,16 @@ async function executeCallService(args, trace) {
|
|
|
87513
87935
|
config2,
|
|
87514
87936
|
fetchImpl
|
|
87515
87937
|
);
|
|
87938
|
+
} catch (error61) {
|
|
87939
|
+
assertSupportedListingResolution(error61);
|
|
87940
|
+
throw error61;
|
|
87516
87941
|
} finally {
|
|
87517
87942
|
trace.phases.discoverMs = elapsed2(trace, discoverStarted);
|
|
87518
87943
|
}
|
|
87519
87944
|
}
|
|
87945
|
+
assertSupportedListingNetwork(
|
|
87946
|
+
listingPaymentNetwork(endpoint?.payment?.network, endpoint?.serviceNetworks)
|
|
87947
|
+
);
|
|
87520
87948
|
const requestedNetwork = normalizeRequiredNetwork(input2.network);
|
|
87521
87949
|
const listingNetwork = endpoint?.payment?.network;
|
|
87522
87950
|
if (requestedNetwork && listingNetwork && !areSamePaymentNetwork(requestedNetwork, listingNetwork)) {
|
|
@@ -87571,6 +87999,8 @@ async function executeCallService(args, trace) {
|
|
|
87571
87999
|
body: method === "GET" || method === "HEAD" ? void 0 : requestBody
|
|
87572
88000
|
});
|
|
87573
88001
|
const request = createRequest(headers);
|
|
88002
|
+
const probeTimeoutMs = input2.timeoutSeconds === void 0 ? args.timeoutMs ?? 3e4 : Math.min(input2.timeoutSeconds, 30) * 1e3;
|
|
88003
|
+
let requestTimeoutMs = probeTimeoutMs;
|
|
87574
88004
|
const fetchWithGuardedRedirects = async (candidateRequest, followRedirects = true) => {
|
|
87575
88005
|
let currentRequest = candidateRequest;
|
|
87576
88006
|
let followedRedirects = 0;
|
|
@@ -87578,7 +88008,7 @@ async function executeCallService(args, trace) {
|
|
|
87578
88008
|
const attempt = await fetchAttempt(
|
|
87579
88009
|
fetchImpl,
|
|
87580
88010
|
new Request(currentRequest.clone(), { redirect: "manual" }),
|
|
87581
|
-
|
|
88011
|
+
requestTimeoutMs
|
|
87582
88012
|
);
|
|
87583
88013
|
const response = attempt.response;
|
|
87584
88014
|
if (!isRedirectStatus2(response.status)) {
|
|
@@ -87732,8 +88162,13 @@ async function executeCallService(args, trace) {
|
|
|
87732
88162
|
challenge: challengeAttempt,
|
|
87733
88163
|
account,
|
|
87734
88164
|
caps: args.spendCaps ?? config2.spendCaps,
|
|
87735
|
-
config: config2,
|
|
87736
|
-
send: async (paidRequest) => {
|
|
88165
|
+
config: payableConfig(config2, account),
|
|
88166
|
+
send: async (paidRequest, quote) => {
|
|
88167
|
+
requestTimeoutMs = paidRequestTimeoutMs(
|
|
88168
|
+
input2.timeoutSeconds,
|
|
88169
|
+
args.timeoutMs,
|
|
88170
|
+
quote.accepted.maxTimeoutSeconds
|
|
88171
|
+
);
|
|
87737
88172
|
paidAttempt = await fetchWithGuardedRedirects(paidRequest, false);
|
|
87738
88173
|
return paidAttempt;
|
|
87739
88174
|
},
|
|
@@ -87772,7 +88207,7 @@ async function executeCallService(args, trace) {
|
|
|
87772
88207
|
asset: completed.quote.accepted.asset,
|
|
87773
88208
|
payTo: completed.quote.accepted.payTo,
|
|
87774
88209
|
settlement: settlementWithExplorer2(completed.settlement, completed.quote.accepted.network),
|
|
87775
|
-
proof: completed.
|
|
88210
|
+
proof: completed.paymentProof
|
|
87776
88211
|
},
|
|
87777
88212
|
...verificationFor(endpoint),
|
|
87778
88213
|
...expectedRequestFor(endpoint, completed.response.status)
|
|
@@ -87982,7 +88417,7 @@ async function resolveCallEndpoint(id2, endpointName, marketplaceHit, config2, f
|
|
|
87982
88417
|
try {
|
|
87983
88418
|
return registeredEndpoint(await resolveServiceListing(id2, config2, fetchImpl, endpointName));
|
|
87984
88419
|
} catch (error61) {
|
|
87985
|
-
if (!(error61
|
|
88420
|
+
if (!isDiscoveryCatalogError(error61) || error61.code !== "service_not_found") {
|
|
87986
88421
|
throw error61;
|
|
87987
88422
|
}
|
|
87988
88423
|
const discovered = await findMarketplaceApiByRef(id2, config2, fetchImpl);
|
|
@@ -88019,9 +88454,18 @@ async function resolveCallEndpoint(id2, endpointName, marketplaceHit, config2, f
|
|
|
88019
88454
|
);
|
|
88020
88455
|
}
|
|
88021
88456
|
function registeredEndpoint(listing, verification) {
|
|
88457
|
+
const { payment, ...endpoint } = listing.endpoint;
|
|
88458
|
+
if (payment && (typeof payment.protocol === "string" || typeof payment.network !== "string")) {
|
|
88459
|
+
throw new VapiCallError(
|
|
88460
|
+
"unsupported_payment",
|
|
88461
|
+
`Payment protocol ${payment.protocol} is not supported. This client pays x402 exact USDC endpoints only.`
|
|
88462
|
+
);
|
|
88463
|
+
}
|
|
88022
88464
|
return {
|
|
88023
|
-
...
|
|
88465
|
+
...endpoint,
|
|
88466
|
+
...payment ? { payment: { network: payment.network, payTo: payment.payTo } } : {},
|
|
88024
88467
|
verification: verification ?? listing.service.verification,
|
|
88468
|
+
serviceNetworks: listing.service.networks,
|
|
88025
88469
|
registered: true,
|
|
88026
88470
|
resolvedListing: true
|
|
88027
88471
|
};
|
|
@@ -88181,7 +88625,7 @@ async function readResponseBody2(response) {
|
|
|
88181
88625
|
async function fetchAttempt(fetchImpl, request, timeoutMs) {
|
|
88182
88626
|
const controller = new AbortController();
|
|
88183
88627
|
let rejectTimeout = null;
|
|
88184
|
-
const timeoutError = new Error(`API request timed out after ${timeoutMs}
|
|
88628
|
+
const timeoutError = new Error(`API request timed out after ${timeoutMs / 1e3} seconds.`);
|
|
88185
88629
|
const timedOut = new Promise((_resolve, reject) => {
|
|
88186
88630
|
rejectTimeout = reject;
|
|
88187
88631
|
});
|
|
@@ -88221,6 +88665,19 @@ async function fetchAttempt(fetchImpl, request, timeoutMs) {
|
|
|
88221
88665
|
throw error61;
|
|
88222
88666
|
}
|
|
88223
88667
|
}
|
|
88668
|
+
function validateTimeoutSeconds(timeoutSeconds) {
|
|
88669
|
+
if (timeoutSeconds !== void 0 && (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 1 || timeoutSeconds > 300)) {
|
|
88670
|
+
throw new Error("call timeoutSeconds must be an integer from 1 to 300 seconds.");
|
|
88671
|
+
}
|
|
88672
|
+
}
|
|
88673
|
+
function paidRequestTimeoutMs(timeoutSeconds, internalTimeoutMs, offerTimeoutSeconds) {
|
|
88674
|
+
const usableOfferTimeout = Number.isInteger(offerTimeoutSeconds) && offerTimeoutSeconds > 0 ? offerTimeoutSeconds : void 0;
|
|
88675
|
+
if (timeoutSeconds !== void 0) {
|
|
88676
|
+
return Math.min(timeoutSeconds, usableOfferTimeout ?? timeoutSeconds) * 1e3;
|
|
88677
|
+
}
|
|
88678
|
+
if (internalTimeoutMs !== void 0) return internalTimeoutMs;
|
|
88679
|
+
return usableOfferTimeout === void 0 ? 12e4 : Math.min(12e4, Math.max(3e4, usableOfferTimeout * 1e3));
|
|
88680
|
+
}
|
|
88224
88681
|
function mapX402PaymentError(error61, resumeId) {
|
|
88225
88682
|
if (!(error61 instanceof X402PaymentError)) return error61;
|
|
88226
88683
|
if (error61.code === "payment_rejected") {
|
|
@@ -88236,9 +88693,10 @@ function mapX402PaymentError(error61, resumeId) {
|
|
|
88236
88693
|
});
|
|
88237
88694
|
}
|
|
88238
88695
|
const resume = resumeId !== void 0 && error61.possibleSettlement?.authorizationNonce ? ` Check whether it settled with \`vapi pay --resume ${resumeId}\` before paying again.` : "";
|
|
88696
|
+
const timeoutDetail = error61.cause instanceof Error && error61.cause.message.startsWith("API request timed out after ") ? `${error61.cause.message} ` : "";
|
|
88239
88697
|
return new VapiCallError(
|
|
88240
88698
|
"settlement_unknown",
|
|
88241
|
-
`${error61.message}${resume}`,
|
|
88699
|
+
`${timeoutDetail}${error61.message}${resume}`,
|
|
88242
88700
|
error61.possibleSettlement,
|
|
88243
88701
|
{ cause: error61.cause }
|
|
88244
88702
|
);
|
|
@@ -88260,14 +88718,17 @@ async function inspectService(input2, config2, fetchImpl) {
|
|
|
88260
88718
|
try {
|
|
88261
88719
|
listing = await resolveServiceListing(input2.id, config2, fetchImpl, input2.endpoint);
|
|
88262
88720
|
} catch (error61) {
|
|
88263
|
-
|
|
88721
|
+
assertSupportedListingResolution(error61);
|
|
88722
|
+
if (input2.endpoint || !isDiscoveryCatalogError(error61) || error61.code !== "service_not_found") {
|
|
88264
88723
|
throw error61;
|
|
88265
88724
|
}
|
|
88266
88725
|
const hit = await findMarketplaceApiByRef(input2.id, config2, fetchImpl);
|
|
88267
88726
|
if (!hit || hit.kind !== "api" || hit.provenance !== "indexed") throw error61;
|
|
88727
|
+
assertSupportedListingNetwork(hit.execution.network);
|
|
88268
88728
|
return inspectIndexedHit(hit);
|
|
88269
88729
|
}
|
|
88270
88730
|
const { endpoint, service } = listing;
|
|
88731
|
+
assertSupportedListingNetwork(listingPaymentNetwork(endpoint.payment?.network, service.networks));
|
|
88271
88732
|
return {
|
|
88272
88733
|
name: endpoint.name,
|
|
88273
88734
|
method: endpoint.method,
|
|
@@ -88367,13 +88828,7 @@ var inspectToolResultSchema = external_exports.object({
|
|
|
88367
88828
|
liveness: listingLivenessSchema.optional(),
|
|
88368
88829
|
conformance: listingConformanceSchema.optional(),
|
|
88369
88830
|
identity: listingIdentitySchema.optional(),
|
|
88370
|
-
payment:
|
|
88371
|
-
scheme: external_exports.literal("exact"),
|
|
88372
|
-
network: external_exports.string(),
|
|
88373
|
-
asset: external_exports.string(),
|
|
88374
|
-
payTo: external_exports.string(),
|
|
88375
|
-
checkedAt: external_exports.string()
|
|
88376
|
-
}).nullable()
|
|
88831
|
+
payment: discoveryEndpointSchema.shape.payment.unwrap().nullable()
|
|
88377
88832
|
});
|
|
88378
88833
|
var callSearchInputSchema = external_exports.object({
|
|
88379
88834
|
query: external_exports.string().trim().max(200).optional().describe("Capability, API, service, or request."),
|
|
@@ -88402,7 +88857,10 @@ var callPayInputSchema = external_exports.object({
|
|
|
88402
88857
|
(value) => /^0x[0-9a-fA-F]{40}$/.test(value) || isSolanaAddress(value),
|
|
88403
88858
|
"Expected an EVM or Solana address."
|
|
88404
88859
|
).optional(),
|
|
88405
|
-
maxPriceUsd: external_exports.union([external_exports.number().nonnegative(), external_exports.string().regex(/^\d+(?:\.\d{1,6})?$/)]).optional()
|
|
88860
|
+
maxPriceUsd: external_exports.union([external_exports.number().nonnegative(), external_exports.string().regex(/^\d+(?:\.\d{1,6})?$/)]).optional(),
|
|
88861
|
+
timeoutSeconds: external_exports.number().int().min(1).max(300).optional().describe(
|
|
88862
|
+
"Seconds to wait for the paid response. Default: the provider's maxTimeoutSeconds, at most 120."
|
|
88863
|
+
)
|
|
88406
88864
|
});
|
|
88407
88865
|
var callSearch = defineAction({
|
|
88408
88866
|
name: "call.search",
|
|
@@ -88665,7 +89123,7 @@ async function readResult(response, signal, secrets = []) {
|
|
|
88665
89123
|
return {
|
|
88666
89124
|
status: response.status,
|
|
88667
89125
|
contentType: contentType === null ? null : redactKnownSecrets2(contentType, secrets),
|
|
88668
|
-
body:
|
|
89126
|
+
body: sanitizeReturnedValue2(await readResponseBody3(response, contentType, signal), secrets)
|
|
88669
89127
|
};
|
|
88670
89128
|
}
|
|
88671
89129
|
async function readResponseBody3(response, contentType, signal) {
|
|
@@ -88710,17 +89168,17 @@ function isJsonContentType2(value) {
|
|
|
88710
89168
|
const mediaType = value?.split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
88711
89169
|
return mediaType === "application/json" || mediaType.endsWith("+json");
|
|
88712
89170
|
}
|
|
88713
|
-
function
|
|
89171
|
+
function sanitizeReturnedValue2(value, secrets, depth = 0) {
|
|
88714
89172
|
if (typeof value === "string") return redactKnownSecrets2(value, secrets);
|
|
88715
89173
|
if (value === null || typeof value !== "object") return value;
|
|
88716
89174
|
if (depth >= 16) return "[redacted nested response value]";
|
|
88717
89175
|
if (Array.isArray(value)) {
|
|
88718
|
-
return value.map((item) =>
|
|
89176
|
+
return value.map((item) => sanitizeReturnedValue2(item, secrets, depth + 1));
|
|
88719
89177
|
}
|
|
88720
89178
|
return Object.fromEntries(
|
|
88721
89179
|
Object.entries(value).map(([key2, item]) => [
|
|
88722
89180
|
redactKnownSecrets2(key2, secrets),
|
|
88723
|
-
|
|
89181
|
+
sanitizeReturnedValue2(item, secrets, depth + 1)
|
|
88724
89182
|
])
|
|
88725
89183
|
);
|
|
88726
89184
|
}
|
|
@@ -92037,6 +92495,7 @@ var moneyParticipant = {
|
|
|
92037
92495
|
"Checksummed 0x address of the other party, taken from tasks.show (the poster's clientAddress when you are the worker; the accepted proposal's providerAddress when you are the poster). The human must supply it; it is compared with the signed scope and stored as local consent. Without it tasks.sign refuses and no local party binding is created, so tasks.fund/deliver/release cannot run from this machine."
|
|
92038
92496
|
).optional()
|
|
92039
92497
|
};
|
|
92498
|
+
var waitForIndexer = external_exports.boolean().default(true).describe("Wait up to 60 seconds for vAPI to index the chain result before returning.");
|
|
92040
92499
|
var cursor = external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
92041
92500
|
function usdWithinEscrow(value, positive = false) {
|
|
92042
92501
|
try {
|
|
@@ -92083,7 +92542,10 @@ var tasksPostTool = descriptor(
|
|
|
92083
92542
|
deadline: external_exports.string(),
|
|
92084
92543
|
intake: external_exports.enum(["proposals", "submissions"]).optional(),
|
|
92085
92544
|
maxAwards: external_exports.number().int().min(TASK_LIMITS.maxAwardsMin).max(TASK_LIMITS.maxAwardsMax).optional(),
|
|
92086
|
-
webhookUrl: httpsUrl.optional()
|
|
92545
|
+
webhookUrl: httpsUrl.optional(),
|
|
92546
|
+
vendor: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/u).describe(
|
|
92547
|
+
"Optional 0x address of a vendor to invite directly; the task is addressed to that wallet and shows up for them. Anyone may still propose."
|
|
92548
|
+
).optional()
|
|
92087
92549
|
}
|
|
92088
92550
|
);
|
|
92089
92551
|
var tasksProposeTool = descriptor(
|
|
@@ -92108,42 +92570,43 @@ var tasksAwardTool = descriptor(
|
|
|
92108
92570
|
{ ...participant, proposalId: id }
|
|
92109
92571
|
);
|
|
92110
92572
|
var tasksSignTool = descriptor(
|
|
92111
|
-
"
|
|
92112
|
-
moneyParticipant
|
|
92573
|
+
"Signs the user's own task scope locally with the user's vault wallet after the human confirms the money direction via counterparty; a worker may also create the unfunded escrow; nothing is custodial. Does not move money. Waits up to 60 seconds for vAPI to index a created escrow by default.",
|
|
92574
|
+
{ ...moneyParticipant, wait: waitForIndexer }
|
|
92113
92575
|
);
|
|
92114
92576
|
var tasksFundTool = descriptor(
|
|
92115
|
-
"
|
|
92116
|
-
moneyParticipant
|
|
92577
|
+
"Executes the user's own funding of this task from the user's vault wallet, within the spend policy the user configured; nothing is custodial. MCP cannot grant human approval; amounts above the approval threshold are refused with approval:true. Waits up to 60 seconds for vAPI to index the locked escrow by default.",
|
|
92578
|
+
{ ...moneyParticipant, wait: waitForIndexer }
|
|
92117
92579
|
);
|
|
92118
92580
|
var tasksDeliverTool = descriptor(
|
|
92119
|
-
"Does not move money. Upload local delivery files, freeze the manifest and record delivery with the local vault wallet.",
|
|
92581
|
+
"Does not move money. Upload local delivery files, freeze the manifest and record delivery with the local vault wallet. Waits up to 60 seconds for vAPI to index the delivery by default.",
|
|
92120
92582
|
{
|
|
92121
92583
|
...moneyParticipant,
|
|
92584
|
+
wait: waitForIndexer,
|
|
92122
92585
|
files: external_exports.array(localPath).min(TASK_LIMITS.deliveryFilesMin).max(TASK_LIMITS.deliveryFilesMax),
|
|
92123
92586
|
note: external_exports.string().max(TASK_LIMITS.deliveryNoteMax).refine((value) => value.trim().length > 0)
|
|
92124
92587
|
}
|
|
92125
92588
|
);
|
|
92126
92589
|
var tasksReleaseTool = descriptor(
|
|
92127
|
-
"
|
|
92128
|
-
moneyParticipant
|
|
92590
|
+
"Executes the user's own payment to the worker from task escrow with the user's vault wallet; nothing is custodial. Returns gross \xB7 fee \xB7 net using the deployed fee. Waits up to 60 seconds for vAPI to index the release by default.",
|
|
92591
|
+
{ ...moneyParticipant, wait: waitForIndexer }
|
|
92129
92592
|
);
|
|
92130
92593
|
var tasksRefundTool = descriptor(
|
|
92131
|
-
"
|
|
92594
|
+
"Executes the user's own refund of escrowed USDC to the poster with the user's vault wallet; nothing is custodial. Returns gross \xB7 fee \xB7 net using the deployed fee.",
|
|
92132
92595
|
moneyParticipant
|
|
92133
92596
|
);
|
|
92134
92597
|
var tasksDisputeTool = descriptor(
|
|
92135
|
-
"
|
|
92598
|
+
"Executes the user's own approval of the verified dispute fee and raises a dispute with the user's vault wallet; nothing is custodial. Applies task and daily caps; MCP refuses human approval with approval:true. Accepts a precomputed evidence hash.",
|
|
92136
92599
|
{
|
|
92137
92600
|
...moneyParticipant,
|
|
92138
92601
|
evidenceHash: external_exports.string().regex(TASK_LIMITS.disputeEvidenceHash)
|
|
92139
92602
|
}
|
|
92140
92603
|
);
|
|
92141
92604
|
var tasksCounterEvidenceTool = descriptor(
|
|
92142
|
-
"
|
|
92605
|
+
"Executes the user's own counter-evidence submission and approval of the verified dispute fee with the user's vault wallet as the non-opener before the onchain deadline; nothing is custodial. Applies task and daily caps; MCP refuses human approval with approval:true.",
|
|
92143
92606
|
{ ...moneyParticipant, evidenceHash: external_exports.string().regex(TASK_LIMITS.disputeEvidenceHash) }
|
|
92144
92607
|
);
|
|
92145
92608
|
var tasksResolveUnmatchedTool = descriptor(
|
|
92146
|
-
"
|
|
92609
|
+
"Executes the user's own resolution of an unmatched dispute with the user's vault wallet after the onchain counter-evidence deadline when no counter-evidence was submitted; nothing is custodial.",
|
|
92147
92610
|
moneyParticipant
|
|
92148
92611
|
);
|
|
92149
92612
|
var tasksMessageTool = descriptor(
|
|
@@ -92167,8 +92630,8 @@ var tasksWatchTool = descriptor(
|
|
|
92167
92630
|
}
|
|
92168
92631
|
);
|
|
92169
92632
|
var tasksStatusTool = descriptor(
|
|
92170
|
-
"Does not move money. Read the public task card
|
|
92171
|
-
|
|
92633
|
+
"Does not move money. Read signed-in chain state and participant events, or the public task card without sign-in.",
|
|
92634
|
+
participant
|
|
92172
92635
|
);
|
|
92173
92636
|
var signInHint = "Call auth.link for the acting wallet.";
|
|
92174
92637
|
function lazyTasksChain(factory, pending) {
|
|
@@ -92308,6 +92771,22 @@ function createTasksTools(options) {
|
|
|
92308
92771
|
};
|
|
92309
92772
|
};
|
|
92310
92773
|
}
|
|
92774
|
+
async function waitAfterChain(ctx, orderId, milestoneId, target) {
|
|
92775
|
+
return await taskRequest(
|
|
92776
|
+
target,
|
|
92777
|
+
"getOrder",
|
|
92778
|
+
() => waitForMilestone(ctx.client, {
|
|
92779
|
+
orderId,
|
|
92780
|
+
milestoneId,
|
|
92781
|
+
target,
|
|
92782
|
+
timeoutMs: 6e4,
|
|
92783
|
+
intervalMs: 3e3,
|
|
92784
|
+
...options.sleep === void 0 ? {} : { sleep: options.sleep },
|
|
92785
|
+
now
|
|
92786
|
+
}),
|
|
92787
|
+
ctx
|
|
92788
|
+
);
|
|
92789
|
+
}
|
|
92311
92790
|
async function feeAction(verb, input2) {
|
|
92312
92791
|
const ctx = await acting(input2.wallet);
|
|
92313
92792
|
const policy = await taskPolicyForWallet({
|
|
@@ -92350,7 +92829,12 @@ function createTasksTools(options) {
|
|
|
92350
92829
|
throw new TaskInputError("deadline must be at least 10 minutes from now.");
|
|
92351
92830
|
const ctx = await acting(input2.wallet);
|
|
92352
92831
|
const outcome = await postTask(ctx, {
|
|
92353
|
-
order: {
|
|
92832
|
+
order: {
|
|
92833
|
+
title: input2.title,
|
|
92834
|
+
description: input2.brief,
|
|
92835
|
+
policyFamily: "general-digital",
|
|
92836
|
+
...input2.vendor === void 0 ? {} : { invitedProviderAddress: input2.vendor }
|
|
92837
|
+
},
|
|
92354
92838
|
amount: parseUsdToBaseUnits(input2.amountUsd),
|
|
92355
92839
|
deadlineAt: new Date(postedAt.getTime() + deadlineDuration).toISOString(),
|
|
92356
92840
|
...input2.intake === void 0 ? {} : { intake: input2.intake },
|
|
@@ -92408,15 +92892,15 @@ function createTasksTools(options) {
|
|
|
92408
92892
|
const ctx = await acting(input2.wallet);
|
|
92409
92893
|
const signerAddress = (await options.session.addressesFor(ctx.selected.name)).address;
|
|
92410
92894
|
try {
|
|
92411
|
-
|
|
92412
|
-
|
|
92413
|
-
|
|
92414
|
-
|
|
92415
|
-
|
|
92416
|
-
|
|
92417
|
-
|
|
92418
|
-
|
|
92419
|
-
);
|
|
92895
|
+
const outcome = await signTaskScope(ctx, {
|
|
92896
|
+
id: input2.id,
|
|
92897
|
+
counterparty: input2.counterparty,
|
|
92898
|
+
signerAddress,
|
|
92899
|
+
bindings: createScopeBindings(home),
|
|
92900
|
+
signMessage: async (message) => (await unlock(ctx.selected.name)()).signMessage(message)
|
|
92901
|
+
});
|
|
92902
|
+
const wait2 = input2.wait && outcome.escrowCreation ? await waitAfterChain(ctx, input2.id, outcome.escrowCreation.milestone.id, "created") : null;
|
|
92903
|
+
return taskResult({ ...outcome, wait: wait2 });
|
|
92420
92904
|
} catch (error61) {
|
|
92421
92905
|
if (!(error61 instanceof TasksScopeCreationError)) throw error61;
|
|
92422
92906
|
try {
|
|
@@ -92452,28 +92936,31 @@ function createTasksTools(options) {
|
|
|
92452
92936
|
// Stdio has no human approval channel. Model arguments cannot grant approval.
|
|
92453
92937
|
approval: { granted: false }
|
|
92454
92938
|
});
|
|
92455
|
-
|
|
92939
|
+
const wait2 = input2.wait && outcome.ok ? await waitAfterChain(ctx, input2.id, outcome.result.milestone.id, "locked") : null;
|
|
92940
|
+
return taskResult({ ...outcome, wait: wait2 }, !outcome.ok);
|
|
92456
92941
|
},
|
|
92457
92942
|
async deliver(input2) {
|
|
92458
92943
|
const files = (await Promise.all(input2.files.map(readTaskFile))).map(
|
|
92459
92944
|
({ fileName: name, bytes, contentType }) => ({ name, bytes, contentType })
|
|
92460
92945
|
);
|
|
92461
|
-
|
|
92462
|
-
|
|
92463
|
-
|
|
92464
|
-
|
|
92465
|
-
|
|
92466
|
-
|
|
92467
|
-
|
|
92468
|
-
);
|
|
92946
|
+
const ctx = await acting(input2.wallet);
|
|
92947
|
+
const outcome = await deliverTaskOperation(ctx, {
|
|
92948
|
+
id: input2.id,
|
|
92949
|
+
...input2.counterparty === void 0 ? {} : { counterparty: input2.counterparty },
|
|
92950
|
+
files,
|
|
92951
|
+
note: input2.note
|
|
92952
|
+
});
|
|
92953
|
+
const wait2 = input2.wait ? await waitAfterChain(ctx, input2.id, outcome.result.milestone.id, "delivered") : null;
|
|
92954
|
+
return taskResult({ ...outcome, wait: wait2 });
|
|
92469
92955
|
},
|
|
92470
92956
|
async release(input2) {
|
|
92471
|
-
|
|
92472
|
-
|
|
92473
|
-
|
|
92474
|
-
|
|
92475
|
-
|
|
92476
|
-
);
|
|
92957
|
+
const ctx = await acting(input2.wallet);
|
|
92958
|
+
const outcome = await releaseTaskOperation(ctx, {
|
|
92959
|
+
id: input2.id,
|
|
92960
|
+
...input2.counterparty === void 0 ? {} : { counterparty: input2.counterparty }
|
|
92961
|
+
});
|
|
92962
|
+
const wait2 = input2.wait ? await waitAfterChain(ctx, input2.id, outcome.result.milestone.id, "released") : null;
|
|
92963
|
+
return taskResult({ ...outcome, wait: wait2 });
|
|
92477
92964
|
},
|
|
92478
92965
|
async refund(input2) {
|
|
92479
92966
|
return taskResult(
|
|
@@ -92540,7 +93027,11 @@ function createTasksTools(options) {
|
|
|
92540
93027
|
}
|
|
92541
93028
|
},
|
|
92542
93029
|
async status(input2) {
|
|
92543
|
-
|
|
93030
|
+
await options.wallets?.reload();
|
|
93031
|
+
const publicOnly = input2.wallet === void 0 && options.session.activeName === void 0 && options.wallets !== void 0 && options.wallets.names().length === 0;
|
|
93032
|
+
const candidate = await context(input2.wallet, publicOnly);
|
|
93033
|
+
const ctx = candidate.token || publicOnly ? candidate : await context(void 0, true);
|
|
93034
|
+
return taskResult(await taskStatus(ctx, { id: input2.id, signedIn: Boolean(ctx.token) }));
|
|
92544
93035
|
}
|
|
92545
93036
|
};
|
|
92546
93037
|
}
|
|
@@ -93297,6 +93788,11 @@ var statsToolResultSchema = external_exports.object({
|
|
|
93297
93788
|
)
|
|
93298
93789
|
})
|
|
93299
93790
|
});
|
|
93791
|
+
function objectOutputSchema(schema) {
|
|
93792
|
+
if (!schema) return {};
|
|
93793
|
+
const json2 = external_exports.toJSONSchema(schema);
|
|
93794
|
+
return json2.type === "object" ? { outputSchema: json2 } : {};
|
|
93795
|
+
}
|
|
93300
93796
|
var VapiMcpServer = class {
|
|
93301
93797
|
#tools = /* @__PURE__ */ new Map();
|
|
93302
93798
|
#onClose;
|
|
@@ -93320,7 +93816,7 @@ var VapiMcpServer = class {
|
|
|
93320
93816
|
name,
|
|
93321
93817
|
...tool.description ? { description: tool.description } : {},
|
|
93322
93818
|
inputSchema: external_exports.toJSONSchema(tool.inputSchema),
|
|
93323
|
-
...
|
|
93819
|
+
...objectOutputSchema(tool.outputSchema)
|
|
93324
93820
|
}))
|
|
93325
93821
|
};
|
|
93326
93822
|
}
|
|
@@ -94188,7 +94684,13 @@ function toolError(error61) {
|
|
|
94188
94684
|
{
|
|
94189
94685
|
error: error61.message,
|
|
94190
94686
|
code: error61.code,
|
|
94191
|
-
...error61.possibleSettlement ? {
|
|
94687
|
+
...error61.possibleSettlement ? {
|
|
94688
|
+
possibleSettlement: Object.fromEntries(
|
|
94689
|
+
Object.entries(error61.possibleSettlement).filter(
|
|
94690
|
+
([key2]) => key2 !== "authorizationTransaction"
|
|
94691
|
+
)
|
|
94692
|
+
)
|
|
94693
|
+
} : {},
|
|
94192
94694
|
...error61.paymentRejection ? { paymentRejection: error61.paymentRejection } : {},
|
|
94193
94695
|
...error61.confirmedSettlement ? { confirmedSettlement: error61.confirmedSettlement } : {}
|
|
94194
94696
|
},
|
|
@@ -97682,7 +98184,7 @@ async function readProcessStdin() {
|
|
|
97682
98184
|
}
|
|
97683
98185
|
|
|
97684
98186
|
// src/version.ts
|
|
97685
|
-
var CLI_VERSION = "0.9.
|
|
98187
|
+
var CLI_VERSION = "0.9.4";
|
|
97686
98188
|
|
|
97687
98189
|
// src/status.ts
|
|
97688
98190
|
async function statusCommand(argv, json2, io, dependencies) {
|
|
@@ -101184,7 +101686,7 @@ function createLocalRuntime(options) {
|
|
|
101184
101686
|
const processCommand = options.processCommand ?? defaultProcessCommand;
|
|
101185
101687
|
const ownsProcess = (handle, pid) => processCommand(pid)?.includes(runResultPath(home, handle.runId)) === true;
|
|
101186
101688
|
const closeFd = options.closeFd ?? closeSync2;
|
|
101187
|
-
const
|
|
101689
|
+
const readFile30 = options.readFile ?? nodeReadFile;
|
|
101188
101690
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
101189
101691
|
const openLog = options.openLog ?? ((path) => {
|
|
101190
101692
|
mkdirSync2(runsDirectory(home), { recursive: true, mode: 448 });
|
|
@@ -101239,7 +101741,7 @@ function createLocalRuntime(options) {
|
|
|
101239
101741
|
return handle;
|
|
101240
101742
|
},
|
|
101241
101743
|
async status(handle) {
|
|
101242
|
-
const result = await readResultFile(
|
|
101744
|
+
const result = await readResultFile(readFile30, runResultPath(home, handle.runId));
|
|
101243
101745
|
if (result !== void 0) return result;
|
|
101244
101746
|
const pid = localPid(handle);
|
|
101245
101747
|
if (pid === void 0 || handle.kind !== "local") {
|
|
@@ -101342,10 +101844,10 @@ function childArguments(member, run) {
|
|
|
101342
101844
|
...run.drawUsd ? ["--draw", run.drawUsd] : []
|
|
101343
101845
|
];
|
|
101344
101846
|
}
|
|
101345
|
-
async function readResultFile(
|
|
101847
|
+
async function readResultFile(readFile30, path) {
|
|
101346
101848
|
let text;
|
|
101347
101849
|
try {
|
|
101348
|
-
text = await
|
|
101850
|
+
text = await readFile30(path, "utf8");
|
|
101349
101851
|
} catch (error61) {
|
|
101350
101852
|
if (hasCode3(error61, "ENOENT")) return void 0;
|
|
101351
101853
|
return { state: "failed", detail: "unreadable result file" };
|
|
@@ -102195,7 +102697,7 @@ function isMcpInstallApp(value) {
|
|
|
102195
102697
|
function serverEntry(home, registry2) {
|
|
102196
102698
|
return {
|
|
102197
102699
|
command: "npx",
|
|
102198
|
-
args: ["-y", "vapi-network", "mcp"],
|
|
102700
|
+
args: ["-y", "vapi-network@latest", "mcp"],
|
|
102199
102701
|
env: { VAPI_HOME: home, VAPI_REGISTRY_URL: registry2 }
|
|
102200
102702
|
};
|
|
102201
102703
|
}
|
|
@@ -102244,7 +102746,7 @@ function tomlConfig(existing, entry) {
|
|
|
102244
102746
|
const block = [
|
|
102245
102747
|
"[mcp_servers.vapi]",
|
|
102246
102748
|
'command = "npx"',
|
|
102247
|
-
'args = ["-y", "vapi-network", "mcp"]',
|
|
102749
|
+
'args = ["-y", "vapi-network@latest", "mcp"]',
|
|
102248
102750
|
`env = { VAPI_HOME = "${escapeToml(entry.env.VAPI_HOME)}", VAPI_REGISTRY_URL = "${escapeToml(entry.env.VAPI_REGISTRY_URL)}" }`,
|
|
102249
102751
|
""
|
|
102250
102752
|
].join("\n");
|
|
@@ -102411,13 +102913,13 @@ async function sendConfig(dependencies) {
|
|
|
102411
102913
|
// src/setup.ts
|
|
102412
102914
|
import { rm as rm5 } from "node:fs/promises";
|
|
102413
102915
|
import { join as join26 } from "node:path";
|
|
102414
|
-
var SETUP_ARGUMENT_ERROR =
|
|
102916
|
+
var SETUP_ARGUMENT_ERROR = `vapi setup accepts only --no-cloud-backup and --accounts <n> (1-${MAX_RESTORE_ACCOUNTS}); a recovery phrase is typed at the prompt, never passed on the command line.`;
|
|
102415
102917
|
var VAULT_CHOICE = "Create a new vault, or restore one from a recovery phrase? [new/restore] ";
|
|
102416
102918
|
async function setupCommand(argv, json2, io, dependencies) {
|
|
102417
102919
|
let parsed;
|
|
102418
102920
|
try {
|
|
102419
102921
|
parsed = parseArguments(argv, {
|
|
102420
|
-
valueOptions: /* @__PURE__ */ new Set(),
|
|
102922
|
+
valueOptions: /* @__PURE__ */ new Set(["--accounts"]),
|
|
102421
102923
|
booleanOptions: /* @__PURE__ */ new Set(["--no-cloud-backup"]),
|
|
102422
102924
|
maximumPositionals: 0
|
|
102423
102925
|
});
|
|
@@ -102428,6 +102930,7 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102428
102930
|
const paths = getVapiPaths();
|
|
102429
102931
|
const steps = [];
|
|
102430
102932
|
const humanIo = json2 ? stderrIo(io) : io;
|
|
102933
|
+
const accountCount = parseAccountCount(parsed.one("--accounts"));
|
|
102431
102934
|
if (!await fileExists2(paths.config)) {
|
|
102432
102935
|
await writeDefaultConfig(paths.config, process.env, { networks: ["base"] });
|
|
102433
102936
|
steps.push("config");
|
|
@@ -102438,6 +102941,7 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102438
102941
|
let changedVault = false;
|
|
102439
102942
|
let changedAccount = false;
|
|
102440
102943
|
let changedLink = false;
|
|
102944
|
+
let scannedAddresses;
|
|
102441
102945
|
if (!await fileExists2(join26(paths.directory, "vault.json"))) {
|
|
102442
102946
|
const choice = await vaultChoice(dependencies);
|
|
102443
102947
|
if (choice === "restore") {
|
|
@@ -102445,12 +102949,14 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102445
102949
|
throw new Error("Restoring needs a terminal to type the phrase.");
|
|
102446
102950
|
}
|
|
102447
102951
|
const readSecret = dependencies.prompts?.secret ?? promptForSecret;
|
|
102448
|
-
await restoreVaultFromPhrase(
|
|
102952
|
+
const restored = await restoreVaultFromPhrase(
|
|
102449
102953
|
await readSecret("Recovery phrase: "),
|
|
102450
102954
|
config2,
|
|
102451
102955
|
humanIo,
|
|
102452
|
-
dependencies
|
|
102956
|
+
dependencies,
|
|
102957
|
+
accountCount
|
|
102453
102958
|
);
|
|
102959
|
+
scannedAddresses = restored.scannedAddresses;
|
|
102454
102960
|
store = await WalletStore.open(paths.directory, {
|
|
102455
102961
|
secrets: getSecretStore(dependencies),
|
|
102456
102962
|
env: dependencies.env ?? process.env,
|
|
@@ -102503,22 +103009,35 @@ async function setupCommand(argv, json2, io, dependencies) {
|
|
|
102503
103009
|
}
|
|
102504
103010
|
if (json2) {
|
|
102505
103011
|
io.stdout(
|
|
102506
|
-
JSON.stringify({
|
|
103012
|
+
JSON.stringify({
|
|
103013
|
+
vault,
|
|
103014
|
+
account,
|
|
103015
|
+
address: address4,
|
|
103016
|
+
linked,
|
|
103017
|
+
steps,
|
|
103018
|
+
cloudBackup,
|
|
103019
|
+
...scannedAddresses === void 0 ? {} : { scannedAddresses }
|
|
103020
|
+
})
|
|
102507
103021
|
);
|
|
102508
103022
|
}
|
|
102509
103023
|
}
|
|
102510
|
-
async function restoreVaultFromPhrase(phrase, config2, io, dependencies) {
|
|
103024
|
+
async function restoreVaultFromPhrase(phrase, config2, io, dependencies, accountCount) {
|
|
102511
103025
|
const paths = getVapiPaths();
|
|
102512
103026
|
const validatedPhrase = validateRecoveryPhrase(phrase);
|
|
102513
103027
|
const readBalance3 = baseUsdcBalanceReader(config2, dependencies);
|
|
102514
103028
|
const key2 = await loadOrCreateDeviceKey({ secrets: getSecretStore(dependencies) });
|
|
102515
103029
|
let names;
|
|
103030
|
+
let scannedAddresses = 0;
|
|
102516
103031
|
try {
|
|
102517
103032
|
const restored = await restoreVault({
|
|
102518
103033
|
path: join26(paths.directory, "vault.json"),
|
|
102519
103034
|
key: key2,
|
|
102520
103035
|
phrase: validatedPhrase,
|
|
102521
103036
|
probe: async (address4) => await readBalance3(address4) > 0n,
|
|
103037
|
+
...accountCount === void 0 ? {} : { accountCount },
|
|
103038
|
+
onScanComplete: (count) => {
|
|
103039
|
+
scannedAddresses = count;
|
|
103040
|
+
},
|
|
102522
103041
|
...dependencies.now === void 0 ? {} : { now: dependencies.now }
|
|
102523
103042
|
});
|
|
102524
103043
|
names = restored.accounts().map((account) => account.name);
|
|
@@ -102530,8 +103049,25 @@ async function restoreVaultFromPhrase(phrase, config2, io, dependencies) {
|
|
|
102530
103049
|
...names[0] === void 0 ? {} : { wallet: names[0] },
|
|
102531
103050
|
detail: `${names.length} account(s)`
|
|
102532
103051
|
});
|
|
102533
|
-
io.stdout(
|
|
102534
|
-
|
|
103052
|
+
io.stdout(
|
|
103053
|
+
`Vault restored with ${names.length} account(s): ${names.join(", ")}. ${scannedAddresses} address(es) scanned.`
|
|
103054
|
+
);
|
|
103055
|
+
return { names, scannedAddresses };
|
|
103056
|
+
}
|
|
103057
|
+
function parseAccountCount(value) {
|
|
103058
|
+
if (value === void 0) return void 0;
|
|
103059
|
+
if (!/^\d+$/u.test(value)) {
|
|
103060
|
+
throw new UsageError(
|
|
103061
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
103062
|
+
);
|
|
103063
|
+
}
|
|
103064
|
+
const count = Number(value);
|
|
103065
|
+
if (!Number.isSafeInteger(count) || count < 1 || count > MAX_RESTORE_ACCOUNTS) {
|
|
103066
|
+
throw new UsageError(
|
|
103067
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
103068
|
+
);
|
|
103069
|
+
}
|
|
103070
|
+
return count;
|
|
102535
103071
|
}
|
|
102536
103072
|
async function vaultChoice(dependencies) {
|
|
102537
103073
|
const answer = dependencies.prompts?.line === void 0 ? isInteractive(dependencies) ? await promptForLine(VAULT_CHOICE) : "" : await dependencies.prompts.line(VAULT_CHOICE);
|
|
@@ -102631,10 +103167,10 @@ var TASK_HELP = `Usage:
|
|
|
102631
103167
|
vapi task propose <id> --price <usd> --duration <duration> --note <text> [--account <name>] [--json]
|
|
102632
103168
|
vapi task submit <id> --proof <https-url> [--proof <https-url>...] [--file <path>...] [--account <name>] [--json]
|
|
102633
103169
|
vapi task award <id> <proposalId> [--account <name>] [--json]
|
|
102634
|
-
vapi task sign <id> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
102635
|
-
vapi task fund <id> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
102636
|
-
vapi task deliver <id> --files <path...> --note <text> [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
102637
|
-
vapi task release <id> [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
103170
|
+
vapi task sign <id> [--yes] [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
103171
|
+
vapi task fund <id> [--yes] [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
103172
|
+
vapi task deliver <id> --files <path...> --note <text> [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
103173
|
+
vapi task release <id> [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
102638
103174
|
vapi task refund <id> [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
102639
103175
|
vapi task dispute <id> --evidence-hash <0x + 64 hex> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
102640
103176
|
vapi task counter-evidence <id> --evidence-hash <0x + 64 hex> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
|
|
@@ -102657,23 +103193,25 @@ Exit codes:
|
|
|
102657
103193
|
2 policy refusal only (JSON ok:false with reason policy.perTask or policy.perDay)
|
|
102658
103194
|
3 approval needed in non-interactive mode
|
|
102659
103195
|
|
|
102660
|
-
Fund, deliver, release, refund, dispute, counter-evidence, resolve-unmatched and watch auto-release sign with the local vault wallet. The CLI waits for two confirmations and records pending transactions for recovery. It never retries a chain mutation automatically.`;
|
|
103196
|
+
Fund, deliver, release, refund, dispute, counter-evidence, resolve-unmatched and watch auto-release sign with the local vault wallet. The CLI waits for two confirmations and records pending transactions for recovery. It never retries a chain mutation automatically. Sign, fund, deliver and release wait up to 120s for vAPI to index a confirmed transaction unless --no-wait is set; an indexing timeout keeps exit code 0.`;
|
|
102661
103197
|
var IMPLEMENTED_VERBS = TASKS_CLIENT_VERBS;
|
|
102662
103198
|
var USAGE = `Usage: vapi task <${IMPLEMENTED_VERBS.join("|")}>. Run vapi task --help.`;
|
|
102663
103199
|
var TaskCommandError = class extends Error {
|
|
102664
|
-
constructor(code, message, manifestHash) {
|
|
103200
|
+
constructor(code, message, manifestHash, prefixCode = false) {
|
|
102665
103201
|
super(message);
|
|
102666
103202
|
this.code = code;
|
|
102667
103203
|
this.manifestHash = manifestHash;
|
|
103204
|
+
this.prefixCode = prefixCode;
|
|
102668
103205
|
this.name = "TaskCommandError";
|
|
102669
103206
|
}
|
|
102670
103207
|
code;
|
|
102671
103208
|
manifestHash;
|
|
103209
|
+
prefixCode;
|
|
102672
103210
|
};
|
|
102673
103211
|
function mapTaskError(error61) {
|
|
102674
103212
|
if (error61 instanceof TaskInputError) return new UsageError(error61.message);
|
|
102675
103213
|
if (error61 instanceof TaskOperationError)
|
|
102676
|
-
return new TaskCommandError(error61.code, error61.message, error61.manifestHash);
|
|
103214
|
+
return new TaskCommandError(error61.code, error61.message, error61.manifestHash, true);
|
|
102677
103215
|
return error61;
|
|
102678
103216
|
}
|
|
102679
103217
|
async function mapped(operation) {
|
|
@@ -102892,11 +103430,13 @@ async function taskCommandInner(argv, json2, io, dependencies) {
|
|
|
102892
103430
|
"--intake",
|
|
102893
103431
|
"--max-awards",
|
|
102894
103432
|
"--webhook"
|
|
102895
|
-
] : verb === "propose" ? ["--price", "--duration", "--note"] : verb === "submit" ? ["--proof", "--file"] : verb === "thread" ? ["--after"] : verb === "deliver" ? ["--files", "--note"] : ["dispute", "counter-evidence"].includes(verb) ? ["--evidence-hash"] : verb === "watch" ? ["--until", "--timeout", "--interval"] : []
|
|
103433
|
+
] : verb === "propose" ? ["--price", "--duration", "--note"] : verb === "submit" ? ["--proof", "--file"] : verb === "thread" ? ["--after"] : verb === "deliver" ? ["--files", "--note"] : ["dispute", "counter-evidence"].includes(verb) ? ["--evidence-hash"] : verb === "watch" ? ["--until", "--timeout", "--interval"] : [],
|
|
103434
|
+
...["sign", "fund", "deliver", "release"].includes(verb) ? ["--timeout"] : []
|
|
102896
103435
|
]),
|
|
102897
103436
|
booleanOptions: /* @__PURE__ */ new Set([
|
|
102898
103437
|
...verb === "search" ? ["--open"] : [],
|
|
102899
103438
|
...["sign", "fund", "dispute", "counter-evidence"].includes(verb) ? ["--yes"] : [],
|
|
103439
|
+
...["sign", "fund", "deliver", "release"].includes(verb) ? ["--no-wait"] : [],
|
|
102900
103440
|
...verb === "watch" ? ["--auto-release"] : []
|
|
102901
103441
|
]),
|
|
102902
103442
|
repeatableOptions: /* @__PURE__ */ new Set([
|
|
@@ -103052,7 +103592,7 @@ async function taskCommandInner(argv, json2, io, dependencies) {
|
|
|
103052
103592
|
throw new UsageError("message needs text between 1 and 10000 characters.");
|
|
103053
103593
|
}
|
|
103054
103594
|
if (verb === "thread") cursor2 = optionalInteger(parsed.one("--after"), "--after");
|
|
103055
|
-
const context = await taskContext(parsed, io, dependencies
|
|
103595
|
+
const context = await taskContext(parsed, io, dependencies);
|
|
103056
103596
|
if (verb === "show" || verb === "status") {
|
|
103057
103597
|
if (verb === "show" && context.token) {
|
|
103058
103598
|
const result = await showTask(context, { id: id2, signedIn: true });
|
|
@@ -103062,7 +103602,21 @@ async function taskCommandInner(argv, json2, io, dependencies) {
|
|
|
103062
103602
|
...receipts.map((receipt) => `Receipt (from escrow): ${receipt.receiptUrl}`)
|
|
103063
103603
|
]);
|
|
103064
103604
|
} else {
|
|
103065
|
-
const result = verb === "status" ? await taskStatus(context, { id: id2 }) : await showTask(context, { id: id2, signedIn: false });
|
|
103605
|
+
const result = verb === "status" ? await taskStatus(context, { id: id2, signedIn: Boolean(context.token) }) : await showTask(context, { id: id2, signedIn: false });
|
|
103606
|
+
if ("chainState" in result) {
|
|
103607
|
+
const milestoneLines = result.chainState.milestones.map((milestone) => {
|
|
103608
|
+
const ordinal = "ordinal" in milestone && typeof milestone.ordinal === "number" && Number.isFinite(milestone.ordinal) ? milestone.ordinal : milestone.milestoneId;
|
|
103609
|
+
const state = "state" in milestone.read ? ` ${milestone.read.state}` : "";
|
|
103610
|
+
const explorer = milestone.explorerUrl ? ` ${milestone.explorerUrl}` : "";
|
|
103611
|
+
return `milestone ${ordinal}: ${milestone.read.status}${state}${explorer}`;
|
|
103612
|
+
});
|
|
103613
|
+
const eventLines = (result.events ?? []).slice(-10).map((event) => {
|
|
103614
|
+
const createdAt = "createdAt" in event && typeof event.createdAt === "string" ? event.createdAt : event.at;
|
|
103615
|
+
return `${event.sequence} ${event.type} ${createdAt}`;
|
|
103616
|
+
});
|
|
103617
|
+
taskOutput(io, json2, context, verb, result, [...milestoneLines, ...eventLines]);
|
|
103618
|
+
return;
|
|
103619
|
+
}
|
|
103066
103620
|
const task = result.task;
|
|
103067
103621
|
taskOutput(
|
|
103068
103622
|
io,
|
|
@@ -103106,6 +103660,11 @@ async function taskCommandInner(argv, json2, io, dependencies) {
|
|
|
103106
103660
|
async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now) {
|
|
103107
103661
|
taskCounterparty(parsed);
|
|
103108
103662
|
if (verb === "watch") return await watchTask(id2, parsed, json2, io, dependencies, now);
|
|
103663
|
+
const waitsForIndex = ["sign", "fund", "deliver", "release"].includes(verb);
|
|
103664
|
+
const waitTimeoutText = parsed.one("--timeout") ?? "120s";
|
|
103665
|
+
const waitTimeoutMs = waitsForIndex ? parseTaskDuration2(waitTimeoutText, now) : void 0;
|
|
103666
|
+
if (waitTimeoutMs !== void 0 && waitTimeoutMs <= 0)
|
|
103667
|
+
throw new UsageError("--timeout must be positive.");
|
|
103109
103668
|
const disputeEvidenceHash = ["dispute", "counter-evidence"].includes(verb) ? required3(parsed, "--evidence-hash") : void 0;
|
|
103110
103669
|
const counterparty = taskCounterparty(parsed);
|
|
103111
103670
|
if (disputeEvidenceHash !== void 0 && !TASK_LIMITS.disputeEvidenceHash.test(disputeEvidenceHash))
|
|
@@ -103155,9 +103714,24 @@ async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now
|
|
|
103155
103714
|
return await account.signMessage({ message });
|
|
103156
103715
|
}
|
|
103157
103716
|
});
|
|
103158
|
-
|
|
103717
|
+
if (!json2 && result2.escrowCreation?.resumedFromServer)
|
|
103718
|
+
io.stdout("The server had already prepared escrow creation; resumed from it.");
|
|
103719
|
+
const wait3 = result2.escrowCreation ? await waitForTaskIndex(
|
|
103720
|
+
context,
|
|
103721
|
+
dependencies,
|
|
103722
|
+
parsed,
|
|
103723
|
+
json2,
|
|
103724
|
+
io,
|
|
103725
|
+
id2,
|
|
103726
|
+
result2.escrowCreation,
|
|
103727
|
+
"created",
|
|
103728
|
+
"escrow creation",
|
|
103729
|
+
waitTimeoutText,
|
|
103730
|
+
waitTimeoutMs
|
|
103731
|
+
) : null;
|
|
103732
|
+
taskOutput(io, json2, displayContext, verb, { ...result2, wait: wait3 }, [
|
|
103159
103733
|
`Accepted scope for task ${id2}.`,
|
|
103160
|
-
...result2.escrowCreation
|
|
103734
|
+
...result2.escrowCreation && (wait3 === null || wait3.reached) ? ["escrow created"] : []
|
|
103161
103735
|
]);
|
|
103162
103736
|
return;
|
|
103163
103737
|
} catch (error61) {
|
|
@@ -103191,7 +103765,23 @@ async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now
|
|
|
103191
103765
|
taskOutput(io, false, context, verb, {}, [`Prepared delivery manifest ${manifestHash}.`]);
|
|
103192
103766
|
}
|
|
103193
103767
|
});
|
|
103194
|
-
|
|
103768
|
+
const wait3 = await waitForTaskIndex(
|
|
103769
|
+
context,
|
|
103770
|
+
dependencies,
|
|
103771
|
+
parsed,
|
|
103772
|
+
json2,
|
|
103773
|
+
io,
|
|
103774
|
+
id2,
|
|
103775
|
+
outcome.result,
|
|
103776
|
+
"delivered",
|
|
103777
|
+
"delivery",
|
|
103778
|
+
waitTimeoutText,
|
|
103779
|
+
waitTimeoutMs
|
|
103780
|
+
);
|
|
103781
|
+
taskOutput(io, json2, context, verb, { ...outcome, wait: wait3 }, [
|
|
103782
|
+
...wait3 === null || wait3.reached ? ["delivery recorded"] : [],
|
|
103783
|
+
...outcome.result.resumedFromServer === true ? ["The server had already recorded this delivery; resumed from it."] : []
|
|
103784
|
+
]);
|
|
103195
103785
|
return;
|
|
103196
103786
|
}
|
|
103197
103787
|
const snapshot = await taskMoneySnapshot(context.client, id2, void 0, {
|
|
@@ -103254,15 +103844,82 @@ async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now
|
|
|
103254
103844
|
}
|
|
103255
103845
|
if (!outcome.ok && "declined" in outcome)
|
|
103256
103846
|
throw new TaskCommandError("not_approved", "Not approved; nothing was signed.");
|
|
103257
|
-
|
|
103258
|
-
|
|
103259
|
-
|
|
103847
|
+
if (!json2 && outcome.result.resumedFromServer)
|
|
103848
|
+
io.stdout("The server had already prepared this task operation; resumed from it.");
|
|
103849
|
+
const wait3 = verb === "fund" ? await waitForTaskIndex(
|
|
103850
|
+
context,
|
|
103851
|
+
dependencies,
|
|
103852
|
+
parsed,
|
|
103853
|
+
json2,
|
|
103854
|
+
io,
|
|
103855
|
+
id2,
|
|
103856
|
+
outcome.result,
|
|
103857
|
+
"locked",
|
|
103858
|
+
"funding",
|
|
103859
|
+
waitTimeoutText,
|
|
103860
|
+
waitTimeoutMs
|
|
103861
|
+
) : void 0;
|
|
103862
|
+
taskOutput(
|
|
103863
|
+
io,
|
|
103864
|
+
json2,
|
|
103865
|
+
context,
|
|
103866
|
+
verb,
|
|
103867
|
+
wait3 === void 0 ? outcome : { ...outcome, wait: wait3 },
|
|
103868
|
+
verb === "fund" ? wait3 === null || wait3?.reached ? ["escrow funded"] : [] : [`Completed task ${verb} for ${id2}.`]
|
|
103869
|
+
);
|
|
103260
103870
|
return;
|
|
103261
103871
|
}
|
|
103262
103872
|
if (!json2) io.stdout("Policy: explicit user instruction.");
|
|
103263
103873
|
const settlementInput = { id: id2, snapshot, ...counterparty === void 0 ? {} : { counterparty } };
|
|
103264
103874
|
const result = verb === "release" ? await releaseTaskOperation(context, settlementInput) : verb === "refund" ? await refundTaskOperation(context, settlementInput) : await resolveUnmatchedTaskOperation(context, settlementInput);
|
|
103265
|
-
|
|
103875
|
+
if (!json2 && result.result.resumedFromServer)
|
|
103876
|
+
io.stdout("The server had already prepared this task operation; resumed from it.");
|
|
103877
|
+
const wait2 = verb === "release" ? await waitForTaskIndex(
|
|
103878
|
+
context,
|
|
103879
|
+
dependencies,
|
|
103880
|
+
parsed,
|
|
103881
|
+
json2,
|
|
103882
|
+
io,
|
|
103883
|
+
id2,
|
|
103884
|
+
result.result,
|
|
103885
|
+
"released",
|
|
103886
|
+
"release",
|
|
103887
|
+
waitTimeoutText,
|
|
103888
|
+
waitTimeoutMs
|
|
103889
|
+
) : void 0;
|
|
103890
|
+
taskOutput(
|
|
103891
|
+
io,
|
|
103892
|
+
json2,
|
|
103893
|
+
context,
|
|
103894
|
+
verb,
|
|
103895
|
+
wait2 === void 0 ? result : { ...result, wait: wait2 },
|
|
103896
|
+
verb === "release" ? wait2 === null || wait2?.reached ? ["funds released"] : [] : [`Completed task ${verb} for ${id2}.`]
|
|
103897
|
+
);
|
|
103898
|
+
}
|
|
103899
|
+
async function waitForTaskIndex(context, dependencies, parsed, json2, io, orderId, result, target, description, timeoutText, timeoutMs) {
|
|
103900
|
+
if (parsed.has("--no-wait")) return null;
|
|
103901
|
+
if (!json2)
|
|
103902
|
+
io.stdout(
|
|
103903
|
+
`confirmed on chain${result.blockNumber === void 0 ? "" : ` in block ${result.blockNumber}`}, waiting for vAPI to index\u2026`
|
|
103904
|
+
);
|
|
103905
|
+
const wait2 = await taskRequest2(
|
|
103906
|
+
description,
|
|
103907
|
+
"getOrder",
|
|
103908
|
+
() => waitForMilestone(context.client, {
|
|
103909
|
+
orderId,
|
|
103910
|
+
milestoneId: result.milestone.id,
|
|
103911
|
+
target,
|
|
103912
|
+
timeoutMs,
|
|
103913
|
+
intervalMs: 3e3,
|
|
103914
|
+
sleep: context.sleep,
|
|
103915
|
+
now: dependencies.now ?? (() => /* @__PURE__ */ new Date())
|
|
103916
|
+
})
|
|
103917
|
+
);
|
|
103918
|
+
if (!wait2.reached)
|
|
103919
|
+
io.stderr(
|
|
103920
|
+
`vAPI has not indexed the ${description} yet after ${timeoutText}; run vapi task status ${orderId} later.`
|
|
103921
|
+
);
|
|
103922
|
+
return wait2;
|
|
103266
103923
|
}
|
|
103267
103924
|
var ScopeApprovalNeeded = class extends Error {
|
|
103268
103925
|
constructor(terms) {
|
|
@@ -104518,6 +105175,7 @@ async function referencedSleep(milliseconds, signal) {
|
|
|
104518
105175
|
// src/vault.ts
|
|
104519
105176
|
import { join as join27 } from "node:path";
|
|
104520
105177
|
var VAULT_USAGE = "Usage: vapi vault protect|unprotect|lock|unlock|status [--json]";
|
|
105178
|
+
var RESTORE_USAGE = "Usage: vapi restore [--accounts <n> | --from-owner [--owner <0x\u2026>]] [--json]";
|
|
104521
105179
|
var LEGACY_PASSWORD_NOTICE = "VAPI_KEYSTORE_PASSWORD is deprecated for vault passwords; use VAPI_VAULT_PASSWORD instead.";
|
|
104522
105180
|
async function vaultCommand(argv, json2, io, dependencies) {
|
|
104523
105181
|
const subcommand = argv[0];
|
|
@@ -104547,9 +105205,17 @@ async function restoreCommand(argv, json2, io, dependencies) {
|
|
|
104547
105205
|
await restoreFromOwnerCommand(argv, json2, io, dependencies);
|
|
104548
105206
|
return;
|
|
104549
105207
|
}
|
|
104550
|
-
|
|
104551
|
-
|
|
105208
|
+
let parsed;
|
|
105209
|
+
try {
|
|
105210
|
+
parsed = parseArguments(argv, {
|
|
105211
|
+
valueOptions: /* @__PURE__ */ new Set(["--accounts"]),
|
|
105212
|
+
maximumPositionals: 0
|
|
105213
|
+
});
|
|
105214
|
+
} catch (error61) {
|
|
105215
|
+
if (error61 instanceof UsageError) throw new UsageError(RESTORE_USAGE);
|
|
105216
|
+
throw error61;
|
|
104552
105217
|
}
|
|
105218
|
+
const accountCount = parseRestoreAccountCount(parsed.one("--accounts"));
|
|
104553
105219
|
const paths = getVapiPaths();
|
|
104554
105220
|
const path = join27(paths.directory, "vault.json");
|
|
104555
105221
|
if (await fileExists2(path)) {
|
|
@@ -104563,13 +105229,39 @@ async function restoreCommand(argv, json2, io, dependencies) {
|
|
|
104563
105229
|
const config2 = await readConfig(paths.config, json2 ? quietIo(io) : io);
|
|
104564
105230
|
const phrase = isStdinInteractive(dependencies) ? await getPrompts(dependencies).secret("Recovery phrase: ") : await (dependencies.readStdin ?? readProcessStdin3)();
|
|
104565
105231
|
const restoreIo = json2 ? quietIo(io) : io;
|
|
104566
|
-
const { names } = await restoreVaultFromPhrase(
|
|
105232
|
+
const { names, scannedAddresses } = await restoreVaultFromPhrase(
|
|
105233
|
+
phrase.trim(),
|
|
105234
|
+
config2,
|
|
105235
|
+
restoreIo,
|
|
105236
|
+
dependencies,
|
|
105237
|
+
accountCount
|
|
105238
|
+
);
|
|
104567
105239
|
if (json2) {
|
|
104568
|
-
output3(
|
|
105240
|
+
output3(
|
|
105241
|
+
io,
|
|
105242
|
+
true,
|
|
105243
|
+
{ command: "restore", vault: "restored", accounts: names, scannedAddresses },
|
|
105244
|
+
""
|
|
105245
|
+
);
|
|
104569
105246
|
return;
|
|
104570
105247
|
}
|
|
104571
105248
|
io.stdout(`Run vapi setup to link ${names[0]}.`);
|
|
104572
105249
|
}
|
|
105250
|
+
function parseRestoreAccountCount(value) {
|
|
105251
|
+
if (value === void 0) return void 0;
|
|
105252
|
+
if (!/^\d+$/u.test(value)) {
|
|
105253
|
+
throw new UsageError(
|
|
105254
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
105255
|
+
);
|
|
105256
|
+
}
|
|
105257
|
+
const count = Number(value);
|
|
105258
|
+
if (!Number.isSafeInteger(count) || count < 1 || count > MAX_RESTORE_ACCOUNTS) {
|
|
105259
|
+
throw new UsageError(
|
|
105260
|
+
`--accounts must be a positive integer no greater than ${MAX_RESTORE_ACCOUNTS}.`
|
|
105261
|
+
);
|
|
105262
|
+
}
|
|
105263
|
+
return count;
|
|
105264
|
+
}
|
|
104573
105265
|
async function protectCommand(argv, json2, io, dependencies) {
|
|
104574
105266
|
requireNoArguments(argv);
|
|
104575
105267
|
const env = getEnvironment(dependencies);
|
|
@@ -104699,8 +105391,8 @@ var HELP_HEADING = "vAPI Network";
|
|
|
104699
105391
|
var HELP = `${HELP_HEADING}
|
|
104700
105392
|
|
|
104701
105393
|
Usage:
|
|
104702
|
-
vapi init [--networks <base,arc
|
|
104703
|
-
vapi setup [--no-cloud-backup] [--json]
|
|
105394
|
+
vapi init [--networks <base,arc>] [--json]
|
|
105395
|
+
vapi setup [--no-cloud-backup] [--accounts <n>] [--json]
|
|
104704
105396
|
vapi accounts [--all] [--json]
|
|
104705
105397
|
vapi accounts add <name> [--label <text>] [--no-link] [--json]
|
|
104706
105398
|
vapi accounts import <name> [--keystore <path> | --key-file <path>] [--label <text>] [--json]
|
|
@@ -104730,7 +105422,7 @@ Usage:
|
|
|
104730
105422
|
vapi docs read <url-or-path> [--json]
|
|
104731
105423
|
vapi search [query] [--kind <kind>] [--network <caip2>] [--limit <n>] [--cursor <cursor>] [--include-unverified] [--json]
|
|
104732
105424
|
vapi inspect <id> [--endpoint <name>] [--json]
|
|
104733
|
-
vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--account <name>] [--json]
|
|
105425
|
+
vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--timeout <seconds>] [--account <name>] [--json]
|
|
104734
105426
|
vapi pay --resume <receipt-id> [--json]
|
|
104735
105427
|
vapi check <url> [--method <method>] [--json]
|
|
104736
105428
|
vapi balance [--account <name>] [--json]
|
|
@@ -104776,8 +105468,8 @@ Usage:
|
|
|
104776
105468
|
vapi task status <id> [--account <name>] [--json]
|
|
104777
105469
|
vapi export-key [--network <caip2>] [--account <name>] [--json]
|
|
104778
105470
|
vapi backup [--account <name>] [--cloud [off]] [--json]
|
|
104779
|
-
vapi restore [--from-owner [--owner <0x\u2026>]] [--json]
|
|
104780
|
-
vapi import (--phrase | --key) [--account <name>] [--networks <base,arc
|
|
105471
|
+
vapi restore [--accounts <n> | --from-owner [--owner <0x\u2026>]] [--json]
|
|
105472
|
+
vapi import (--phrase | --key) [--account <name>] [--networks <base,arc>] [--replace] [--force] [--json]
|
|
104781
105473
|
vapi passphrase [--account <name>] [--json]
|
|
104782
105474
|
vapi vault protect [--json]
|
|
104783
105475
|
vapi vault unprotect [--json]
|
|
@@ -104805,6 +105497,8 @@ Every command that touches a wallet takes \`--account <name>\`, falls back to \`
|
|
|
104805
105497
|
|
|
104806
105498
|
\`vapi search\` answers with vAPI-verified listings plus the mirrored external catalogs. \`--include-unverified\` also returns self-listed APIs that passed vAPI's automated x402 probe but were never reviewed; every result is tagged \`[verified]\`, \`[requested]\`, \`[unverified]\` or \`[external]\`.
|
|
104807
105499
|
|
|
105500
|
+
Solana listings remain searchable; inspect and pay return \`unsupported_network\`. Solana keys are not part of the device vault yet.
|
|
105501
|
+
|
|
104808
105502
|
\`vapi docs\` asks the public vAPI documentation assistant; \`vapi docs search\` searches documentation excerpts and \`vapi docs read\` reads one Markdown page. They need no account, wallet or payment.
|
|
104809
105503
|
|
|
104810
105504
|
\`vapi task --help\` lists task options and availability. Task exit codes: 0 ok, 1 error, 2 policy refusal (JSON ok:false with a policy. reason) or invalid usage (JSON error), 3 approval needed in non-interactive mode. Posting moves no money; the current create-order contract does not store amount, deadline, intake, max awards or webhook yet.
|
|
@@ -104817,7 +105511,7 @@ Every command that touches a wallet takes \`--account <name>\`, falls back to \`
|
|
|
104817
105511
|
|
|
104818
105512
|
\`vapi vault protect\` adds a password to the device vault. \`vapi vault unlock\` opens it on this device for 8 hours; for unattended use, set \`VAPI_VAULT_PASSWORD\`. \`vapi unlock\` and \`vapi lock\` remain aliases for one release.
|
|
104819
105513
|
|
|
104820
|
-
\`vapi backup\` and \`vapi export-key\` print a secret, so they run only on a real terminal, never for an agent, and ask you to type the wallet name first. \`vapi backup --cloud\` keeps an encrypted vault copy that only the owner can approve for recovery. \`vapi restore\` rebuilds the vault from the phrase and re-derives accounts until
|
|
105514
|
+
\`vapi backup\` and \`vapi export-key\` print a secret, so they run only on a real terminal, never for an agent, and ask you to type the wallet name first. \`vapi backup --cloud\` keeps an encrypted vault copy that only the owner can approve for recovery. \`vapi restore\` rebuilds the vault from the phrase and re-derives accounts until five consecutive addresses have no Base USDC, and reports the number scanned. Use \`--accounts <n>\` with restore or setup to recover a fixed count without querying balances. Set \`VAPI_NO_SECRETS=1\` to switch exports off entirely. Every export and every wallet change is logged to ~/.vapi/audit.log.
|
|
104821
105515
|
|
|
104822
105516
|
\`vapi publish <url>\` lists an API you own. vAPI probes the URL \u2014 an origin, one endpoint, or an OpenAPI document \u2014 you choose which endpoints to list, and your wallet signs one line naming where the payouts go. Listing is permissionless: a listing that passed the probe goes live with \`vapi publish activate <slug>\`, and \`vapi publish verify-request <slug>\` asks for the review that puts it in the default search. Deploying the FeeSplitter that receives the payouts is a wallet transaction and stays in the console. A catalog of more than 20 endpoints is listed as several listings of up to 20, with one result line per endpoint; \`--resume\` skips every endpoint this key already lists.
|
|
104823
105517
|
|
|
@@ -105194,6 +105888,7 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
|
|
|
105194
105888
|
error: message,
|
|
105195
105889
|
exitCode: code,
|
|
105196
105890
|
...error61 instanceof RuntimeError ? { code: error61.code } : {},
|
|
105891
|
+
...error61 instanceof VapiCallError ? { code: error61.code } : {},
|
|
105197
105892
|
...error61 instanceof DocsError ? { code: error61.code } : {},
|
|
105198
105893
|
...error61 instanceof RemoteKeyRefusedError ? { code: error61.code } : {},
|
|
105199
105894
|
...error61 instanceof TransferError ? { code: error61.code, moneyMoved: error61.moneyMoved } : {}
|
|
@@ -105201,7 +105896,10 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
|
|
|
105201
105896
|
);
|
|
105202
105897
|
}
|
|
105203
105898
|
} else {
|
|
105204
|
-
|
|
105899
|
+
const errorCode2 = taskInvocation && error61 instanceof TaskCommandError && error61.prefixCode ? errorCodeOf(error61) : void 0;
|
|
105900
|
+
runIo.stderr(
|
|
105901
|
+
errorCode2 !== void 0 && !message.startsWith(`${errorCode2}: `) ? `${errorCode2}: ${message}` : message
|
|
105902
|
+
);
|
|
105205
105903
|
}
|
|
105206
105904
|
if (shouldAutoUploadAfterFailure(argv.filter((argument) => argument !== "--json"))) {
|
|
105207
105905
|
await autoUploadBackup(io, json2, dependencies);
|
|
@@ -105602,7 +106300,7 @@ async function inspectCommand(argv, json2, io, dependencies) {
|
|
|
105602
106300
|
);
|
|
105603
106301
|
output3(io, json2, result, formatInspect(result));
|
|
105604
106302
|
}
|
|
105605
|
-
var PAY_USAGE = "Usage: vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--account <name>] [--json]";
|
|
106303
|
+
var PAY_USAGE = "Usage: vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--timeout <seconds>] [--account <name>] [--json]";
|
|
105606
106304
|
async function payCommand(argv, json2, io, dependencies) {
|
|
105607
106305
|
if (argv.includes(RESUME_OPTION)) {
|
|
105608
106306
|
await payResumeCommand(argv, json2, io, dependencies);
|
|
@@ -105618,11 +106316,13 @@ async function payCommand(argv, json2, io, dependencies) {
|
|
|
105618
106316
|
"--expected-pay-to",
|
|
105619
106317
|
"--max",
|
|
105620
106318
|
"--max-price-usd",
|
|
106319
|
+
"--timeout",
|
|
105621
106320
|
WALLET_OPTION5
|
|
105622
106321
|
]),
|
|
105623
106322
|
maximumPositionals: 1
|
|
105624
106323
|
});
|
|
105625
106324
|
const target = requiredPositional(parsed.positionals[0], "<id-or-url>", PAY_USAGE);
|
|
106325
|
+
const timeoutSeconds = optionalBoundedInteger(parsed.one("--timeout"), "--timeout", 1, 300);
|
|
105626
106326
|
const paths = getVapiPaths();
|
|
105627
106327
|
const config2 = await readConfig(paths.config, io);
|
|
105628
106328
|
const wallet = await targetWallet(parsed, dependencies);
|
|
@@ -105638,7 +106338,8 @@ async function payCommand(argv, json2, io, dependencies) {
|
|
|
105638
106338
|
...parsed.one("--content-type") ? { contentType: parsed.one("--content-type") } : {},
|
|
105639
106339
|
...parsed.one("--network") ? { network: parsed.one("--network") } : {},
|
|
105640
106340
|
...parsed.one("--expected-pay-to") ? { expectedPayTo: parsed.one("--expected-pay-to") } : {},
|
|
105641
|
-
...maxPriceUsd ? { maxPriceUsd } : {}
|
|
106341
|
+
...maxPriceUsd ? { maxPriceUsd } : {},
|
|
106342
|
+
...timeoutSeconds === void 0 ? {} : { timeoutSeconds }
|
|
105642
106343
|
};
|
|
105643
106344
|
const call2 = createCallPort({
|
|
105644
106345
|
config: config2,
|
|
@@ -107313,7 +108014,7 @@ function buildNextSteps(address4) {
|
|
|
107313
108014
|
formatNextStep("Pay", "vapi pay <ref> --max 0.02"),
|
|
107314
108015
|
formatNextStep(
|
|
107315
108016
|
"Agent",
|
|
107316
|
-
'add {"command":"npx","args":["-y","vapi-network","mcp"]} to your MCP config'
|
|
108017
|
+
'add {"command":"npx","args":["-y","vapi-network@latest","mcp"]} to your MCP config'
|
|
107317
108018
|
)
|
|
107318
108019
|
];
|
|
107319
108020
|
}
|
|
@@ -107494,6 +108195,17 @@ function optionalPositiveInteger(value, option) {
|
|
|
107494
108195
|
if (result === 0) throw new UsageError(`${option} must be a positive integer.`);
|
|
107495
108196
|
return result;
|
|
107496
108197
|
}
|
|
108198
|
+
function optionalBoundedInteger(value, option, minimum, maximum) {
|
|
108199
|
+
if (value === void 0) return void 0;
|
|
108200
|
+
if (!/^\d+$/.test(value)) {
|
|
108201
|
+
throw new UsageError(`${option} must be an integer from ${minimum} to ${maximum}.`);
|
|
108202
|
+
}
|
|
108203
|
+
const parsed = Number(value);
|
|
108204
|
+
if (!Number.isSafeInteger(parsed) || parsed < minimum || parsed > maximum) {
|
|
108205
|
+
throw new UsageError(`${option} must be an integer from ${minimum} to ${maximum}.`);
|
|
108206
|
+
}
|
|
108207
|
+
return parsed;
|
|
108208
|
+
}
|
|
107497
108209
|
function optionalUsdAmount(value, option) {
|
|
107498
108210
|
if (value === void 0) return void 0;
|
|
107499
108211
|
if (!/^\d+(?:\.\d{1,2})?$/.test(value)) {
|
|
@@ -107554,12 +108266,136 @@ function parseInitNetworks(value) {
|
|
|
107554
108266
|
}
|
|
107555
108267
|
for (const network of networks) {
|
|
107556
108268
|
if (network !== "base" && network !== "arc" && network !== "solana") {
|
|
107557
|
-
throw new UsageError("--networks supports base
|
|
108269
|
+
throw new UsageError("--networks supports base and arc; Solana vault setup is unavailable.");
|
|
107558
108270
|
}
|
|
107559
108271
|
}
|
|
107560
108272
|
return networks;
|
|
107561
108273
|
}
|
|
107562
108274
|
|
|
108275
|
+
// src/update-check.ts
|
|
108276
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
108277
|
+
var CHECK_TIMEOUT_MS = 1500;
|
|
108278
|
+
var LATEST_URL = "https://registry.npmjs.org/vapi-network/latest";
|
|
108279
|
+
async function runCliWithUpdateCheck(argv = process.argv.slice(2), io = {
|
|
108280
|
+
stdout: (message) => console.log(message),
|
|
108281
|
+
stderr: (message) => console.error(message)
|
|
108282
|
+
}, dependencies = {}, options = {}) {
|
|
108283
|
+
const notice = checkForUpdate({ ...options, env: options.env ?? dependencies.env, argv });
|
|
108284
|
+
const code = await runCli(argv, io, dependencies);
|
|
108285
|
+
const message = await notice;
|
|
108286
|
+
if (message) io.stderr(message);
|
|
108287
|
+
return code;
|
|
108288
|
+
}
|
|
108289
|
+
async function checkForUpdate(options = {}) {
|
|
108290
|
+
const env = options.env ?? process.env;
|
|
108291
|
+
const argv = options.argv ?? process.argv.slice(2);
|
|
108292
|
+
if (!(options.stderrIsTTY ?? process.stderr.isTTY) || argv.includes("--json") || argv[0] === "mcp" && argv[1] !== "install" || env.VAPI_NO_UPDATE_CHECK === "1" || env.CI !== void 0) {
|
|
108293
|
+
return void 0;
|
|
108294
|
+
}
|
|
108295
|
+
const controller = new AbortController();
|
|
108296
|
+
let timer;
|
|
108297
|
+
try {
|
|
108298
|
+
return await Promise.race([
|
|
108299
|
+
latestNotice(options, env, controller.signal),
|
|
108300
|
+
new Promise((resolve2) => {
|
|
108301
|
+
timer = setTimeout(() => {
|
|
108302
|
+
controller.abort();
|
|
108303
|
+
resolve2(void 0);
|
|
108304
|
+
}, CHECK_TIMEOUT_MS);
|
|
108305
|
+
})
|
|
108306
|
+
]);
|
|
108307
|
+
} catch {
|
|
108308
|
+
return void 0;
|
|
108309
|
+
} finally {
|
|
108310
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
108311
|
+
controller.abort();
|
|
108312
|
+
}
|
|
108313
|
+
}
|
|
108314
|
+
async function latestNotice(options, env, signal) {
|
|
108315
|
+
const paths = getVapiPaths(options.home ?? (env.VAPI_HOME?.trim() || void 0));
|
|
108316
|
+
const now = (options.nowMs ?? Date.now)();
|
|
108317
|
+
let cached2;
|
|
108318
|
+
try {
|
|
108319
|
+
const value = JSON.parse(await readFile29(paths.updateCheck, "utf8"));
|
|
108320
|
+
if (isRecord12(value) && typeof value.checkedAt === "number" && Number.isFinite(value.checkedAt) && typeof value.latest === "string" && parseVersion(value.latest)) {
|
|
108321
|
+
cached2 = { checkedAt: value.checkedAt, latest: value.latest };
|
|
108322
|
+
}
|
|
108323
|
+
} catch {
|
|
108324
|
+
}
|
|
108325
|
+
signal.throwIfAborted();
|
|
108326
|
+
let latest = cached2?.latest ?? CLI_VERSION;
|
|
108327
|
+
if (cached2 === void 0 || now - cached2.checkedAt >= CHECK_INTERVAL_MS || now < cached2.checkedAt) {
|
|
108328
|
+
await mkdir21(paths.directory, { recursive: true });
|
|
108329
|
+
signal.throwIfAborted();
|
|
108330
|
+
await writeFile12(paths.updateCheck, JSON.stringify({ checkedAt: now, latest }), { mode: 384 });
|
|
108331
|
+
signal.throwIfAborted();
|
|
108332
|
+
const fetchImpl = options.fetchImpl ?? createPublicFetch({
|
|
108333
|
+
allowPrivateNetwork: false,
|
|
108334
|
+
lookup: async (hostname3) => {
|
|
108335
|
+
let onAbort;
|
|
108336
|
+
const aborted2 = new Promise((_resolve, reject) => {
|
|
108337
|
+
onAbort = () => reject(signal.reason);
|
|
108338
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
108339
|
+
});
|
|
108340
|
+
try {
|
|
108341
|
+
signal.throwIfAborted();
|
|
108342
|
+
const addresses = await Promise.race([lookup(hostname3, { all: true }), aborted2]);
|
|
108343
|
+
return addresses.map(({ address: address4 }) => address4);
|
|
108344
|
+
} finally {
|
|
108345
|
+
signal.removeEventListener("abort", onAbort);
|
|
108346
|
+
}
|
|
108347
|
+
}
|
|
108348
|
+
});
|
|
108349
|
+
const response = await fetchImpl(LATEST_URL, { signal, redirect: "error" });
|
|
108350
|
+
if (!response.ok) return void 0;
|
|
108351
|
+
const body = await response.json();
|
|
108352
|
+
signal.throwIfAborted();
|
|
108353
|
+
if (!isRecord12(body) || typeof body.version !== "string" || !parseVersion(body.version)) {
|
|
108354
|
+
return void 0;
|
|
108355
|
+
}
|
|
108356
|
+
latest = body.version;
|
|
108357
|
+
await writeFile12(paths.updateCheck, JSON.stringify({ checkedAt: now, latest }), { mode: 384 });
|
|
108358
|
+
}
|
|
108359
|
+
signal.throwIfAborted();
|
|
108360
|
+
return isNewerVersion(latest, CLI_VERSION) ? `vapi-network ${latest} is available (you have ${CLI_VERSION}). Update: npm i -g vapi-network@latest` : void 0;
|
|
108361
|
+
}
|
|
108362
|
+
function isRecord12(value) {
|
|
108363
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
108364
|
+
}
|
|
108365
|
+
function parseVersion(version5) {
|
|
108366
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([\da-zA-Z.-]+))?(?:\+[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?$/.exec(
|
|
108367
|
+
version5
|
|
108368
|
+
);
|
|
108369
|
+
if (!match) return void 0;
|
|
108370
|
+
const prerelease = match[4]?.split(".");
|
|
108371
|
+
if (prerelease?.some((part) => part === "" || /^\d+$/.test(part) && /^0\d/.test(part))) {
|
|
108372
|
+
return void 0;
|
|
108373
|
+
}
|
|
108374
|
+
return { core: match.slice(1, 4).map(BigInt), prerelease };
|
|
108375
|
+
}
|
|
108376
|
+
function isNewerVersion(latest, current) {
|
|
108377
|
+
const next = parseVersion(latest);
|
|
108378
|
+
const running = parseVersion(current);
|
|
108379
|
+
for (let index2 = 0; index2 < 3; index2 += 1) {
|
|
108380
|
+
if (next.core[index2] !== running.core[index2]) return next.core[index2] > running.core[index2];
|
|
108381
|
+
}
|
|
108382
|
+
if (running.prerelease === void 0) return false;
|
|
108383
|
+
if (next.prerelease === void 0) return true;
|
|
108384
|
+
for (let index2 = 0; index2 < Math.max(next.prerelease.length, running.prerelease.length); index2 += 1) {
|
|
108385
|
+
const a = next.prerelease[index2];
|
|
108386
|
+
const b = running.prerelease[index2];
|
|
108387
|
+
if (a === b) continue;
|
|
108388
|
+
if (a === void 0) return false;
|
|
108389
|
+
if (b === void 0) return true;
|
|
108390
|
+
const aNumeric = /^\d+$/.test(a);
|
|
108391
|
+
const bNumeric = /^\d+$/.test(b);
|
|
108392
|
+
if (aNumeric && bNumeric) return BigInt(a) > BigInt(b);
|
|
108393
|
+
if (aNumeric !== bNumeric) return !aNumeric;
|
|
108394
|
+
return a > b;
|
|
108395
|
+
}
|
|
108396
|
+
return false;
|
|
108397
|
+
}
|
|
108398
|
+
|
|
107563
108399
|
// src/main-module.ts
|
|
107564
108400
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
107565
108401
|
import { pathToFileURL } from "node:url";
|
|
@@ -107576,7 +108412,7 @@ function isMainModule(entry, moduleUrl, realpath = realpathSync2) {
|
|
|
107576
108412
|
|
|
107577
108413
|
// src/bin.ts
|
|
107578
108414
|
if (isMainModule(process.argv[1], import.meta.url)) {
|
|
107579
|
-
process.exitCode = await
|
|
108415
|
+
process.exitCode = await runCliWithUpdateCheck();
|
|
107580
108416
|
}
|
|
107581
108417
|
export {
|
|
107582
108418
|
CUSTODY_NOTICE,
|