@vapi-network/cli 0.9.0 → 0.9.2

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/index.js CHANGED
@@ -28987,365 +28987,6 @@ function date4(params) {
28987
28987
  return _coercedDate(ZodDate, params);
28988
28988
  }
28989
28989
 
28990
- // ../core/src/marketplace-contracts.ts
28991
- var MARKETPLACE_DISCOVERY_PROTOCOL = "vapi.marketplace.discovery/1";
28992
- var MARKETPLACE_RANKING_VERSION = "marketplace-ranking-v1";
28993
- var MARKETPLACE_KINDS = ["api", "service_offer", "open_request"];
28994
- var MARKETPLACE_EXECUTION_METHODS = [
28995
- "GET",
28996
- "HEAD",
28997
- "POST",
28998
- "PUT",
28999
- "PATCH",
29000
- "DELETE"
29001
- ];
29002
- var marketplaceExecutionMethodSchema = external_exports.enum(MARKETPLACE_EXECUTION_METHODS);
29003
- var marketplaceKindSchema = external_exports.enum(MARKETPLACE_KINDS);
29004
- var EXECUTION_MODES = ["direct", "gateway"];
29005
- var executionModeSchema = external_exports.enum(EXECUTION_MODES);
29006
- var PROVENANCES = ["indexed", "self_listed", "partner"];
29007
- var provenanceSchema = external_exports.enum(PROVENANCES);
29008
- var FIRST_PARTY_PROVENANCES = ["self_listed", "partner"];
29009
- var firstPartyProvenanceSchema = external_exports.enum(FIRST_PARTY_PROVENANCES);
29010
- var LISTING_GROUPS = ["vapi", "added", "partner", "external"];
29011
- var listingGroupSchema = external_exports.enum(LISTING_GROUPS);
29012
- var listingFeeSchema = external_exports.looseObject({
29013
- bps: external_exports.number().int().min(0),
29014
- label: external_exports.string()
29015
- });
29016
- var LISTING_VERIFICATIONS = ["none", "requested", "verified"];
29017
- var listingVerificationSchema = external_exports.enum(LISTING_VERIFICATIONS);
29018
- var listingVerificationFieldSchema = listingVerificationSchema.default("none").catch("none");
29019
- var listingLivenessSchema = external_exports.looseObject({
29020
- uptime7d: external_exports.number().min(0).max(1),
29021
- latencyP50Ms: external_exports.number().nonnegative().nullable(),
29022
- latencyP95Ms: external_exports.number().nonnegative().nullable(),
29023
- checks7d: external_exports.number().int().nonnegative()
29024
- });
29025
- var listingConformanceSchema = external_exports.looseObject({
29026
- declaredVersion: external_exports.union([external_exports.literal(1), external_exports.literal(2)]).nullable(),
29027
- versionConformant: external_exports.boolean(),
29028
- offerTransport: external_exports.enum(["body", "header", "both"]),
29029
- issues: external_exports.array(external_exports.string())
29030
- });
29031
- var listingIdentitySchema = external_exports.looseObject({
29032
- erc8004Id: external_exports.string().trim().min(1),
29033
- reputation: external_exports.looseObject({
29034
- score: external_exports.number().finite(),
29035
- count: external_exports.number().int().nonnegative()
29036
- }).optional().catch(void 0)
29037
- });
29038
- var listingDisclosureShape = {
29039
- group: listingGroupSchema.optional(),
29040
- fee: listingFeeSchema.optional(),
29041
- verification: listingVerificationFieldSchema,
29042
- liveness: listingLivenessSchema.optional().catch(void 0),
29043
- conformance: listingConformanceSchema.optional().catch(void 0),
29044
- identity: listingIdentitySchema.optional().catch(void 0)
29045
- };
29046
- var marketplaceBadgeCodeSchema = external_exports.enum([
29047
- "live_x402",
29048
- "partner",
29049
- "payout_wallet_confirmed",
29050
- "vapi_verified",
29051
- "external_catalog",
29052
- "approved_vendor"
29053
- ]);
29054
- var marketplaceBadgeSchema = external_exports.looseObject({
29055
- code: marketplaceBadgeCodeSchema,
29056
- label: external_exports.string().trim().min(1).max(80)
29057
- });
29058
- var marketplacePublicFactSchema = external_exports.looseObject({
29059
- label: external_exports.string().trim().min(1).max(80),
29060
- value: external_exports.string().trim().min(1).max(160)
29061
- });
29062
- var marketplaceHrefSchema = external_exports.union([
29063
- external_exports.string().trim().min(1).max(2048).regex(/^\/(?!\/)/),
29064
- external_exports.url().max(2048).regex(/^https:\/\//)
29065
- ]);
29066
- var marketplaceCardSchema = external_exports.looseObject({
29067
- title: external_exports.string().trim().min(1).max(160),
29068
- summary: external_exports.string().trim().min(1).max(1e3),
29069
- byline: external_exports.string().trim().min(1).max(160).optional(),
29070
- bylineHref: marketplaceHrefSchema.optional(),
29071
- badges: external_exports.array(marketplaceBadgeSchema).max(8),
29072
- facts: external_exports.array(marketplacePublicFactSchema).max(12)
29073
- });
29074
- var marketplaceHitBase = {
29075
- ref: external_exports.string().trim().min(1).max(512),
29076
- card: marketplaceCardSchema,
29077
- ...listingDisclosureShape
29078
- };
29079
- var invokeApiActionSchema = external_exports.looseObject({
29080
- type: external_exports.literal("invoke_api"),
29081
- href: marketplaceHrefSchema
29082
- });
29083
- var firstPartyApiMarketplaceHitSchema = external_exports.looseObject({
29084
- ...marketplaceHitBase,
29085
- kind: external_exports.literal("api"),
29086
- provenance: firstPartyProvenanceSchema,
29087
- execution: external_exports.looseObject({
29088
- mode: executionModeSchema
29089
- }),
29090
- action: invokeApiActionSchema
29091
- });
29092
- var mirroredApiMarketplaceHitSchema = external_exports.looseObject({
29093
- ...marketplaceHitBase,
29094
- kind: external_exports.literal("api"),
29095
- provenance: external_exports.literal("indexed"),
29096
- execution: external_exports.looseObject({
29097
- mode: external_exports.literal("direct"),
29098
- url: external_exports.url().max(2048).regex(/^https:\/\/(?![^/?#]*@)/),
29099
- method: marketplaceExecutionMethodSchema.nullable(),
29100
- network: external_exports.string().trim().max(160).regex(/^eip155:[1-9]\d*$/)
29101
- }),
29102
- action: invokeApiActionSchema
29103
- });
29104
- var apiMarketplaceHitSchema = external_exports.discriminatedUnion("provenance", [
29105
- firstPartyApiMarketplaceHitSchema,
29106
- mirroredApiMarketplaceHitSchema
29107
- ]);
29108
- var serviceOfferMarketplaceHitSchema = external_exports.looseObject({
29109
- ...marketplaceHitBase,
29110
- kind: external_exports.literal("service_offer"),
29111
- action: external_exports.looseObject({
29112
- type: external_exports.literal("start_engagement"),
29113
- href: marketplaceHrefSchema
29114
- })
29115
- });
29116
- var openRequestMarketplaceHitSchema = external_exports.looseObject({
29117
- ...marketplaceHitBase,
29118
- kind: external_exports.literal("open_request"),
29119
- action: external_exports.looseObject({
29120
- type: external_exports.literal("propose_to_request"),
29121
- href: marketplaceHrefSchema
29122
- })
29123
- });
29124
- var marketplaceHitSchema = external_exports.union([
29125
- apiMarketplaceHitSchema,
29126
- serviceOfferMarketplaceHitSchema,
29127
- openRequestMarketplaceHitSchema
29128
- ]);
29129
- var marketplaceDiscoveryInputSchema = external_exports.strictObject({
29130
- q: external_exports.string().trim().max(200).optional(),
29131
- kinds: external_exports.array(marketplaceKindSchema).min(1).max(MARKETPLACE_KINDS.length).optional(),
29132
- network: external_exports.string().trim().min(1).max(160).optional(),
29133
- cursor: external_exports.string().trim().min(1).max(4096).optional(),
29134
- limit: external_exports.number().int().min(1).max(50).optional(),
29135
- includeUnverified: external_exports.boolean().optional()
29136
- }).superRefine((input2, context) => {
29137
- if (input2.kinds && new Set(input2.kinds).size !== input2.kinds.length) {
29138
- context.addIssue({
29139
- code: "custom",
29140
- path: ["kinds"],
29141
- message: "Marketplace kinds must be unique"
29142
- });
29143
- }
29144
- });
29145
- function isMirroredHit(hit) {
29146
- return hit.kind === "api" && hit.provenance === "indexed";
29147
- }
29148
- var marketplaceDiscoveryPageSchema = external_exports.looseObject({
29149
- protocol: external_exports.literal(MARKETPLACE_DISCOVERY_PROTOCOL),
29150
- items: external_exports.array(marketplaceHitSchema),
29151
- nextCursor: external_exports.string().min(1).max(4096).nullable(),
29152
- unavailableKinds: external_exports.array(marketplaceKindSchema).max(MARKETPLACE_KINDS.length),
29153
- rankingVersion: external_exports.literal(MARKETPLACE_RANKING_VERSION)
29154
- });
29155
-
29156
- // ../core/src/call-contracts-wire.ts
29157
- var CALLABLE_CATEGORIES = ["ai", "data", "crypto", "compute", "search"];
29158
- var callableCategorySchema = external_exports.enum(CALLABLE_CATEGORIES);
29159
- var DISCOVERY_CATEGORIES = [...CALLABLE_CATEGORIES, "other"];
29160
- var discoveryCategorySchema = external_exports.enum(DISCOVERY_CATEGORIES);
29161
- var CALLABLE_CATEGORY_SET = new Set(CALLABLE_CATEGORIES);
29162
- var serviceTierSchema = external_exports.enum(["listed", "verified", "partner"]);
29163
- var discoveryEndpointSchema = external_exports.looseObject({
29164
- name: external_exports.string(),
29165
- method: external_exports.string(),
29166
- url: external_exports.url(),
29167
- price: external_exports.string(),
29168
- description: external_exports.string(),
29169
- operationId: external_exports.string().trim().min(1).optional(),
29170
- requestContentType: external_exports.string().trim().min(1).optional(),
29171
- requestSchema: external_exports.json().optional(),
29172
- responseContentType: external_exports.string().trim().min(1).optional(),
29173
- pathTemplate: external_exports.string().trim().min(1).optional(),
29174
- pathParameters: external_exports.array(external_exports.string().trim().min(1)).optional(),
29175
- payment: external_exports.looseObject({
29176
- scheme: external_exports.literal("exact"),
29177
- network: external_exports.string().regex(/^eip155:\d+$/),
29178
- asset: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
29179
- payTo: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
29180
- checkedAt: external_exports.iso.datetime()
29181
- }).optional()
29182
- });
29183
- var serviceSummarySchema = external_exports.looseObject({
29184
- id: external_exports.string(),
29185
- name: external_exports.string(),
29186
- description: external_exports.string(),
29187
- category: discoveryCategorySchema,
29188
- tier: serviceTierSchema,
29189
- ...listingDisclosureShape,
29190
- verified: external_exports.boolean(),
29191
- wrapped: external_exports.boolean(),
29192
- price: external_exports.string(),
29193
- networks: external_exports.array(external_exports.string()),
29194
- endpoints: external_exports.array(discoveryEndpointSchema)
29195
- });
29196
- var searchServicesResponseSchema = external_exports.looseObject({
29197
- services: external_exports.array(serviceSummarySchema)
29198
- });
29199
- var discoveryResponseSchema = searchServicesResponseSchema;
29200
-
29201
- // ../core/src/call-contracts.ts
29202
- var DiscoveryCatalogError = class extends Error {
29203
- name = "DiscoveryCatalogError";
29204
- code;
29205
- serviceId;
29206
- constructor(code, message, serviceId) {
29207
- super(message);
29208
- this.code = code;
29209
- this.serviceId = serviceId;
29210
- }
29211
- };
29212
- function parseDiscovery(raw) {
29213
- const parsed = discoveryResponseSchema.safeParse(raw);
29214
- if (!parsed.success) {
29215
- const malformedUrl = parsed.error.issues.find(
29216
- (issue2) => issue2.path.at(-1) === "url" && issue2.path.includes("endpoints")
29217
- );
29218
- if (malformedUrl) {
29219
- const serviceIndex = pathIndexAfter(malformedUrl.path, "services");
29220
- const serviceId = rawServiceId(raw, serviceIndex);
29221
- throw new DiscoveryCatalogError(
29222
- "malformed_url",
29223
- `Service ${JSON.stringify(serviceId ?? "unknown")} has a malformed endpoint URL.`,
29224
- serviceId
29225
- );
29226
- }
29227
- throw new DiscoveryCatalogError("invalid_discovery", "Discovery response is malformed.");
29228
- }
29229
- for (const service of parsed.data.services) {
29230
- buildTargets(service);
29231
- }
29232
- const resolveListing = (serviceId, endpointName) => {
29233
- const service = parsed.data.services.find((candidate) => candidate.id === serviceId);
29234
- if (!service) {
29235
- throw new DiscoveryCatalogError(
29236
- "service_not_found",
29237
- `No payable endpoint found for service ${JSON.stringify(serviceId)}.`,
29238
- serviceId
29239
- );
29240
- }
29241
- return { service, endpoint: resolveTarget(service, endpointName) };
29242
- };
29243
- return {
29244
- services: parsed.data.services,
29245
- resolve: (serviceId, endpointName) => resolveListing(serviceId, endpointName).endpoint,
29246
- resolveListing
29247
- };
29248
- }
29249
- function resolveTarget(service, endpointName) {
29250
- const { targets, targetsByName } = buildTargets(service);
29251
- if (endpointName !== void 0) {
29252
- const selected = targetsByName.get(endpointName.trim());
29253
- if (!selected) {
29254
- throw new DiscoveryCatalogError(
29255
- "endpoint_not_found",
29256
- `Service ${JSON.stringify(service.id)} has no endpoint ${JSON.stringify(endpointName)}. Available endpoints: ${[...targetsByName.keys()].join(", ")}.`,
29257
- service.id
29258
- );
29259
- }
29260
- return { ...selected };
29261
- }
29262
- if (targets.size !== 1) {
29263
- throw new DiscoveryCatalogError(
29264
- "ambiguous_default",
29265
- `Service ${JSON.stringify(service.id)} has ${targets.size} distinct payable endpoints. Choose one with endpoint: ${[...targetsByName.keys()].join(", ")}.`,
29266
- service.id
29267
- );
29268
- }
29269
- return targets.values().next().value;
29270
- }
29271
- function buildTargets(service) {
29272
- if (service.endpoints.length === 0) {
29273
- throw new DiscoveryCatalogError(
29274
- "no_endpoint",
29275
- `Service ${JSON.stringify(service.id)} has no payable endpoint.`,
29276
- service.id
29277
- );
29278
- }
29279
- const namedEndpoints = [...service.endpoints].sort(
29280
- (left, right) => compareNames(left.name.trim(), right.name.trim())
29281
- );
29282
- const names = /* @__PURE__ */ new Set();
29283
- const targets = /* @__PURE__ */ new Map();
29284
- const targetsByName = /* @__PURE__ */ new Map();
29285
- for (const endpoint of namedEndpoints) {
29286
- const name = endpoint.name.trim();
29287
- if (!name) {
29288
- throw new DiscoveryCatalogError(
29289
- "invalid_endpoint_name",
29290
- `Service ${JSON.stringify(service.id)} has a blank endpoint name.`,
29291
- service.id
29292
- );
29293
- }
29294
- if (names.has(name)) {
29295
- throw new DiscoveryCatalogError(
29296
- "duplicate_endpoint_name",
29297
- `Service ${JSON.stringify(service.id)} has duplicate endpoint name ${JSON.stringify(name)}.`,
29298
- service.id
29299
- );
29300
- }
29301
- names.add(name);
29302
- const method = endpoint.method.trim().toUpperCase();
29303
- if (!method) {
29304
- throw new DiscoveryCatalogError(
29305
- "blank_method",
29306
- `Service ${JSON.stringify(service.id)} has a blank endpoint method.`,
29307
- service.id
29308
- );
29309
- }
29310
- const url2 = new URL(endpoint.url);
29311
- if (url2.protocol !== "http:" && url2.protocol !== "https:") {
29312
- throw new DiscoveryCatalogError(
29313
- "malformed_url",
29314
- `Service ${JSON.stringify(service.id)} has a non-HTTP endpoint URL.`,
29315
- service.id
29316
- );
29317
- }
29318
- const transportKey = `${method}\0${endpoint.url}`;
29319
- const normalized = { ...endpoint, name, method };
29320
- targetsByName.set(name, normalized);
29321
- if (!targets.has(transportKey)) targets.set(transportKey, normalized);
29322
- }
29323
- return { targets, targetsByName };
29324
- }
29325
- function compareNames(left, right) {
29326
- return left < right ? -1 : left > right ? 1 : 0;
29327
- }
29328
- function pathIndexAfter(path, key2) {
29329
- const keyIndex = path.indexOf(key2);
29330
- const candidate = path[keyIndex + 1];
29331
- return typeof candidate === "number" ? candidate : void 0;
29332
- }
29333
- function rawServiceId(raw, serviceIndex) {
29334
- if (serviceIndex === void 0 || typeof raw !== "object" || raw === null) {
29335
- return void 0;
29336
- }
29337
- const services = Reflect.get(raw, "services");
29338
- if (!Array.isArray(services)) {
29339
- return void 0;
29340
- }
29341
- const service = services[serviceIndex];
29342
- if (typeof service !== "object" || service === null) {
29343
- return void 0;
29344
- }
29345
- const id2 = Reflect.get(service, "id");
29346
- return typeof id2 === "string" ? id2 : void 0;
29347
- }
29348
-
29349
28990
  // ../../node_modules/.pnpm/viem@2.56.1_typescript@6.0.3_zod@4.5.4/node_modules/viem/_esm/index.js
29350
28991
  init_exports();
29351
28992
 
@@ -39622,6 +39263,7 @@ var ARC_MAINNET_CAIP2 = "eip155:5042";
39622
39263
  var ARC_TESTNET_CAIP2 = "eip155:5042002";
39623
39264
  var SOLANA_MAINNET_CAIP2 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
39624
39265
  var X402_SOLANA_MAINNET_CAIP2 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
39266
+ var SOLANA_DEVNET_CAIP2 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
39625
39267
  var SOLANA_MAINNET_USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
39626
39268
  function canonicalIdentity(usdc, eip712Domain) {
39627
39269
  return Object.freeze({
@@ -39665,375 +39307,184 @@ var BROWSER_ENABLED_X402_NETWORK_CONFIG = Object.freeze({
39665
39307
  [ARC_TESTNET_CAIP2]: browserNetwork(arcTestnetUsdc)
39666
39308
  });
39667
39309
 
39668
- // ../core/src/net-guard.ts
39669
- import { lookup as dnsLookup } from "node:dns/promises";
39670
- import { request as httpRequest } from "node:http";
39671
- import { request as httpsRequest } from "node:https";
39672
- import { isIP } from "node:net";
39673
- import { Readable } from "node:stream";
39674
- var defaultLookup = async (hostname3) => {
39675
- const addresses = await dnsLookup(hostname3, { all: true });
39676
- return addresses.map(({ address: address4 }) => address4);
39310
+ // ../core/src/marketplace-contracts.ts
39311
+ var MARKETPLACE_DISCOVERY_PROTOCOL = "vapi.marketplace.discovery/1";
39312
+ var MARKETPLACE_RANKING_VERSION = "marketplace-ranking-v1";
39313
+ var MARKETPLACE_KINDS = ["api", "service_offer", "open_request"];
39314
+ var MARKETPLACE_EXECUTION_METHODS = [
39315
+ "GET",
39316
+ "HEAD",
39317
+ "POST",
39318
+ "PUT",
39319
+ "PATCH",
39320
+ "DELETE"
39321
+ ];
39322
+ var marketplaceExecutionMethodSchema = external_exports.enum(MARKETPLACE_EXECUTION_METHODS);
39323
+ var marketplaceKindSchema = external_exports.enum(MARKETPLACE_KINDS);
39324
+ var EXECUTION_MODES = ["direct", "gateway"];
39325
+ var executionModeSchema = external_exports.enum(EXECUTION_MODES);
39326
+ var PROVENANCES = ["indexed", "self_listed", "partner"];
39327
+ var provenanceSchema = external_exports.enum(PROVENANCES);
39328
+ var FIRST_PARTY_PROVENANCES = ["self_listed", "partner"];
39329
+ var firstPartyProvenanceSchema = external_exports.enum(FIRST_PARTY_PROVENANCES);
39330
+ var LISTING_GROUPS = ["vapi", "added", "partner", "external"];
39331
+ var listingGroupSchema = external_exports.enum(LISTING_GROUPS);
39332
+ var listingFeeSchema = external_exports.looseObject({
39333
+ bps: external_exports.number().int().min(0),
39334
+ label: external_exports.string()
39335
+ });
39336
+ var LISTING_VERIFICATIONS = ["none", "requested", "verified"];
39337
+ var listingVerificationSchema = external_exports.enum(LISTING_VERIFICATIONS);
39338
+ var listingVerificationFieldSchema = listingVerificationSchema.default("none").catch("none");
39339
+ var listingLivenessSchema = external_exports.looseObject({
39340
+ uptime7d: external_exports.number().min(0).max(1),
39341
+ latencyP50Ms: external_exports.number().nonnegative().nullable(),
39342
+ latencyP95Ms: external_exports.number().nonnegative().nullable(),
39343
+ checks7d: external_exports.number().int().nonnegative()
39344
+ });
39345
+ var listingConformanceSchema = external_exports.looseObject({
39346
+ declaredVersion: external_exports.union([external_exports.literal(1), external_exports.literal(2)]).nullable(),
39347
+ versionConformant: external_exports.boolean(),
39348
+ offerTransport: external_exports.enum(["body", "header", "both"]),
39349
+ issues: external_exports.array(external_exports.string())
39350
+ });
39351
+ var listingIdentitySchema = external_exports.looseObject({
39352
+ erc8004Id: external_exports.string().trim().min(1),
39353
+ reputation: external_exports.looseObject({
39354
+ score: external_exports.number().finite(),
39355
+ count: external_exports.number().int().nonnegative()
39356
+ }).optional().catch(void 0)
39357
+ });
39358
+ var listingDisclosureShape = {
39359
+ group: listingGroupSchema.optional(),
39360
+ fee: listingFeeSchema.optional(),
39361
+ verification: listingVerificationFieldSchema,
39362
+ liveness: listingLivenessSchema.optional().catch(void 0),
39363
+ conformance: listingConformanceSchema.optional().catch(void 0),
39364
+ identity: listingIdentitySchema.optional().catch(void 0)
39677
39365
  };
39678
- async function assertPublicUrl(url2, options) {
39679
- if (url2.username || url2.password) {
39680
- throw guardError(url2);
39681
- }
39682
- if (url2.protocol !== "http:" && url2.protocol !== "https:") {
39683
- throw guardError(url2);
39684
- }
39685
- if (options.allowPrivateNetwork) {
39686
- return;
39687
- }
39688
- const hostname3 = normalizeHostname(url2.hostname);
39689
- const lowercaseHostname = hostname3.toLowerCase();
39690
- if (!lowercaseHostname || lowercaseHostname === "localhost" || lowercaseHostname.endsWith(".localhost") || lowercaseHostname.endsWith(".local") || lowercaseHostname.endsWith(".internal")) {
39691
- throw guardError(url2);
39692
- }
39693
- if (isIP(hostname3)) {
39694
- if (isNonPublicAddress(hostname3)) {
39695
- throw guardError(url2);
39696
- }
39697
- return;
39698
- }
39699
- let addresses;
39700
- try {
39701
- addresses = await withTimeout2(
39702
- (options.lookup ?? defaultLookup)(hostname3),
39703
- options.timeoutMs ?? 5e3
39704
- );
39705
- } catch {
39706
- throw guardError(url2);
39707
- }
39708
- if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
39709
- throw guardError(url2);
39710
- }
39711
- }
39712
- function createPublicFetch(options) {
39713
- const lookupFn = options.lookup ?? defaultLookup;
39714
- return (async (input2, init) => {
39715
- const url2 = new URL(input2 instanceof Request ? input2.url : input2);
39716
- await assertPublicUrl(url2, {
39717
- allowPrivateNetwork: options.allowPrivateNetwork,
39718
- lookup: lookupFn,
39719
- timeoutMs: 5e3
39720
- });
39721
- const normalized = new Request(input2, init);
39722
- const bytes = normalized.body ? Buffer.from(await normalized.arrayBuffer()) : null;
39723
- return await new Promise((resolve2, reject) => {
39724
- const requestOptions2 = {
39725
- method: normalized.method,
39726
- headers: Object.fromEntries(normalized.headers),
39727
- signal: normalized.signal,
39728
- ...options.allowPrivateNetwork ? {} : { lookup: pinnedLookup(lookupFn) }
39729
- };
39730
- const onResponse = (incoming) => {
39731
- try {
39732
- const headers = new Headers();
39733
- for (const [name, value] of Object.entries(incoming.headers)) {
39734
- if (Array.isArray(value)) {
39735
- for (const item of value) headers.append(name, item);
39736
- } else if (value !== void 0) {
39737
- headers.set(name, value);
39738
- }
39739
- }
39740
- const status = incoming.statusCode ?? 500;
39741
- const bodyForbidden = normalized.method === "HEAD" || [204, 205, 304].includes(status);
39742
- if (bodyForbidden) incoming.resume();
39743
- const response = new Response(
39744
- bodyForbidden ? null : Readable.toWeb(incoming),
39745
- { status, statusText: incoming.statusMessage, headers }
39746
- );
39747
- Object.defineProperty(response, "url", { value: url2.toString() });
39748
- resolve2(response);
39749
- } catch (error61) {
39750
- incoming.destroy();
39751
- reject(error61);
39752
- }
39753
- };
39754
- const request = url2.protocol === "https:" ? httpsRequest(url2, requestOptions2, onResponse) : httpRequest(url2, requestOptions2, onResponse);
39755
- request.on("error", reject);
39756
- if (bytes) request.write(bytes);
39757
- request.end();
39758
- });
39759
- });
39760
- }
39761
- function pinnedLookup(lookup) {
39762
- return (hostname3, dnsOptions, callback) => {
39763
- void lookup(normalizeHostname(hostname3)).then((addresses) => {
39764
- if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
39765
- callback(guardError(new URL(`https://${hostname3}`)), "");
39766
- return;
39767
- }
39768
- const address4 = addresses[0];
39769
- const family = isIP(address4);
39770
- callback(
39771
- null,
39772
- dnsOptions.all ? [{ address: address4, family }] : address4,
39773
- dnsOptions.all ? void 0 : family
39774
- );
39775
- }).catch(
39776
- (error61) => callback(error61 instanceof Error ? error61 : new Error("DNS lookup failed."), "")
39777
- );
39778
- };
39779
- }
39780
- async function withTimeout2(operation, timeoutMs) {
39781
- let timeout;
39782
- try {
39783
- return await Promise.race([
39784
- operation,
39785
- new Promise((_resolve, reject) => {
39786
- timeout = setTimeout(() => reject(new Error("DNS lookup timed out.")), timeoutMs);
39787
- })
39788
- ]);
39789
- } finally {
39790
- if (timeout) clearTimeout(timeout);
39791
- }
39792
- }
39793
- function normalizeHostname(hostname3) {
39794
- const unbracketed = hostname3.startsWith("[") && hostname3.endsWith("]") ? hostname3.slice(1, -1) : hostname3;
39795
- return unbracketed.endsWith(".") ? unbracketed.slice(0, -1) : unbracketed;
39796
- }
39797
- function isNonPublicAddress(address4) {
39798
- const normalized = normalizeHostname(address4);
39799
- const version5 = isIP(normalized);
39800
- if (version5 === 4) {
39801
- return isNonPublicIpv4(parseIpv4(normalized));
39802
- }
39803
- if (version5 === 6) {
39804
- return isNonPublicIpv6(parseIpv6(normalized));
39805
- }
39806
- return true;
39807
- }
39808
- function parseIpv4(address4) {
39809
- const octets = address4.split(".").map(Number);
39810
- return [octets[0], octets[1], octets[2], octets[3]];
39811
- }
39812
- function isNonPublicIpv4([first, second, third]) {
39813
- 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;
39814
- }
39815
- function parseIpv6(address4) {
39816
- let normalized = address4.toLowerCase();
39817
- const lastColon = normalized.lastIndexOf(":");
39818
- const dottedTail = normalized.slice(lastColon + 1);
39819
- if (dottedTail.includes(".")) {
39820
- const [first, second, third, fourth] = parseIpv4(dottedTail);
39821
- normalized = `${normalized.slice(0, lastColon + 1)}${(first << 8 | second).toString(16)}:${(third << 8 | fourth).toString(16)}`;
39822
- }
39823
- const halves = normalized.split("::");
39824
- const left = halves[0] ? halves[0].split(":").map(parseHex) : [];
39825
- const right = halves[1] ? halves[1].split(":").map(parseHex) : [];
39826
- const omittedCount = 8 - left.length - right.length;
39827
- return halves.length === 2 ? [...left, ...Array.from({ length: omittedCount }, () => 0), ...right] : left;
39828
- }
39829
- function parseHex(value) {
39830
- return Number.parseInt(value, 16);
39831
- }
39832
- function isNonPublicIpv6(hextets) {
39833
- if (hextets.slice(0, 5).every((hextet) => hextet === 0) && hextets[5] === 65535) {
39834
- const embeddedIpv4 = [
39835
- hextets[6] >> 8,
39836
- hextets[6] & 255,
39837
- hextets[7] >> 8,
39838
- hextets[7] & 255
39839
- ];
39840
- return isNonPublicIpv4(embeddedIpv4);
39841
- }
39842
- if (hextets.slice(0, 6).every((hextet) => hextet === 0)) {
39843
- const compatibleIpv4 = [
39844
- hextets[6] >> 8,
39845
- hextets[6] & 255,
39846
- hextets[7] >> 8,
39847
- hextets[7] & 255
39848
- ];
39849
- if (isNonPublicIpv4(compatibleIpv4)) return true;
39850
- }
39851
- const isUnspecified = hextets.every((hextet) => hextet === 0);
39852
- const isLoopback = hextets.slice(0, 7).every((hextet) => hextet === 0) && hextets[7] === 1;
39853
- const first = hextets[0];
39854
- const isUniqueLocal = first >= 64512 && first <= 65023;
39855
- const isLinkLocal = first >= 65152 && first <= 65215;
39856
- const isSiteLocal = first >= 65216 && first <= 65279;
39857
- const isMulticast = first >= 65280;
39858
- const isDocumentation = first === 8193 && hextets[1] === 3512;
39859
- return isUnspecified || isLoopback || isUniqueLocal || isLinkLocal || isSiteLocal || isMulticast || isDocumentation;
39860
- }
39861
- function guardError(url2) {
39862
- return new Error(
39863
- `URL hostname ${JSON.stringify(url2.hostname)} is not allowed; private or internal destinations require allowPrivateNetwork true in the vAPI config.`
39864
- );
39865
- }
39866
-
39867
- // ../core/src/networks.ts
39868
- var USDC_DECIMALS = 6;
39869
- var DEFAULT_ARC_GAS_HEADROOM_ATOMIC = 50000n;
39870
- var NETWORKS = {
39871
- [BASE_MAINNET_CAIP2]: {
39872
- family: "evm",
39873
- chainId: 8453,
39874
- name: "Base mainnet",
39875
- usdc: CANONICAL_X402_USDC_NETWORKS[BASE_MAINNET_CAIP2].usdc,
39876
- gasToken: "ETH",
39877
- rpcEnv: "BASE_RPC_URL",
39878
- publicRpcUrl: "https://mainnet.base.org",
39879
- explorerUrl: "https://basescan.org"
39880
- },
39881
- [ARC_MAINNET_CAIP2]: {
39882
- family: "evm",
39883
- chainId: 5042,
39884
- name: "Arc mainnet",
39885
- usdc: CANONICAL_X402_USDC_NETWORKS[ARC_MAINNET_CAIP2].usdc,
39886
- gasToken: "USDC",
39887
- rpcEnv: "ARC_RPC_URL",
39888
- publicRpcUrl: "https://rpc.mainnet.arc.io",
39889
- explorerUrl: "https://explorer.arc.io"
39890
- },
39891
- [ARC_TESTNET_CAIP2]: {
39892
- family: "evm",
39893
- chainId: 5042002,
39894
- name: "Arc testnet",
39895
- usdc: CANONICAL_X402_USDC_NETWORKS[ARC_TESTNET_CAIP2].usdc,
39896
- gasToken: "USDC",
39897
- rpcEnv: "ARC_TESTNET_RPC_URL"
39898
- },
39899
- [SOLANA_MAINNET_CAIP2]: {
39900
- family: "svm",
39901
- name: "Solana mainnet",
39902
- usdc: SOLANA_MAINNET_USDC,
39903
- gasToken: "SOL",
39904
- rpcEnv: "SOLANA_RPC_URL",
39905
- publicRpcUrl: "https://api.mainnet-beta.solana.com"
39906
- },
39907
- [X402_SOLANA_MAINNET_CAIP2]: {
39908
- family: "svm",
39909
- name: "Solana mainnet",
39910
- usdc: SOLANA_MAINNET_USDC,
39911
- gasToken: "SOL",
39912
- rpcEnv: "SOLANA_RPC_URL",
39913
- publicRpcUrl: "https://api.mainnet-beta.solana.com"
39914
- }
39366
+ var marketplaceBadgeCodeSchema = external_exports.enum([
39367
+ "live_x402",
39368
+ "partner",
39369
+ "payout_wallet_confirmed",
39370
+ "vapi_verified",
39371
+ "external_catalog",
39372
+ "approved_vendor"
39373
+ ]);
39374
+ var marketplaceBadgeSchema = external_exports.looseObject({
39375
+ code: marketplaceBadgeCodeSchema,
39376
+ label: external_exports.string().trim().min(1).max(80)
39377
+ });
39378
+ var marketplacePublicFactSchema = external_exports.looseObject({
39379
+ label: external_exports.string().trim().min(1).max(80),
39380
+ value: external_exports.string().trim().min(1).max(160)
39381
+ });
39382
+ var marketplaceHrefSchema = external_exports.union([
39383
+ external_exports.string().trim().min(1).max(2048).regex(/^\/(?!\/)/),
39384
+ external_exports.url().max(2048).regex(/^https:\/\//)
39385
+ ]);
39386
+ var marketplaceCardSchema = external_exports.looseObject({
39387
+ title: external_exports.string().trim().min(1).max(160),
39388
+ summary: external_exports.string().trim().min(1).max(1e3),
39389
+ byline: external_exports.string().trim().min(1).max(160).optional(),
39390
+ bylineHref: marketplaceHrefSchema.optional(),
39391
+ badges: external_exports.array(marketplaceBadgeSchema).max(8),
39392
+ facts: external_exports.array(marketplacePublicFactSchema).max(12)
39393
+ });
39394
+ var marketplaceHitBase = {
39395
+ ref: external_exports.string().trim().min(1).max(512),
39396
+ card: marketplaceCardSchema,
39397
+ ...listingDisclosureShape
39915
39398
  };
39916
- function parseEip155ChainId(network) {
39917
- const match = /^eip155:(\d+)$/.exec(network);
39918
- if (!match) {
39919
- throw new Error(`Unsupported network ${network}; expected eip155:<chainId>.`);
39920
- }
39921
- const chainId = Number(match[1]);
39922
- if (!Number.isSafeInteger(chainId) || chainId <= 0) {
39923
- throw new Error(`Invalid EVM chain ID in network ${network}.`);
39924
- }
39925
- return chainId;
39926
- }
39927
- function isSolanaNetwork(network) {
39928
- return network === SOLANA_MAINNET_CAIP2 || network === X402_SOLANA_MAINNET_CAIP2;
39929
- }
39930
- function usesUsdcGas(network) {
39931
- try {
39932
- return getNetworkDefinition(network).gasToken === "USDC";
39933
- } catch {
39934
- return false;
39935
- }
39936
- }
39937
- function explorerTransactionUrl(network, hash5) {
39938
- try {
39939
- const explorerUrl = getNetworkDefinition(network).explorerUrl;
39940
- return explorerUrl ? `${explorerUrl}/tx/${hash5}` : void 0;
39941
- } catch {
39942
- return void 0;
39943
- }
39944
- }
39945
- function explorerAddressUrl(network, address4) {
39946
- try {
39947
- const explorerUrl = getNetworkDefinition(network).explorerUrl;
39948
- return explorerUrl ? `${explorerUrl}/address/${address4}` : void 0;
39949
- } catch {
39950
- return void 0;
39951
- }
39952
- }
39953
- function areSamePaymentNetwork(left, right) {
39954
- return left === right || isSolanaNetwork(left) && isSolanaNetwork(right);
39955
- }
39956
- function isSupportedPaymentNetwork(network) {
39957
- if (isSolanaNetwork(network)) return true;
39958
- try {
39959
- parseEip155ChainId(network);
39960
- return true;
39961
- } catch {
39962
- return false;
39963
- }
39964
- }
39965
- function configuredNetworkFor(networks, network) {
39966
- const configured = networks[network];
39967
- if (configured) return configured;
39968
- if (network === X402_SOLANA_MAINNET_CAIP2) return networks[SOLANA_MAINNET_CAIP2];
39969
- if (network === SOLANA_MAINNET_CAIP2) return networks[X402_SOLANA_MAINNET_CAIP2];
39970
- return void 0;
39971
- }
39972
- function getNetworkDefinition(network) {
39973
- const known = NETWORKS[network];
39974
- if (known) {
39975
- return known;
39976
- }
39977
- const chainId = parseEip155ChainId(network);
39978
- return {
39979
- family: "evm",
39980
- chainId,
39981
- name: network,
39982
- usdc: getAddress("0x0000000000000000000000000000000000000000"),
39983
- gasToken: "ETH",
39984
- rpcEnv: ""
39985
- };
39986
- }
39987
- function requireRpcUrl(network, configured) {
39988
- const definition = getNetworkDefinition(network);
39989
- const envUrl = definition.rpcEnv ? process.env[definition.rpcEnv]?.trim() : void 0;
39990
- const rpcUrl = envUrl || configured.rpcUrl.trim();
39991
- if (rpcUrl) {
39992
- return rpcUrl;
39993
- }
39994
- if (network === ARC_TESTNET_CAIP2) {
39995
- throw new Error(
39996
- "Arc testnet RPC is required. Set ARC_TESTNET_RPC_URL or add rpcUrl for eip155:5042002 in config.json."
39997
- );
39998
- }
39999
- throw new Error(`RPC URL is required for ${network}.`);
40000
- }
40001
- function createChain(network, rpcUrl) {
40002
- const definition = getNetworkDefinition(network);
40003
- if (definition.family !== "evm" || definition.chainId === void 0) {
40004
- throw new Error(`Network ${network} is not an EVM chain.`);
39399
+ var invokeApiActionSchema = external_exports.looseObject({
39400
+ type: external_exports.literal("invoke_api"),
39401
+ href: marketplaceHrefSchema
39402
+ });
39403
+ var firstPartyApiMarketplaceHitSchema = external_exports.looseObject({
39404
+ ...marketplaceHitBase,
39405
+ kind: external_exports.literal("api"),
39406
+ provenance: firstPartyProvenanceSchema,
39407
+ execution: external_exports.looseObject({
39408
+ mode: executionModeSchema
39409
+ }),
39410
+ action: invokeApiActionSchema
39411
+ });
39412
+ var mirroredApiMarketplaceHitSchema = external_exports.looseObject({
39413
+ ...marketplaceHitBase,
39414
+ kind: external_exports.literal("api"),
39415
+ provenance: external_exports.literal("indexed"),
39416
+ execution: external_exports.looseObject({
39417
+ mode: external_exports.literal("direct"),
39418
+ url: external_exports.url().max(2048).regex(/^https:\/\/(?![^/?#]*@)/),
39419
+ method: marketplaceExecutionMethodSchema.nullable(),
39420
+ network: external_exports.string().trim().max(160).transform((network) => {
39421
+ if (network === "solana") return X402_SOLANA_MAINNET_CAIP2;
39422
+ if (network === "solana-devnet") return SOLANA_DEVNET_CAIP2;
39423
+ return network;
39424
+ }).pipe(
39425
+ external_exports.union([
39426
+ external_exports.string().regex(/^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$/),
39427
+ // Persisted mainnet configs also use the full genesis hash.
39428
+ external_exports.literal(SOLANA_MAINNET_CAIP2)
39429
+ ])
39430
+ )
39431
+ }),
39432
+ action: invokeApiActionSchema
39433
+ });
39434
+ var apiMarketplaceHitSchema = external_exports.discriminatedUnion("provenance", [
39435
+ firstPartyApiMarketplaceHitSchema,
39436
+ mirroredApiMarketplaceHitSchema
39437
+ ]);
39438
+ var serviceOfferMarketplaceHitSchema = external_exports.looseObject({
39439
+ ...marketplaceHitBase,
39440
+ kind: external_exports.literal("service_offer"),
39441
+ action: external_exports.looseObject({
39442
+ type: external_exports.literal("start_engagement"),
39443
+ href: marketplaceHrefSchema
39444
+ })
39445
+ });
39446
+ var openRequestMarketplaceHitSchema = external_exports.looseObject({
39447
+ ...marketplaceHitBase,
39448
+ kind: external_exports.literal("open_request"),
39449
+ action: external_exports.looseObject({
39450
+ type: external_exports.literal("propose_to_request"),
39451
+ href: marketplaceHrefSchema
39452
+ })
39453
+ });
39454
+ var marketplaceHitSchema = external_exports.union([
39455
+ apiMarketplaceHitSchema,
39456
+ serviceOfferMarketplaceHitSchema,
39457
+ openRequestMarketplaceHitSchema
39458
+ ]);
39459
+ var marketplaceDiscoveryInputSchema = external_exports.strictObject({
39460
+ q: external_exports.string().trim().max(200).optional(),
39461
+ kinds: external_exports.array(marketplaceKindSchema).min(1).max(MARKETPLACE_KINDS.length).optional(),
39462
+ network: external_exports.string().trim().min(1).max(160).optional(),
39463
+ cursor: external_exports.string().trim().min(1).max(4096).optional(),
39464
+ limit: external_exports.number().int().min(1).max(50).optional(),
39465
+ includeUnverified: external_exports.boolean().optional()
39466
+ }).superRefine((input2, context) => {
39467
+ if (input2.kinds && new Set(input2.kinds).size !== input2.kinds.length) {
39468
+ context.addIssue({
39469
+ code: "custom",
39470
+ path: ["kinds"],
39471
+ message: "Marketplace kinds must be unique"
39472
+ });
40005
39473
  }
40006
- return defineChain({
40007
- id: definition.chainId,
40008
- name: definition.name,
40009
- nativeCurrency: definition.gasToken === "USDC" ? { name: "USDC", symbol: "USDC", decimals: USDC_DECIMALS } : { name: "Ether", symbol: "ETH", decimals: 18 },
40010
- rpcUrls: {
40011
- default: { http: [rpcUrl] }
40012
- },
40013
- ...definition.explorerUrl ? {
40014
- blockExplorers: {
40015
- default: { name: `${definition.name} explorer`, url: definition.explorerUrl }
40016
- }
40017
- } : {}
40018
- });
40019
- }
40020
- function createNetworkPublicClient(network, configured, options = {}) {
40021
- const rpcUrl = requireRpcUrl(network, configured);
40022
- return createPublicClient({
40023
- chain: createChain(network, rpcUrl),
40024
- transport: createNetworkHttpTransport(rpcUrl, options)
40025
- });
40026
- }
40027
- function createNetworkHttpTransport(rpcUrl, options = {}) {
40028
- const fetchFn = options.fetch ?? createPublicFetch({
40029
- allowPrivateNetwork: options.allowPrivateNetwork ?? false,
40030
- ...options.lookup ? { lookup: options.lookup } : {}
40031
- });
40032
- return http(rpcUrl, { fetchFn, fetchOptions: { redirect: "manual" } });
40033
- }
40034
- function formatUsdc(amountAtomic2) {
40035
- return formatUnits(amountAtomic2, USDC_DECIMALS);
39474
+ });
39475
+ function isMirroredHit(hit) {
39476
+ return hit.kind === "api" && hit.provenance === "indexed";
40036
39477
  }
39478
+ var marketplaceDiscoveryEnvelopeSchema = external_exports.looseObject({
39479
+ protocol: external_exports.literal(MARKETPLACE_DISCOVERY_PROTOCOL),
39480
+ items: external_exports.array(external_exports.unknown()),
39481
+ nextCursor: external_exports.string().min(1).max(4096).nullable(),
39482
+ unavailableKinds: external_exports.array(marketplaceKindSchema).max(MARKETPLACE_KINDS.length),
39483
+ rankingVersion: external_exports.literal(MARKETPLACE_RANKING_VERSION)
39484
+ });
39485
+ var marketplaceDiscoveryPageSchema = marketplaceDiscoveryEnvelopeSchema.extend({
39486
+ items: external_exports.array(marketplaceHitSchema)
39487
+ });
40037
39488
 
40038
39489
  // ../../node_modules/.pnpm/@solana+errors@5.5.1_typescript@6.0.3/node_modules/@solana/errors/dist/index.node.mjs
40039
39490
  var SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED = 1;
@@ -45015,16 +44466,16 @@ var DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;
45015
44466
  var DEFAULT_COMPUTE_UNIT_LIMIT = 2e4;
45016
44467
  var MAX_MEMO_BYTES = 256;
45017
44468
  var SOLANA_MAINNET_CAIP22 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
45018
- var SOLANA_DEVNET_CAIP2 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
44469
+ var SOLANA_DEVNET_CAIP22 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
45019
44470
  var SOLANA_TESTNET_CAIP2 = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";
45020
44471
  var V1_TO_V2_NETWORK_MAP = {
45021
44472
  solana: SOLANA_MAINNET_CAIP22,
45022
- "solana-devnet": SOLANA_DEVNET_CAIP2,
44473
+ "solana-devnet": SOLANA_DEVNET_CAIP22,
45023
44474
  "solana-testnet": SOLANA_TESTNET_CAIP2
45024
44475
  };
45025
44476
  function normalizeNetwork(network) {
45026
44477
  if (network.includes(":")) {
45027
- const supported = [SOLANA_MAINNET_CAIP22, SOLANA_DEVNET_CAIP2, SOLANA_TESTNET_CAIP2];
44478
+ const supported = [SOLANA_MAINNET_CAIP22, SOLANA_DEVNET_CAIP22, SOLANA_TESTNET_CAIP2];
45028
44479
  if (!supported.includes(network)) {
45029
44480
  throw new Error(`Unsupported SVM network: ${network}`);
45030
44481
  }
@@ -45072,7 +44523,7 @@ var DEFAULT_ASSETS = {
45072
44523
  tokenProgram: TOKEN_2022_PROGRAM_ADDRESS2
45073
44524
  }
45074
44525
  ],
45075
- [SOLANA_DEVNET_CAIP2]: [
44526
+ [SOLANA_DEVNET_CAIP22]: [
45076
44527
  {
45077
44528
  asset: USDC_DEVNET_ADDRESS,
45078
44529
  decimals: 6,
@@ -45127,7 +44578,7 @@ var findDefaultAsset = (asset, network) => {
45127
44578
  function createRpcClient(network, customRpcUrl) {
45128
44579
  const caip2Network = normalizeNetwork(network);
45129
44580
  switch (caip2Network) {
45130
- case SOLANA_DEVNET_CAIP2: {
44581
+ case SOLANA_DEVNET_CAIP22: {
45131
44582
  const url2 = customRpcUrl || DEVNET_RPC_URL;
45132
44583
  return createSolanaRpc(devnet(url2));
45133
44584
  }
@@ -45325,6 +44776,376 @@ var ExactSvmScheme = class {
45325
44776
  var addressEncoder = getAddressEncoder();
45326
44777
  var compiledMessageDecoder = getCompiledTransactionMessageDecoder();
45327
44778
 
44779
+ // ../core/src/net-guard.ts
44780
+ import { lookup as dnsLookup } from "node:dns/promises";
44781
+ import { request as httpRequest } from "node:http";
44782
+ import { request as httpsRequest } from "node:https";
44783
+ import { isIP } from "node:net";
44784
+ import { Readable } from "node:stream";
44785
+ var defaultLookup = async (hostname3) => {
44786
+ const addresses = await dnsLookup(hostname3, { all: true });
44787
+ return addresses.map(({ address: address4 }) => address4);
44788
+ };
44789
+ async function assertPublicUrl(url2, options) {
44790
+ if (url2.username || url2.password) {
44791
+ throw guardError(url2);
44792
+ }
44793
+ if (url2.protocol !== "http:" && url2.protocol !== "https:") {
44794
+ throw guardError(url2);
44795
+ }
44796
+ if (options.allowPrivateNetwork) {
44797
+ return;
44798
+ }
44799
+ const hostname3 = normalizeHostname(url2.hostname);
44800
+ const lowercaseHostname = hostname3.toLowerCase();
44801
+ if (!lowercaseHostname || lowercaseHostname === "localhost" || lowercaseHostname.endsWith(".localhost") || lowercaseHostname.endsWith(".local") || lowercaseHostname.endsWith(".internal")) {
44802
+ throw guardError(url2);
44803
+ }
44804
+ if (isIP(hostname3)) {
44805
+ if (isNonPublicAddress(hostname3)) {
44806
+ throw guardError(url2);
44807
+ }
44808
+ return;
44809
+ }
44810
+ let addresses;
44811
+ try {
44812
+ addresses = await withTimeout2(
44813
+ (options.lookup ?? defaultLookup)(hostname3),
44814
+ options.timeoutMs ?? 5e3
44815
+ );
44816
+ } catch {
44817
+ throw guardError(url2);
44818
+ }
44819
+ if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
44820
+ throw guardError(url2);
44821
+ }
44822
+ }
44823
+ function createPublicFetch(options) {
44824
+ const lookupFn = options.lookup ?? defaultLookup;
44825
+ return (async (input2, init) => {
44826
+ const url2 = new URL(input2 instanceof Request ? input2.url : input2);
44827
+ await assertPublicUrl(url2, {
44828
+ allowPrivateNetwork: options.allowPrivateNetwork,
44829
+ lookup: lookupFn,
44830
+ timeoutMs: 5e3
44831
+ });
44832
+ const normalized = new Request(input2, init);
44833
+ const bytes = normalized.body ? Buffer.from(await normalized.arrayBuffer()) : null;
44834
+ return await new Promise((resolve2, reject) => {
44835
+ const requestOptions2 = {
44836
+ method: normalized.method,
44837
+ headers: Object.fromEntries(normalized.headers),
44838
+ signal: normalized.signal,
44839
+ ...options.allowPrivateNetwork ? {} : { lookup: pinnedLookup(lookupFn) }
44840
+ };
44841
+ const onResponse = (incoming) => {
44842
+ try {
44843
+ const headers = new Headers();
44844
+ for (const [name, value] of Object.entries(incoming.headers)) {
44845
+ if (Array.isArray(value)) {
44846
+ for (const item of value) headers.append(name, item);
44847
+ } else if (value !== void 0) {
44848
+ headers.set(name, value);
44849
+ }
44850
+ }
44851
+ const status = incoming.statusCode ?? 500;
44852
+ const bodyForbidden = normalized.method === "HEAD" || [204, 205, 304].includes(status);
44853
+ if (bodyForbidden) incoming.resume();
44854
+ const response = new Response(
44855
+ bodyForbidden ? null : Readable.toWeb(incoming),
44856
+ { status, statusText: incoming.statusMessage, headers }
44857
+ );
44858
+ Object.defineProperty(response, "url", { value: url2.toString() });
44859
+ resolve2(response);
44860
+ } catch (error61) {
44861
+ incoming.destroy();
44862
+ reject(error61);
44863
+ }
44864
+ };
44865
+ const request = url2.protocol === "https:" ? httpsRequest(url2, requestOptions2, onResponse) : httpRequest(url2, requestOptions2, onResponse);
44866
+ request.on("error", reject);
44867
+ if (bytes) request.write(bytes);
44868
+ request.end();
44869
+ });
44870
+ });
44871
+ }
44872
+ function pinnedLookup(lookup) {
44873
+ return (hostname3, dnsOptions, callback) => {
44874
+ void lookup(normalizeHostname(hostname3)).then((addresses) => {
44875
+ if (addresses.length === 0 || addresses.some(isNonPublicAddress)) {
44876
+ callback(guardError(new URL(`https://${hostname3}`)), "");
44877
+ return;
44878
+ }
44879
+ const address4 = addresses[0];
44880
+ const family = isIP(address4);
44881
+ callback(
44882
+ null,
44883
+ dnsOptions.all ? [{ address: address4, family }] : address4,
44884
+ dnsOptions.all ? void 0 : family
44885
+ );
44886
+ }).catch(
44887
+ (error61) => callback(error61 instanceof Error ? error61 : new Error("DNS lookup failed."), "")
44888
+ );
44889
+ };
44890
+ }
44891
+ async function withTimeout2(operation, timeoutMs) {
44892
+ let timeout;
44893
+ try {
44894
+ return await Promise.race([
44895
+ operation,
44896
+ new Promise((_resolve, reject) => {
44897
+ timeout = setTimeout(() => reject(new Error("DNS lookup timed out.")), timeoutMs);
44898
+ })
44899
+ ]);
44900
+ } finally {
44901
+ if (timeout) clearTimeout(timeout);
44902
+ }
44903
+ }
44904
+ function normalizeHostname(hostname3) {
44905
+ const unbracketed = hostname3.startsWith("[") && hostname3.endsWith("]") ? hostname3.slice(1, -1) : hostname3;
44906
+ return unbracketed.endsWith(".") ? unbracketed.slice(0, -1) : unbracketed;
44907
+ }
44908
+ function isNonPublicAddress(address4) {
44909
+ const normalized = normalizeHostname(address4);
44910
+ const version5 = isIP(normalized);
44911
+ if (version5 === 4) {
44912
+ return isNonPublicIpv4(parseIpv4(normalized));
44913
+ }
44914
+ if (version5 === 6) {
44915
+ return isNonPublicIpv6(parseIpv6(normalized));
44916
+ }
44917
+ return true;
44918
+ }
44919
+ function parseIpv4(address4) {
44920
+ const octets = address4.split(".").map(Number);
44921
+ return [octets[0], octets[1], octets[2], octets[3]];
44922
+ }
44923
+ function isNonPublicIpv4([first, second, third]) {
44924
+ 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;
44925
+ }
44926
+ function parseIpv6(address4) {
44927
+ let normalized = address4.toLowerCase();
44928
+ const lastColon = normalized.lastIndexOf(":");
44929
+ const dottedTail = normalized.slice(lastColon + 1);
44930
+ if (dottedTail.includes(".")) {
44931
+ const [first, second, third, fourth] = parseIpv4(dottedTail);
44932
+ normalized = `${normalized.slice(0, lastColon + 1)}${(first << 8 | second).toString(16)}:${(third << 8 | fourth).toString(16)}`;
44933
+ }
44934
+ const halves = normalized.split("::");
44935
+ const left = halves[0] ? halves[0].split(":").map(parseHex) : [];
44936
+ const right = halves[1] ? halves[1].split(":").map(parseHex) : [];
44937
+ const omittedCount = 8 - left.length - right.length;
44938
+ return halves.length === 2 ? [...left, ...Array.from({ length: omittedCount }, () => 0), ...right] : left;
44939
+ }
44940
+ function parseHex(value) {
44941
+ return Number.parseInt(value, 16);
44942
+ }
44943
+ function isNonPublicIpv6(hextets) {
44944
+ if (hextets.slice(0, 5).every((hextet) => hextet === 0) && hextets[5] === 65535) {
44945
+ const embeddedIpv4 = [
44946
+ hextets[6] >> 8,
44947
+ hextets[6] & 255,
44948
+ hextets[7] >> 8,
44949
+ hextets[7] & 255
44950
+ ];
44951
+ return isNonPublicIpv4(embeddedIpv4);
44952
+ }
44953
+ if (hextets.slice(0, 6).every((hextet) => hextet === 0)) {
44954
+ const compatibleIpv4 = [
44955
+ hextets[6] >> 8,
44956
+ hextets[6] & 255,
44957
+ hextets[7] >> 8,
44958
+ hextets[7] & 255
44959
+ ];
44960
+ if (isNonPublicIpv4(compatibleIpv4)) return true;
44961
+ }
44962
+ const isUnspecified = hextets.every((hextet) => hextet === 0);
44963
+ const isLoopback = hextets.slice(0, 7).every((hextet) => hextet === 0) && hextets[7] === 1;
44964
+ const first = hextets[0];
44965
+ const isUniqueLocal = first >= 64512 && first <= 65023;
44966
+ const isLinkLocal = first >= 65152 && first <= 65215;
44967
+ const isSiteLocal = first >= 65216 && first <= 65279;
44968
+ const isMulticast = first >= 65280;
44969
+ const isDocumentation = first === 8193 && hextets[1] === 3512;
44970
+ return isUnspecified || isLoopback || isUniqueLocal || isLinkLocal || isSiteLocal || isMulticast || isDocumentation;
44971
+ }
44972
+ function guardError(url2) {
44973
+ return new Error(
44974
+ `URL hostname ${JSON.stringify(url2.hostname)} is not allowed; private or internal destinations require allowPrivateNetwork true in the vAPI config.`
44975
+ );
44976
+ }
44977
+
44978
+ // ../core/src/networks.ts
44979
+ var USDC_DECIMALS = 6;
44980
+ var DEFAULT_ARC_GAS_HEADROOM_ATOMIC = 50000n;
44981
+ var NETWORKS2 = {
44982
+ [BASE_MAINNET_CAIP2]: {
44983
+ family: "evm",
44984
+ chainId: 8453,
44985
+ name: "Base mainnet",
44986
+ usdc: CANONICAL_X402_USDC_NETWORKS[BASE_MAINNET_CAIP2].usdc,
44987
+ gasToken: "ETH",
44988
+ rpcEnv: "BASE_RPC_URL",
44989
+ publicRpcUrl: "https://mainnet.base.org",
44990
+ explorerUrl: "https://basescan.org"
44991
+ },
44992
+ [ARC_MAINNET_CAIP2]: {
44993
+ family: "evm",
44994
+ chainId: 5042,
44995
+ name: "Arc mainnet",
44996
+ usdc: CANONICAL_X402_USDC_NETWORKS[ARC_MAINNET_CAIP2].usdc,
44997
+ gasToken: "USDC",
44998
+ rpcEnv: "ARC_RPC_URL",
44999
+ publicRpcUrl: "https://rpc.mainnet.arc.io",
45000
+ explorerUrl: "https://explorer.arc.io"
45001
+ },
45002
+ [ARC_TESTNET_CAIP2]: {
45003
+ family: "evm",
45004
+ chainId: 5042002,
45005
+ name: "Arc testnet",
45006
+ usdc: CANONICAL_X402_USDC_NETWORKS[ARC_TESTNET_CAIP2].usdc,
45007
+ gasToken: "USDC",
45008
+ rpcEnv: "ARC_TESTNET_RPC_URL"
45009
+ },
45010
+ [SOLANA_MAINNET_CAIP2]: {
45011
+ family: "svm",
45012
+ name: "Solana mainnet",
45013
+ usdc: SOLANA_MAINNET_USDC,
45014
+ gasToken: "SOL",
45015
+ rpcEnv: "SOLANA_RPC_URL",
45016
+ publicRpcUrl: "https://api.mainnet-beta.solana.com"
45017
+ },
45018
+ [X402_SOLANA_MAINNET_CAIP2]: {
45019
+ family: "svm",
45020
+ name: "Solana mainnet",
45021
+ usdc: SOLANA_MAINNET_USDC,
45022
+ gasToken: "SOL",
45023
+ rpcEnv: "SOLANA_RPC_URL",
45024
+ publicRpcUrl: "https://api.mainnet-beta.solana.com"
45025
+ }
45026
+ };
45027
+ function parseEip155ChainId(network) {
45028
+ const match = /^eip155:(\d+)$/.exec(network);
45029
+ if (!match) {
45030
+ throw new Error(`Unsupported network ${network}; expected eip155:<chainId>.`);
45031
+ }
45032
+ const chainId = Number(match[1]);
45033
+ if (!Number.isSafeInteger(chainId) || chainId <= 0) {
45034
+ throw new Error(`Invalid EVM chain ID in network ${network}.`);
45035
+ }
45036
+ return chainId;
45037
+ }
45038
+ function isSolanaNetwork(network) {
45039
+ return network === SOLANA_MAINNET_CAIP2 || network === X402_SOLANA_MAINNET_CAIP2;
45040
+ }
45041
+ function usesUsdcGas(network) {
45042
+ try {
45043
+ return getNetworkDefinition(network).gasToken === "USDC";
45044
+ } catch {
45045
+ return false;
45046
+ }
45047
+ }
45048
+ function explorerTransactionUrl(network, hash5) {
45049
+ try {
45050
+ const explorerUrl = getNetworkDefinition(network).explorerUrl;
45051
+ return explorerUrl ? `${explorerUrl}/tx/${hash5}` : void 0;
45052
+ } catch {
45053
+ return void 0;
45054
+ }
45055
+ }
45056
+ function explorerAddressUrl(network, address4) {
45057
+ try {
45058
+ const explorerUrl = getNetworkDefinition(network).explorerUrl;
45059
+ return explorerUrl ? `${explorerUrl}/address/${address4}` : void 0;
45060
+ } catch {
45061
+ return void 0;
45062
+ }
45063
+ }
45064
+ function areSamePaymentNetwork(left, right) {
45065
+ return left === right || isSolanaNetwork(left) && isSolanaNetwork(right);
45066
+ }
45067
+ function isSupportedPaymentNetwork(network) {
45068
+ if (isSolanaNetwork(network)) return true;
45069
+ try {
45070
+ parseEip155ChainId(network);
45071
+ return true;
45072
+ } catch {
45073
+ return false;
45074
+ }
45075
+ }
45076
+ function configuredNetworkFor(networks, network) {
45077
+ const configured = networks[network];
45078
+ if (configured) return configured;
45079
+ if (network === X402_SOLANA_MAINNET_CAIP2) return networks[SOLANA_MAINNET_CAIP2];
45080
+ if (network === SOLANA_MAINNET_CAIP2) return networks[X402_SOLANA_MAINNET_CAIP2];
45081
+ return void 0;
45082
+ }
45083
+ function getNetworkDefinition(network) {
45084
+ const known = NETWORKS2[network];
45085
+ if (known) {
45086
+ return known;
45087
+ }
45088
+ const chainId = parseEip155ChainId(network);
45089
+ return {
45090
+ family: "evm",
45091
+ chainId,
45092
+ name: network,
45093
+ usdc: getAddress("0x0000000000000000000000000000000000000000"),
45094
+ gasToken: "ETH",
45095
+ rpcEnv: ""
45096
+ };
45097
+ }
45098
+ function requireRpcUrl(network, configured) {
45099
+ const definition = getNetworkDefinition(network);
45100
+ const envUrl = definition.rpcEnv ? process.env[definition.rpcEnv]?.trim() : void 0;
45101
+ const rpcUrl = envUrl || configured.rpcUrl.trim();
45102
+ if (rpcUrl) {
45103
+ return rpcUrl;
45104
+ }
45105
+ if (network === ARC_TESTNET_CAIP2) {
45106
+ throw new Error(
45107
+ "Arc testnet RPC is required. Set ARC_TESTNET_RPC_URL or add rpcUrl for eip155:5042002 in config.json."
45108
+ );
45109
+ }
45110
+ throw new Error(`RPC URL is required for ${network}.`);
45111
+ }
45112
+ function createChain(network, rpcUrl) {
45113
+ const definition = getNetworkDefinition(network);
45114
+ if (definition.family !== "evm" || definition.chainId === void 0) {
45115
+ throw new Error(`Network ${network} is not an EVM chain.`);
45116
+ }
45117
+ return defineChain({
45118
+ id: definition.chainId,
45119
+ name: definition.name,
45120
+ nativeCurrency: definition.gasToken === "USDC" ? { name: "USDC", symbol: "USDC", decimals: USDC_DECIMALS } : { name: "Ether", symbol: "ETH", decimals: 18 },
45121
+ rpcUrls: {
45122
+ default: { http: [rpcUrl] }
45123
+ },
45124
+ ...definition.explorerUrl ? {
45125
+ blockExplorers: {
45126
+ default: { name: `${definition.name} explorer`, url: definition.explorerUrl }
45127
+ }
45128
+ } : {}
45129
+ });
45130
+ }
45131
+ function createNetworkPublicClient(network, configured, options = {}) {
45132
+ const rpcUrl = requireRpcUrl(network, configured);
45133
+ return createPublicClient({
45134
+ chain: createChain(network, rpcUrl),
45135
+ transport: createNetworkHttpTransport(rpcUrl, options)
45136
+ });
45137
+ }
45138
+ function createNetworkHttpTransport(rpcUrl, options = {}) {
45139
+ const fetchFn = options.fetch ?? createPublicFetch({
45140
+ allowPrivateNetwork: options.allowPrivateNetwork ?? false,
45141
+ ...options.lookup ? { lookup: options.lookup } : {}
45142
+ });
45143
+ return http(rpcUrl, { fetchFn, fetchOptions: { redirect: "manual" } });
45144
+ }
45145
+ function formatUsdc(amountAtomic2) {
45146
+ return formatUnits(amountAtomic2, USDC_DECIMALS);
45147
+ }
45148
+
45328
45149
  // ../core/src/x402.ts
45329
45150
  var MAX_CHALLENGE_BYTES = 1048576;
45330
45151
  var MAX_UINT256 = (1n << 256n) - 1n;
@@ -46184,6 +46005,224 @@ function isRecord2(value) {
46184
46005
  return typeof value === "object" && value !== null && !Array.isArray(value);
46185
46006
  }
46186
46007
 
46008
+ // ../core/src/call-contracts-wire.ts
46009
+ var CALLABLE_CATEGORIES = ["ai", "data", "crypto", "compute", "search"];
46010
+ var callableCategorySchema = external_exports.enum(CALLABLE_CATEGORIES);
46011
+ var DISCOVERY_CATEGORIES = [...CALLABLE_CATEGORIES, "other"];
46012
+ var discoveryCategorySchema = external_exports.enum(DISCOVERY_CATEGORIES);
46013
+ var CALLABLE_CATEGORY_SET = new Set(CALLABLE_CATEGORIES);
46014
+ var serviceTierSchema = external_exports.enum(["listed", "verified", "partner"]);
46015
+ var discoveryEndpointSchema = external_exports.looseObject({
46016
+ name: external_exports.string(),
46017
+ method: external_exports.string(),
46018
+ url: external_exports.url(),
46019
+ price: external_exports.string(),
46020
+ description: external_exports.string(),
46021
+ operationId: external_exports.string().trim().min(1).optional(),
46022
+ requestContentType: external_exports.string().trim().min(1).optional(),
46023
+ requestSchema: external_exports.json().optional(),
46024
+ responseContentType: external_exports.string().trim().min(1).optional(),
46025
+ pathTemplate: external_exports.string().trim().min(1).optional(),
46026
+ pathParameters: external_exports.array(external_exports.string().trim().min(1)).optional(),
46027
+ payment: external_exports.union([
46028
+ external_exports.looseObject({
46029
+ scheme: external_exports.literal("exact"),
46030
+ network: external_exports.string().regex(/^eip155:\d+$/),
46031
+ asset: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
46032
+ payTo: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/),
46033
+ checkedAt: external_exports.iso.datetime()
46034
+ }),
46035
+ external_exports.looseObject({
46036
+ scheme: external_exports.literal("exact"),
46037
+ network: external_exports.union([
46038
+ external_exports.string().regex(/^solana:[-_a-zA-Z0-9]{1,32}$/),
46039
+ external_exports.literal(SOLANA_MAINNET_CAIP2)
46040
+ ]),
46041
+ asset: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
46042
+ payTo: external_exports.string().refine(isSolanaAddress, "Expected a Solana base58 address."),
46043
+ checkedAt: external_exports.iso.datetime()
46044
+ })
46045
+ ]).optional()
46046
+ });
46047
+ var serviceSummarySchema = external_exports.looseObject({
46048
+ id: external_exports.string(),
46049
+ name: external_exports.string(),
46050
+ description: external_exports.string(),
46051
+ category: discoveryCategorySchema,
46052
+ tier: serviceTierSchema,
46053
+ ...listingDisclosureShape,
46054
+ verified: external_exports.boolean(),
46055
+ wrapped: external_exports.boolean(),
46056
+ price: external_exports.string(),
46057
+ networks: external_exports.array(external_exports.string()),
46058
+ endpoints: external_exports.array(discoveryEndpointSchema)
46059
+ });
46060
+ var searchServicesResponseSchema = external_exports.looseObject({
46061
+ services: external_exports.array(serviceSummarySchema)
46062
+ });
46063
+ var discoveryResponseSchema = searchServicesResponseSchema;
46064
+
46065
+ // ../core/src/call-contracts.ts
46066
+ var DiscoveryCatalogError = class extends Error {
46067
+ constructor(code, message, serviceId, paymentNetworks) {
46068
+ super(message);
46069
+ this.paymentNetworks = paymentNetworks;
46070
+ this.code = code;
46071
+ this.serviceId = serviceId;
46072
+ }
46073
+ paymentNetworks;
46074
+ name = "DiscoveryCatalogError";
46075
+ code;
46076
+ serviceId;
46077
+ };
46078
+ function isDiscoveryCatalogError(error61) {
46079
+ if (!(error61 instanceof Error) || error61.name !== "DiscoveryCatalogError" || !("code" in error61) || typeof error61.code !== "string") {
46080
+ return false;
46081
+ }
46082
+ const networks = Reflect.get(error61, "paymentNetworks");
46083
+ return networks === void 0 || Array.isArray(networks) && networks.every((network) => typeof network === "string");
46084
+ }
46085
+ function parseDiscovery(raw) {
46086
+ const parsed = discoveryResponseSchema.safeParse(raw);
46087
+ if (!parsed.success) {
46088
+ const malformedUrl = parsed.error.issues.find(
46089
+ (issue2) => issue2.path.at(-1) === "url" && issue2.path.includes("endpoints")
46090
+ );
46091
+ if (malformedUrl) {
46092
+ const serviceIndex = pathIndexAfter(malformedUrl.path, "services");
46093
+ const serviceId = rawServiceId(raw, serviceIndex);
46094
+ throw new DiscoveryCatalogError(
46095
+ "malformed_url",
46096
+ `Service ${JSON.stringify(serviceId ?? "unknown")} has a malformed endpoint URL.`,
46097
+ serviceId
46098
+ );
46099
+ }
46100
+ throw new DiscoveryCatalogError("invalid_discovery", "Discovery response is malformed.");
46101
+ }
46102
+ for (const service of parsed.data.services) {
46103
+ buildTargets(service);
46104
+ }
46105
+ const resolveListing = (serviceId, endpointName) => {
46106
+ const service = parsed.data.services.find((candidate) => candidate.id === serviceId);
46107
+ if (!service) {
46108
+ throw new DiscoveryCatalogError(
46109
+ "service_not_found",
46110
+ `No payable endpoint found for service ${JSON.stringify(serviceId)}.`,
46111
+ serviceId
46112
+ );
46113
+ }
46114
+ return { service, endpoint: resolveTarget(service, endpointName) };
46115
+ };
46116
+ return {
46117
+ services: parsed.data.services,
46118
+ resolve: (serviceId, endpointName) => resolveListing(serviceId, endpointName).endpoint,
46119
+ resolveListing
46120
+ };
46121
+ }
46122
+ function resolveTarget(service, endpointName) {
46123
+ const { targets, targetsByName } = buildTargets(service);
46124
+ if (endpointName !== void 0) {
46125
+ const selected = targetsByName.get(endpointName.trim());
46126
+ if (!selected) {
46127
+ throw new DiscoveryCatalogError(
46128
+ "endpoint_not_found",
46129
+ `Service ${JSON.stringify(service.id)} has no endpoint ${JSON.stringify(endpointName)}. Available endpoints: ${[...targetsByName.keys()].join(", ")}.`,
46130
+ service.id
46131
+ );
46132
+ }
46133
+ return { ...selected };
46134
+ }
46135
+ if (targets.size !== 1) {
46136
+ const paymentNetworks = service.endpoints.flatMap(
46137
+ (endpoint) => endpoint.payment ? [endpoint.payment.network] : []
46138
+ );
46139
+ throw new DiscoveryCatalogError(
46140
+ "ambiguous_default",
46141
+ `Service ${JSON.stringify(service.id)} has ${targets.size} distinct payable endpoints. Choose one with endpoint: ${[...targetsByName.keys()].join(", ")}.`,
46142
+ service.id,
46143
+ paymentNetworks.length === service.endpoints.length ? paymentNetworks : void 0
46144
+ );
46145
+ }
46146
+ return targets.values().next().value;
46147
+ }
46148
+ function buildTargets(service) {
46149
+ if (service.endpoints.length === 0) {
46150
+ throw new DiscoveryCatalogError(
46151
+ "no_endpoint",
46152
+ `Service ${JSON.stringify(service.id)} has no payable endpoint.`,
46153
+ service.id
46154
+ );
46155
+ }
46156
+ const namedEndpoints = [...service.endpoints].sort(
46157
+ (left, right) => compareNames(left.name.trim(), right.name.trim())
46158
+ );
46159
+ const names = /* @__PURE__ */ new Set();
46160
+ const targets = /* @__PURE__ */ new Map();
46161
+ const targetsByName = /* @__PURE__ */ new Map();
46162
+ for (const endpoint of namedEndpoints) {
46163
+ const name = endpoint.name.trim();
46164
+ if (!name) {
46165
+ throw new DiscoveryCatalogError(
46166
+ "invalid_endpoint_name",
46167
+ `Service ${JSON.stringify(service.id)} has a blank endpoint name.`,
46168
+ service.id
46169
+ );
46170
+ }
46171
+ if (names.has(name)) {
46172
+ throw new DiscoveryCatalogError(
46173
+ "duplicate_endpoint_name",
46174
+ `Service ${JSON.stringify(service.id)} has duplicate endpoint name ${JSON.stringify(name)}.`,
46175
+ service.id
46176
+ );
46177
+ }
46178
+ names.add(name);
46179
+ const method = endpoint.method.trim().toUpperCase();
46180
+ if (!method) {
46181
+ throw new DiscoveryCatalogError(
46182
+ "blank_method",
46183
+ `Service ${JSON.stringify(service.id)} has a blank endpoint method.`,
46184
+ service.id
46185
+ );
46186
+ }
46187
+ const url2 = new URL(endpoint.url);
46188
+ if (url2.protocol !== "http:" && url2.protocol !== "https:") {
46189
+ throw new DiscoveryCatalogError(
46190
+ "malformed_url",
46191
+ `Service ${JSON.stringify(service.id)} has a non-HTTP endpoint URL.`,
46192
+ service.id
46193
+ );
46194
+ }
46195
+ const transportKey = `${method}\0${endpoint.url}`;
46196
+ const normalized = { ...endpoint, name, method };
46197
+ targetsByName.set(name, normalized);
46198
+ if (!targets.has(transportKey)) targets.set(transportKey, normalized);
46199
+ }
46200
+ return { targets, targetsByName };
46201
+ }
46202
+ function compareNames(left, right) {
46203
+ return left < right ? -1 : left > right ? 1 : 0;
46204
+ }
46205
+ function pathIndexAfter(path, key2) {
46206
+ const keyIndex = path.indexOf(key2);
46207
+ const candidate = path[keyIndex + 1];
46208
+ return typeof candidate === "number" ? candidate : void 0;
46209
+ }
46210
+ function rawServiceId(raw, serviceIndex) {
46211
+ if (serviceIndex === void 0 || typeof raw !== "object" || raw === null) {
46212
+ return void 0;
46213
+ }
46214
+ const services = Reflect.get(raw, "services");
46215
+ if (!Array.isArray(services)) {
46216
+ return void 0;
46217
+ }
46218
+ const service = services[serviceIndex];
46219
+ if (typeof service !== "object" || service === null) {
46220
+ return void 0;
46221
+ }
46222
+ const id2 = Reflect.get(service, "id");
46223
+ return typeof id2 === "string" ? id2 : void 0;
46224
+ }
46225
+
46187
46226
  // ../core/src/sweep.ts
46188
46227
  var ERC20_ABI = [
46189
46228
  {
@@ -47032,7 +47071,7 @@ var configSchema = external_exports.object({
47032
47071
  }
47033
47072
  for (const [network, configured] of Object.entries(config2.networks)) {
47034
47073
  if (isSolanaNetwork(network)) {
47035
- if (configured.usdc !== NETWORKS[SOLANA_MAINNET_CAIP2].usdc) {
47074
+ if (configured.usdc !== NETWORKS2[SOLANA_MAINNET_CAIP2].usdc) {
47036
47075
  context.addIssue({
47037
47076
  code: "custom",
47038
47077
  path: ["networks", network, "usdc"],
@@ -47043,7 +47082,7 @@ var configSchema = external_exports.object({
47043
47082
  }
47044
47083
  try {
47045
47084
  const usdc = getAddress(configured.usdc);
47046
- if ((network === ARC_MAINNET_CAIP2 || network === ARC_TESTNET_CAIP2) && usdc !== getAddress(NETWORKS[network].usdc)) {
47085
+ if ((network === ARC_MAINNET_CAIP2 || network === ARC_TESTNET_CAIP2) && usdc !== getAddress(NETWORKS2[network].usdc)) {
47047
47086
  context.addIssue({
47048
47087
  code: "custom",
47049
47088
  path: ["networks", network, "usdc"],
@@ -47195,15 +47234,15 @@ function getDefaultConfig(source = process.env, options = {}) {
47195
47234
  const tasksEscrowFactoryOverrides = tasksFactoryOverridesFromEnv(source);
47196
47235
  if (requested.has("base") || requested.has(BASE_MAINNET_CAIP2)) {
47197
47236
  networks[BASE_MAINNET_CAIP2] = {
47198
- rpcUrl: source.BASE_RPC_URL?.trim() || NETWORKS[BASE_MAINNET_CAIP2].publicRpcUrl,
47199
- usdc: NETWORKS[BASE_MAINNET_CAIP2].usdc
47237
+ rpcUrl: source.BASE_RPC_URL?.trim() || NETWORKS2[BASE_MAINNET_CAIP2].publicRpcUrl,
47238
+ usdc: NETWORKS2[BASE_MAINNET_CAIP2].usdc
47200
47239
  };
47201
47240
  }
47202
47241
  const arcMainnetRpcUrl = source.ARC_RPC_URL?.trim();
47203
47242
  if (arcMainnetRpcUrl || requested.has("arc") || requested.has(ARC_MAINNET_CAIP2)) {
47204
47243
  networks[ARC_MAINNET_CAIP2] = {
47205
- rpcUrl: arcMainnetRpcUrl || NETWORKS[ARC_MAINNET_CAIP2].publicRpcUrl,
47206
- usdc: NETWORKS[ARC_MAINNET_CAIP2].usdc
47244
+ rpcUrl: arcMainnetRpcUrl || NETWORKS2[ARC_MAINNET_CAIP2].publicRpcUrl,
47245
+ usdc: NETWORKS2[ARC_MAINNET_CAIP2].usdc
47207
47246
  };
47208
47247
  }
47209
47248
  const arcTestnetRpcUrl = source.ARC_TESTNET_RPC_URL?.trim();
@@ -47215,14 +47254,14 @@ function getDefaultConfig(source = process.env, options = {}) {
47215
47254
  }
47216
47255
  networks[ARC_TESTNET_CAIP2] = {
47217
47256
  rpcUrl: arcTestnetRpcUrl,
47218
- usdc: NETWORKS[ARC_TESTNET_CAIP2].usdc
47257
+ usdc: NETWORKS2[ARC_TESTNET_CAIP2].usdc
47219
47258
  };
47220
47259
  }
47221
47260
  const solanaRpcUrl = source.SOLANA_RPC_URL?.trim();
47222
47261
  if (solanaRpcUrl || requested.has("solana") || requested.has(SOLANA_MAINNET_CAIP2)) {
47223
47262
  networks[SOLANA_MAINNET_CAIP2] = {
47224
- rpcUrl: solanaRpcUrl || NETWORKS[SOLANA_MAINNET_CAIP2].publicRpcUrl,
47225
- usdc: NETWORKS[SOLANA_MAINNET_CAIP2].usdc
47263
+ rpcUrl: solanaRpcUrl || NETWORKS2[SOLANA_MAINNET_CAIP2].publicRpcUrl,
47264
+ usdc: NETWORKS2[SOLANA_MAINNET_CAIP2].usdc
47226
47265
  };
47227
47266
  }
47228
47267
  return {
@@ -47280,21 +47319,21 @@ Run vapi init to write the new URLs to ${path}.`
47280
47319
  if (arcMainnetRpcUrl) {
47281
47320
  const existing = config2.networks[ARC_MAINNET_CAIP2];
47282
47321
  config2.networks[ARC_MAINNET_CAIP2] = {
47283
- ...existing ?? { usdc: NETWORKS[ARC_MAINNET_CAIP2].usdc },
47322
+ ...existing ?? { usdc: NETWORKS2[ARC_MAINNET_CAIP2].usdc },
47284
47323
  rpcUrl: arcMainnetRpcUrl
47285
47324
  };
47286
47325
  }
47287
47326
  if (arcTestnetRpcUrl) {
47288
47327
  const existing = config2.networks[ARC_TESTNET_CAIP2];
47289
47328
  config2.networks[ARC_TESTNET_CAIP2] = {
47290
- ...existing ?? { usdc: NETWORKS[ARC_TESTNET_CAIP2].usdc },
47329
+ ...existing ?? { usdc: NETWORKS2[ARC_TESTNET_CAIP2].usdc },
47291
47330
  rpcUrl: arcTestnetRpcUrl
47292
47331
  };
47293
47332
  }
47294
47333
  if (solanaRpcUrl) {
47295
47334
  config2.networks[SOLANA_MAINNET_CAIP2] = {
47296
47335
  rpcUrl: solanaRpcUrl,
47297
- usdc: config2.networks[SOLANA_MAINNET_CAIP2]?.usdc ?? NETWORKS[SOLANA_MAINNET_CAIP2].usdc
47336
+ usdc: config2.networks[SOLANA_MAINNET_CAIP2]?.usdc ?? NETWORKS2[SOLANA_MAINNET_CAIP2].usdc
47298
47337
  };
47299
47338
  }
47300
47339
  if (registryUrl) {
@@ -47307,7 +47346,7 @@ Run vapi init to write the new URLs to ${path}.`
47307
47346
  for (const [network, configured] of Object.entries(config2.networks)) {
47308
47347
  configured.rpcUrl = configured.rpcUrl.trim();
47309
47348
  configured.usdc = configured.usdc.trim();
47310
- if (isSolanaNetwork(network) && configured.usdc !== NETWORKS[SOLANA_MAINNET_CAIP2].usdc) {
47349
+ if (isSolanaNetwork(network) && configured.usdc !== NETWORKS2[SOLANA_MAINNET_CAIP2].usdc) {
47311
47350
  throw new Error(`Network ${network} must use canonical Solana mainnet USDC.`);
47312
47351
  }
47313
47352
  if (!configured.rpcUrl) delete config2.networks[network];
@@ -47363,14 +47402,14 @@ async function enableDefaultNetwork(network, path = getVapiPaths().config, sourc
47363
47402
  const config2 = await loadConfig(path, source);
47364
47403
  if (network === "solana") {
47365
47404
  config2.networks[SOLANA_MAINNET_CAIP2] = {
47366
- rpcUrl: source.SOLANA_RPC_URL?.trim() || NETWORKS[SOLANA_MAINNET_CAIP2].publicRpcUrl,
47367
- usdc: NETWORKS[SOLANA_MAINNET_CAIP2].usdc
47405
+ rpcUrl: source.SOLANA_RPC_URL?.trim() || NETWORKS2[SOLANA_MAINNET_CAIP2].publicRpcUrl,
47406
+ usdc: NETWORKS2[SOLANA_MAINNET_CAIP2].usdc
47368
47407
  };
47369
47408
  } else {
47370
47409
  const existing = config2.networks[ARC_MAINNET_CAIP2];
47371
47410
  config2.networks[ARC_MAINNET_CAIP2] = {
47372
- ...existing ?? { usdc: NETWORKS[ARC_MAINNET_CAIP2].usdc },
47373
- rpcUrl: source.ARC_RPC_URL?.trim() || NETWORKS[ARC_MAINNET_CAIP2].publicRpcUrl
47411
+ ...existing ?? { usdc: NETWORKS2[ARC_MAINNET_CAIP2].usdc },
47412
+ rpcUrl: source.ARC_RPC_URL?.trim() || NETWORKS2[ARC_MAINNET_CAIP2].publicRpcUrl
47374
47413
  };
47375
47414
  }
47376
47415
  await writeConfigFile(path, config2);
@@ -77483,7 +77522,7 @@ function createRunBudget(args) {
77483
77522
  import { mkdir as mkdir15, writeFile as writeFile8 } from "node:fs/promises";
77484
77523
  import { arch, platform, release } from "node:os";
77485
77524
  import { join as join13 } from "node:path";
77486
- var VAPI_CLIENT_VERSION = "0.9.0";
77525
+ var VAPI_CLIENT_VERSION = "0.9.2";
77487
77526
  async function createSupportReport(options) {
77488
77527
  const message = options.message.trim();
77489
77528
  if (!message) throw new Error("Support report message must not be empty.");
@@ -78996,6 +79035,7 @@ var missingTasksChain = {
78996
79035
 
78997
79036
  // ../core/src/tasks/types.ts
78998
79037
  var uuidSchema = external_exports.uuid();
79038
+ var profileIdSchema = external_exports.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
78999
79039
  var isoDateTimeSchema = external_exports.iso.datetime();
79000
79040
  var addressSchema5 = external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/).transform((value) => value.toLowerCase());
79001
79041
  var bytes32Schema = external_exports.string().regex(/^0x[0-9a-fA-F]{64}$/).transform((value) => value.toLowerCase());
@@ -79333,7 +79373,7 @@ var deliveryResponseSchema = external_exports.looseObject({
79333
79373
  version: external_exports.number().int().positive(),
79334
79374
  manifest: manifestResponseSchema,
79335
79375
  manifestHash: bytes32Schema,
79336
- submittedByProfileId: uuidSchema,
79376
+ submittedByProfileId: profileIdSchema,
79337
79377
  createdAt: isoDateTimeSchema
79338
79378
  });
79339
79379
  var orderDeliveryResponseSchema = external_exports.looseObject({
@@ -79439,7 +79479,7 @@ var reviewResponseSchema = external_exports.looseObject({
79439
79479
  id: uuidSchema,
79440
79480
  workOrderId: uuidSchema,
79441
79481
  clientAddress: addressSchema5,
79442
- vendorProfileId: uuidSchema,
79482
+ vendorProfileId: profileIdSchema,
79443
79483
  rating: external_exports.number().int().min(1).max(5),
79444
79484
  body: external_exports.string(),
79445
79485
  subRatings: external_exports.json().nullable(),
@@ -79982,12 +80022,15 @@ function createTasksClient(options) {
79982
80022
  const parsed2 = serverErrorSchema.safeParse(errorBody);
79983
80023
  const server = parsed2.success ? parsed2.data : void 0;
79984
80024
  const nested = typeof server?.error === "object" ? server.error : void 0;
79985
- const message = (typeof server?.error === "string" ? server.error : nested?.message) || server?.message || response.statusText || `HTTP ${response.status}`;
80025
+ const serverCode = nested?.code ?? server?.code;
80026
+ const serverMessage = (typeof server?.error === "string" ? server.error : nested?.message) || server?.message;
80027
+ const fallback = response.statusText || `HTTP ${response.status}`;
80028
+ 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);
79986
80029
  throw new TasksClientError(
79987
80030
  "http",
79988
80031
  message,
79989
80032
  response.status,
79990
- nested?.code ?? server?.code,
80033
+ serverCode,
79991
80034
  response.headers.get("Retry-After") ?? void 0
79992
80035
  );
79993
80036
  }
@@ -80390,9 +80433,10 @@ function safeTasksChainError(cause, broadcast, authorizationExposed, txHash) {
80390
80433
  let message = "Task chain operation failed.";
80391
80434
  if (cause instanceof TasksValidationError || cause instanceof TasksChainError)
80392
80435
  message = cause.message;
80393
- else if (cause instanceof TasksClientError)
80394
- message = `Tasks service request failed${cause.status === void 0 ? "" : ` (status ${cause.status})`}.`;
80395
- else if (cause instanceof Error) {
80436
+ else if (cause instanceof TasksClientError) {
80437
+ const code = cause.serverCode ?? (cause.status ? `http_${cause.status}` : cause.code);
80438
+ message = cause.status === 401 || cause.status === 403 ? `${code} (status ${cause.status})` : `${code}: ${cause.message}`;
80439
+ } else if (cause instanceof Error) {
80396
80440
  const short = "shortMessage" in cause && typeof cause.shortMessage === "string" ? cause.shortMessage : void 0;
80397
80441
  let statusCode;
80398
80442
  const seen = /* @__PURE__ */ new Set();
@@ -81200,6 +81244,44 @@ function createTasksChain(options) {
81200
81244
  return idempotencyKey;
81201
81245
  });
81202
81246
  }
81247
+ async function prepareOrResume(prepare, expected, idempotencyKey, kind, steps, authorizationExposed = false, beforeSign) {
81248
+ let prepared;
81249
+ let resumedFromServer = false;
81250
+ try {
81251
+ prepared = await prepare();
81252
+ } catch (error61) {
81253
+ if (!uncertainPreparation(error61)) throw error61;
81254
+ const fresh = await order(expected.milestone.workOrderId);
81255
+ const matches = fresh.milestones.filter((item) => item.id === expected.milestone.id);
81256
+ if (matches.length !== 1 || matches[0].workOrderId !== fresh.id)
81257
+ throw new TasksValidationError("The task milestone does not match its parent order.");
81258
+ const selected = matches[0];
81259
+ const operation = selected.chainOperation;
81260
+ if (expected.verb === "deliver" && selected.delivery && !operation)
81261
+ throw new TasksValidationError(
81262
+ "The server recorded this delivery but has no chain operation for it; open the task in the console to continue."
81263
+ );
81264
+ if (!operation || operation.kind !== kind || !(typeof steps === "string" ? [steps] : steps).includes(operation.step) || !["prepared", "submitted", "confirmed"].includes(operation.state))
81265
+ throw error61;
81266
+ if (expected.verb === "deliver" && selected.delivery && selected.delivery.manifestHash !== expected.manifestHash)
81267
+ throw new TasksValidationError(
81268
+ "The server recorded a different delivery manifest; refusing to continue."
81269
+ );
81270
+ prepared = {
81271
+ operation,
81272
+ milestone: { id: selected.id, workOrderId: selected.workOrderId }
81273
+ };
81274
+ resumedFromServer = true;
81275
+ }
81276
+ const result = await execute(
81277
+ prepared,
81278
+ expected,
81279
+ idempotencyKey,
81280
+ authorizationExposed,
81281
+ beforeSign
81282
+ );
81283
+ return resumedFromServer ? { ...result, resumedFromServer: true } : result;
81284
+ }
81203
81285
  async function verifyReceipt(operation, expected, hash5) {
81204
81286
  const rpc = rpcFor(expected.deployment.chainId);
81205
81287
  const receipt = await rpc.waitForTransactionReceipt({ hash: hash5, confirmations });
@@ -81241,6 +81323,7 @@ function createTasksChain(options) {
81241
81323
  throw new TasksValidationError(
81242
81324
  "The RPC transaction input does not match the verified task plan."
81243
81325
  );
81326
+ return receipt.blockNumber.toString();
81244
81327
  }
81245
81328
  async function retryConflict(call2) {
81246
81329
  let waited = 0;
@@ -81268,6 +81351,7 @@ function createTasksChain(options) {
81268
81351
  current = { ...initial, operation: live };
81269
81352
  let broadcast = current.operation.state === "submitted";
81270
81353
  let txHash = current.operation.transactionHash ?? void 0;
81354
+ let blockNumber;
81271
81355
  const operationId = initial.operation.id;
81272
81356
  function checkTransition(previous, next) {
81273
81357
  if (previous !== next && !(previous === "approve-usdc" && next === afterApproval))
@@ -81303,7 +81387,7 @@ function createTasksChain(options) {
81303
81387
  if (!operation.transactionHash)
81304
81388
  throw new TasksValidationError("The confirmed task operation has no transaction hash.");
81305
81389
  if (!checkpoint) {
81306
- await verifyReceipt(operation, expected, operation.transactionHash);
81390
+ blockNumber = await verifyReceipt(operation, expected, operation.transactionHash);
81307
81391
  await pending.complete(operation.id, operation.step, current);
81308
81392
  }
81309
81393
  const fresh = await order(expected.milestone.workOrderId);
@@ -81312,7 +81396,12 @@ function createTasksChain(options) {
81312
81396
  );
81313
81397
  if (!resultMilestone)
81314
81398
  throw new TasksValidationError("The reconciled task milestone is unavailable.");
81315
- return { txHash: operation.transactionHash, operation, milestone: resultMilestone };
81399
+ return {
81400
+ txHash: operation.transactionHash,
81401
+ operation,
81402
+ milestone: resultMilestone,
81403
+ blockNumber
81404
+ };
81316
81405
  }
81317
81406
  const rpc = rpcFor(expected.deployment.chainId);
81318
81407
  if (operation.state === "prepared") {
@@ -81508,7 +81597,7 @@ function createTasksChain(options) {
81508
81597
  }
81509
81598
  if (operation.state !== "submitted" || !operation.transactionHash)
81510
81599
  throw new TasksValidationError("The task operation has no submitted transaction.");
81511
- await verifyReceipt(operation, expected, operation.transactionHash);
81600
+ blockNumber = await verifyReceipt(operation, expected, operation.transactionHash);
81512
81601
  const reconciled = await retryConflict(
81513
81602
  () => client.reconcileOperation(
81514
81603
  operation.id,
@@ -81531,6 +81620,7 @@ function createTasksChain(options) {
81531
81620
  if (reconciled.operation.state !== "confirmed" && !(operation.step === "approve-usdc" && reconciled.operation.state === "prepared" && reconciled.operation.step === afterApproval))
81532
81621
  throw new TasksValidationError("The task transaction was not reconciled.");
81533
81622
  await pending.complete(operation.id, operation.step, reconciled);
81623
+ if (reconciled.operation.step !== operation.step) blockNumber = void 0;
81534
81624
  current = reconciled;
81535
81625
  }
81536
81626
  throw new TasksValidationError("The task operation exceeded its allowed step transitions.");
@@ -81565,14 +81655,16 @@ function createTasksChain(options) {
81565
81655
  );
81566
81656
  const prepareKey = await preparation(input2, verb, { evidenceHash: input2.evidenceHash });
81567
81657
  const call2 = verb === "dispute" ? client.disputeEscrow.bind(client) : client.counterEvidenceEscrow.bind(client);
81568
- return await execute(
81569
- await call2(
81658
+ return await prepareOrResume(
81659
+ () => call2(
81570
81660
  input2.escrowId,
81571
81661
  { evidenceHash: input2.evidenceHash },
81572
81662
  { idempotencyKey: prepareKey }
81573
81663
  ),
81574
81664
  { ...expected, evidenceHash: input2.evidenceHash },
81575
81665
  prepareKey,
81666
+ verb === "dispute" ? "escrow-dispute" : "escrow-counter-evidence",
81667
+ expected.steps,
81576
81668
  exposed,
81577
81669
  input2.beforeSign
81578
81670
  );
@@ -81592,11 +81684,34 @@ function createTasksChain(options) {
81592
81684
  await options.bindings.put(binding);
81593
81685
  },
81594
81686
  createEscrow: (input2) => safe(async () => {
81595
- const workOrder = await order(input2.orderId);
81687
+ let workOrder = await order(input2.orderId);
81596
81688
  const ready = await deployment();
81597
- const prepared = await client.createEscrow(input2.orderId, {
81598
- idempotencyKey: input2.idempotencyKey
81599
- });
81689
+ let prepared;
81690
+ let resumedFromServer = false;
81691
+ try {
81692
+ prepared = await client.createEscrow(input2.orderId, {
81693
+ idempotencyKey: input2.idempotencyKey
81694
+ });
81695
+ } catch (error61) {
81696
+ if (!uncertainPreparation(error61)) throw error61;
81697
+ const fresh = await order(input2.orderId);
81698
+ const candidates = fresh.milestones.filter((item) => {
81699
+ const previous = workOrder.milestones.find((prior) => prior.id === item.id);
81700
+ const operation = item.chainOperation;
81701
+ return item.workOrderId === input2.orderId && previous && operation && operation.kind === "escrow-create" && operation.step === "create-escrow" && (previous.escrowState === null || previous.chainOperation?.id === operation.id);
81702
+ });
81703
+ if (candidates.length !== 1) throw error61;
81704
+ const selected2 = candidates[0];
81705
+ prepared = {
81706
+ operation: selected2.chainOperation,
81707
+ milestone: {
81708
+ id: selected2.id,
81709
+ workOrderId: selected2.workOrderId
81710
+ }
81711
+ };
81712
+ workOrder = fresh;
81713
+ resumedFromServer = true;
81714
+ }
81600
81715
  const selected = workOrder.milestones.find((item) => item.id === prepared.milestone.id);
81601
81716
  if (!selected || selected.workOrderId !== input2.orderId)
81602
81717
  throw new TasksValidationError(
@@ -81606,11 +81721,12 @@ function createTasksChain(options) {
81606
81721
  { escrowId: selected.id, idempotencyKey: input2.idempotencyKey },
81607
81722
  "createEscrow"
81608
81723
  );
81609
- return await execute(
81724
+ const result = await execute(
81610
81725
  prepared,
81611
81726
  await expectation(selected, ready, "createEscrow", ["create-escrow"], input2.counterparty),
81612
81727
  prepareKey
81613
81728
  );
81729
+ return resumedFromServer ? { ...result, resumedFromServer: true } : result;
81614
81730
  }),
81615
81731
  async fund(input2) {
81616
81732
  let exposed = true;
@@ -81698,10 +81814,14 @@ function createTasksChain(options) {
81698
81814
  }
81699
81815
  exposed = true;
81700
81816
  await pending.markExposure(selected.id);
81701
- const prepared = await client.fundEscrow(input2.escrowId, body, {
81702
- idempotencyKey: prepareKey
81703
- });
81704
- return await execute(prepared, expected, prepareKey, exposed);
81817
+ return await prepareOrResume(
81818
+ () => client.fundEscrow(input2.escrowId, body, { idempotencyKey: prepareKey }),
81819
+ expected,
81820
+ prepareKey,
81821
+ "escrow-funding",
81822
+ expected.steps,
81823
+ exposed
81824
+ );
81705
81825
  } catch (cause) {
81706
81826
  throw chainError(cause, false, exposed);
81707
81827
  }
@@ -81726,22 +81846,26 @@ function createTasksChain(options) {
81726
81846
  manifest: frozen.manifest,
81727
81847
  note: input2.note
81728
81848
  });
81729
- const prepared = await client.deliverEscrow(
81730
- input2.escrowId,
81731
- { fileIds: frozen.manifest.files.map((file2) => file2.fileId), note: input2.note },
81732
- { idempotencyKey: prepareKey }
81733
- );
81734
- if (prepared.delivery.manifestHash !== frozen.manifestHash)
81735
- throw new TasksValidationError(
81736
- "The server task delivery manifest hash does not match the local manifest."
81737
- );
81738
- return await execute(
81739
- prepared,
81849
+ return await prepareOrResume(
81850
+ async () => {
81851
+ const prepared = await client.deliverEscrow(
81852
+ input2.escrowId,
81853
+ { fileIds: frozen.manifest.files.map((file2) => file2.fileId), note: input2.note },
81854
+ { idempotencyKey: prepareKey }
81855
+ );
81856
+ if (prepared.delivery.manifestHash !== frozen.manifestHash)
81857
+ throw new TasksValidationError(
81858
+ "The server task delivery manifest hash does not match the local manifest."
81859
+ );
81860
+ return prepared;
81861
+ },
81740
81862
  {
81741
81863
  ...expected,
81742
81864
  manifestHash: frozen.manifestHash
81743
81865
  },
81744
- prepareKey
81866
+ prepareKey,
81867
+ "escrow-delivery",
81868
+ "submit-delivery"
81745
81869
  );
81746
81870
  }),
81747
81871
  release: (input2) => safe(async () => {
@@ -81755,10 +81879,12 @@ function createTasksChain(options) {
81755
81879
  input2.counterparty
81756
81880
  );
81757
81881
  const prepareKey = await preparation(input2, "release");
81758
- return await execute(
81759
- await client.releaseEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
81882
+ return await prepareOrResume(
81883
+ () => client.releaseEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
81760
81884
  expected,
81761
- prepareKey
81885
+ prepareKey,
81886
+ "escrow-release",
81887
+ "release-funds"
81762
81888
  );
81763
81889
  }),
81764
81890
  refund: (input2) => safe(async () => {
@@ -81772,10 +81898,12 @@ function createTasksChain(options) {
81772
81898
  input2.counterparty
81773
81899
  );
81774
81900
  const prepareKey = await preparation(input2, "refund");
81775
- return await execute(
81776
- await client.refundEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
81901
+ return await prepareOrResume(
81902
+ () => client.refundEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
81777
81903
  expected,
81778
- prepareKey
81904
+ prepareKey,
81905
+ "escrow-release",
81906
+ "refund-buyer"
81779
81907
  );
81780
81908
  }),
81781
81909
  disputeFee: (input2) => safe(async () => {
@@ -81803,16 +81931,21 @@ function createTasksChain(options) {
81803
81931
  input2.counterparty
81804
81932
  );
81805
81933
  const prepareKey = await preparation(input2, "resolve-unmatched");
81806
- return execute(
81807
- await client.resolveUnmatchedEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
81934
+ return prepareOrResume(
81935
+ () => client.resolveUnmatchedEscrow(input2.escrowId, { idempotencyKey: prepareKey }),
81808
81936
  expected,
81809
- prepareKey
81937
+ prepareKey,
81938
+ "escrow-unmatched-resolution",
81939
+ "resolve-unmatched-dispute"
81810
81940
  );
81811
81941
  }),
81812
81942
  signScopeMessage: (message) => safe(() => account.signMessage({ message }))
81813
81943
  };
81814
81944
  }
81815
81945
  var chainError = safeTasksChainError;
81946
+ function uncertainPreparation(error61) {
81947
+ return error61 instanceof TasksClientError && ((error61.status ?? 0) >= 400 || error61.code === "network" || error61.code === "timeout");
81948
+ }
81816
81949
  function retryDelay(header, now) {
81817
81950
  if (/^\d+(?:\.\d+)?$/u.test(header.trim())) return Math.max(1, Math.ceil(Number(header) * 1e3));
81818
81951
  const date5 = Date.parse(header);
@@ -81829,6 +81962,60 @@ function alreadySent(error61) {
81829
81962
  return error61 instanceof Error && /already known|known transaction|nonce (?:is )?too low/iu.test(error61.message);
81830
81963
  }
81831
81964
 
81965
+ // ../core/src/tasks/wait.ts
81966
+ async function waitForMilestone(client, input2) {
81967
+ const timeoutMs = input2.timeoutMs ?? 12e4;
81968
+ const intervalMs = input2.intervalMs ?? 3e3;
81969
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0)
81970
+ throw new RangeError("The milestone wait timeout must be non-negative and finite.");
81971
+ if (!Number.isFinite(intervalMs) || intervalMs <= 0)
81972
+ throw new RangeError("The milestone wait interval must be positive and finite.");
81973
+ const sleep = input2.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
81974
+ const now = input2.now ?? (() => /* @__PURE__ */ new Date());
81975
+ const started = now().getTime();
81976
+ const deadline = started + timeoutMs;
81977
+ let polls = 0;
81978
+ let milestone;
81979
+ function result(reached) {
81980
+ return { reached, milestone, polls, elapsedMs: now().getTime() - started };
81981
+ }
81982
+ for (; ; ) {
81983
+ const remaining = deadline - now().getTime();
81984
+ if (remaining <= 0) return result(false);
81985
+ const controller = new AbortController();
81986
+ const timer = setTimeout(() => controller.abort(), remaining);
81987
+ let response;
81988
+ polls++;
81989
+ try {
81990
+ response = await client.getOrder(input2.orderId, { signal: controller.signal });
81991
+ } catch (error61) {
81992
+ if (controller.signal.aborted) return result(false);
81993
+ throw error61;
81994
+ } finally {
81995
+ clearTimeout(timer);
81996
+ }
81997
+ if (controller.signal.aborted || now().getTime() >= deadline) return result(false);
81998
+ const { workOrder } = response;
81999
+ milestone = workOrder.id === input2.orderId && workOrder.version === "work-order-view-v1" ? workOrder.milestones.find(
82000
+ (item) => item.id === input2.milestoneId && item.workOrderId === input2.orderId
82001
+ ) : void 0;
82002
+ if (milestone && reachedTarget(milestone, input2.target)) return result(true);
82003
+ await sleep(Math.min(intervalMs, deadline - now().getTime()));
82004
+ }
82005
+ }
82006
+ function reachedTarget(milestone, target) {
82007
+ switch (target) {
82008
+ case "created":
82009
+ return milestone.escrowState !== null;
82010
+ case "locked":
82011
+ return ["locked", "submitted", "disputed", "resolved"].includes(milestone.escrowState ?? "");
82012
+ case "delivered":
82013
+ return ["submitted", "disputed", "resolved"].includes(milestone.escrowState ?? "");
82014
+ case "released":
82015
+ return milestone.escrowState === "resolved";
82016
+ }
82017
+ }
82018
+
81832
82019
  // ../core/src/tasks/rpc.ts
81833
82020
  function createTasksRpcFor(config2, options = {}) {
81834
82021
  const clients = /* @__PURE__ */ new Map();
@@ -82945,7 +83132,10 @@ async function taskRequest(verb, route, operation, options) {
82945
83132
  "not_signed_in",
82946
83133
  `${verb} needs sign-in. ${options.signInHint}`
82947
83134
  );
82948
- throw new TaskOperationError(error61.serverCode ?? error61.code, error61.message);
83135
+ throw new TaskOperationError(
83136
+ error61.serverCode ?? (error61.status ? `http_${error61.status}` : error61.code),
83137
+ error61.message
83138
+ );
82949
83139
  }
82950
83140
  throw error61;
82951
83141
  }
@@ -83066,7 +83256,8 @@ function proposalTerms(id2, address4, deployment, terms) {
83066
83256
  return {
83067
83257
  version: "work-proposal-v1",
83068
83258
  workOrderId: id2,
83069
- providerAddress: address4,
83259
+ // The server lowercases addresses before canonicalizing the signed payload.
83260
+ providerAddress: address4.toLowerCase(),
83070
83261
  pricingModel: "fixed",
83071
83262
  milestones: [
83072
83263
  {
@@ -83453,6 +83644,55 @@ async function showTask(context, input2) {
83453
83644
  };
83454
83645
  }
83455
83646
  async function taskStatus(context, input2) {
83647
+ if (input2.signedIn) {
83648
+ const chainState = await taskRequest(
83649
+ "status",
83650
+ "chainState",
83651
+ async () => {
83652
+ try {
83653
+ return await context.client.chainState(input2.id);
83654
+ } catch (error61) {
83655
+ if (error61 instanceof TasksClientError && error61.status === 404) {
83656
+ if (isMissingTaskEntity(error61.serverCode, error61.message))
83657
+ throw new TaskOperationError("not_found", error61.message);
83658
+ throw new TaskOperationError(
83659
+ "not_available",
83660
+ "GET /v1/work-orders/:id/chain-state is not available on this server."
83661
+ );
83662
+ }
83663
+ throw error61;
83664
+ }
83665
+ },
83666
+ context
83667
+ );
83668
+ if (chainState.workOrderId !== input2.id)
83669
+ throw new TaskOperationError("invalid_response", "The response belongs to a different task.");
83670
+ const page = await taskRequest(
83671
+ "status",
83672
+ "events",
83673
+ async () => {
83674
+ try {
83675
+ return await context.client.events(input2.id, { wait: 0 });
83676
+ } catch (error61) {
83677
+ if (error61 instanceof TasksClientError && error61.status === 404) {
83678
+ if (isMissingTaskEntity(error61.serverCode, error61.message)) return null;
83679
+ throw new TaskOperationError(
83680
+ "not_available",
83681
+ "GET /v1/work-orders/:id/events is not available on this server."
83682
+ );
83683
+ }
83684
+ throw error61;
83685
+ }
83686
+ },
83687
+ context
83688
+ );
83689
+ return {
83690
+ task: { id: input2.id },
83691
+ chainState,
83692
+ events: page ? [...page.events].sort((a, b) => a.sequence - b.sequence) : null,
83693
+ nextAfter: page?.nextAfter ?? null
83694
+ };
83695
+ }
83456
83696
  const task = await taskRequest(
83457
83697
  "status",
83458
83698
  "publicTask",
@@ -83808,6 +84048,7 @@ var searchEventSchema = external_exports.strictObject({
83808
84048
  source: external_exports.string().min(1),
83809
84049
  latencyMs: external_exports.number().nonnegative().finite(),
83810
84050
  count: external_exports.number().int().nonnegative(),
84051
+ dropped: external_exports.number().int().nonnegative().optional(),
83811
84052
  error: external_exports.string().optional()
83812
84053
  })
83813
84054
  ),
@@ -86879,7 +87120,7 @@ var memberBundleConfigSchema = external_exports.unknown().refine((value) => !has
86879
87120
  external_exports.strictObject({ usdc: external_exports.string() })
86880
87121
  ).refine(
86881
87122
  (networks) => Object.entries(networks).every(
86882
- ([id2, network]) => isMemberBundleNetwork(id2) && network.usdc === NETWORKS[id2].usdc
87123
+ ([id2, network]) => isMemberBundleNetwork(id2) && network.usdc === NETWORKS2[id2].usdc
86883
87124
  ),
86884
87125
  { message: "Expected the canonical USDC token of each network." }
86885
87126
  ).refine((networks) => Object.keys(networks).length === 1, {
@@ -86918,14 +87159,14 @@ function memberBundleConfig(owner, network) {
86918
87159
  return {
86919
87160
  discoveryUrl,
86920
87161
  marketplaceDiscoveryUrl,
86921
- networks: { [network]: { usdc: NETWORKS[network].usdc } }
87162
+ networks: { [network]: { usdc: NETWORKS2[network].usdc } }
86922
87163
  };
86923
87164
  }
86924
87165
  function headlessConfigFromBundle(config2) {
86925
87166
  const networks = {};
86926
87167
  for (const [id2, network] of Object.entries(config2.networks)) {
86927
87168
  if (!isMemberBundleNetwork(id2) || network === void 0) continue;
86928
- networks[id2] = { rpcUrl: NETWORKS[id2].publicRpcUrl, usdc: network.usdc };
87169
+ networks[id2] = { rpcUrl: NETWORKS2[id2].publicRpcUrl, usdc: network.usdc };
86929
87170
  }
86930
87171
  return configSchema.parse({
86931
87172
  discoveryUrl: config2.discoveryUrl,
@@ -87018,7 +87259,7 @@ function parseStoredTokens(value) {
87018
87259
  }
87019
87260
  }
87020
87261
  function isMemberBundleNetwork(id2) {
87021
- return Object.hasOwn(NETWORKS, id2) && typeof NETWORKS[id2].publicRpcUrl === "string";
87262
+ return Object.hasOwn(NETWORKS2, id2) && typeof NETWORKS2[id2].publicRpcUrl === "string";
87022
87263
  }
87023
87264
  function hasForbiddenConfigKey(value) {
87024
87265
  if (Array.isArray(value)) return value.some(hasForbiddenConfigKey);
@@ -87320,11 +87561,28 @@ async function searchMarketplace(input2, config2, fetchImpl, options = {}) {
87320
87561
  }
87321
87562
  }
87322
87563
  });
87323
- const page = marketplaceDiscoveryPageSchema.parse(await response.json());
87324
- mergedCount = page.items.length;
87564
+ const envelope = marketplaceDiscoveryEnvelopeSchema.parse(await response.json());
87565
+ const items = [];
87566
+ let dropped = 0;
87567
+ for (const [index2, rawItem] of envelope.items.entries()) {
87568
+ const parsed = marketplaceHitSchema.safeParse(rawItem);
87569
+ if (parsed.success) {
87570
+ items.push(parsed.data);
87571
+ continue;
87572
+ }
87573
+ dropped += 1;
87574
+ try {
87575
+ options.debug?.(`vAPI marketplace discovery dropped invalid row at index ${index2}.`);
87576
+ } catch {
87577
+ }
87578
+ }
87579
+ mergedCount = items.length;
87325
87580
  const attempt = attempts.at(-1);
87326
- if (attempt) attempt.count = mergedCount;
87327
- return page;
87581
+ if (attempt) {
87582
+ attempt.count = mergedCount;
87583
+ if (dropped > 0) attempt.dropped = dropped;
87584
+ }
87585
+ return { ...envelope, items };
87328
87586
  } finally {
87329
87587
  if (options.searchesPath) {
87330
87588
  await appendSearchEvent(
@@ -87450,6 +87708,34 @@ var VapiCallError = class extends Error {
87450
87708
  paymentRejection;
87451
87709
  confirmedSettlement;
87452
87710
  };
87711
+ var SOLANA_PAYMENTS_UNSUPPORTED_MESSAGE = "Solana payments are not supported in this version of vAPI yet; they arrive in a later release.";
87712
+ function isSolanaCaip2(network) {
87713
+ return network.startsWith("solana:");
87714
+ }
87715
+ function listingPaymentNetwork(endpointNetwork, serviceNetworks) {
87716
+ if (endpointNetwork !== void 0) return endpointNetwork;
87717
+ return serviceNetworks?.length && serviceNetworks.every(isSolanaCaip2) ? serviceNetworks[0] : void 0;
87718
+ }
87719
+ function assertSupportedListingNetwork(network) {
87720
+ if (network !== void 0 && isSolanaCaip2(network)) {
87721
+ throw new VapiCallError(
87722
+ "unsupported_network",
87723
+ `${SOLANA_PAYMENTS_UNSUPPORTED_MESSAGE} This listing pays on ${network}.`
87724
+ );
87725
+ }
87726
+ }
87727
+ function assertSupportedListingResolution(error61) {
87728
+ if (isDiscoveryCatalogError(error61) && error61.code === "ambiguous_default" && error61.paymentNetworks?.length && error61.paymentNetworks.every(isSolanaCaip2)) {
87729
+ assertSupportedListingNetwork(error61.paymentNetworks[0]);
87730
+ }
87731
+ }
87732
+ function payableConfig(config2, account) {
87733
+ if (account.solana !== void 0) return config2;
87734
+ const networks = Object.fromEntries(
87735
+ Object.entries(config2.networks).filter(([network]) => !isSolanaCaip2(network))
87736
+ );
87737
+ return { ...config2, networks };
87738
+ }
87453
87739
  var MAX_RESPONSE_BYTES = 1048576;
87454
87740
  var BODY_HEADER_NAMES = [
87455
87741
  "content-encoding",
@@ -87464,7 +87750,9 @@ async function callService(args) {
87464
87750
  try {
87465
87751
  execution = await executeCallService(args, trace);
87466
87752
  } catch (error61) {
87467
- await recordCallError(args, error61, trace).catch(() => void 0);
87753
+ if (!(error61 instanceof VapiCallError && error61.code === "unsupported_network")) {
87754
+ await recordCallError(args, error61, trace).catch(() => void 0);
87755
+ }
87468
87756
  throw error61;
87469
87757
  }
87470
87758
  try {
@@ -87512,10 +87800,16 @@ async function executeCallService(args, trace) {
87512
87800
  config2,
87513
87801
  fetchImpl
87514
87802
  );
87803
+ } catch (error61) {
87804
+ assertSupportedListingResolution(error61);
87805
+ throw error61;
87515
87806
  } finally {
87516
87807
  trace.phases.discoverMs = elapsed2(trace, discoverStarted);
87517
87808
  }
87518
87809
  }
87810
+ assertSupportedListingNetwork(
87811
+ listingPaymentNetwork(endpoint?.payment?.network, endpoint?.serviceNetworks)
87812
+ );
87519
87813
  const requestedNetwork = normalizeRequiredNetwork(input2.network);
87520
87814
  const listingNetwork = endpoint?.payment?.network;
87521
87815
  if (requestedNetwork && listingNetwork && !areSamePaymentNetwork(requestedNetwork, listingNetwork)) {
@@ -87731,7 +88025,7 @@ async function executeCallService(args, trace) {
87731
88025
  challenge: challengeAttempt,
87732
88026
  account,
87733
88027
  caps: args.spendCaps ?? config2.spendCaps,
87734
- config: config2,
88028
+ config: payableConfig(config2, account),
87735
88029
  send: async (paidRequest) => {
87736
88030
  paidAttempt = await fetchWithGuardedRedirects(paidRequest, false);
87737
88031
  return paidAttempt;
@@ -87981,7 +88275,7 @@ async function resolveCallEndpoint(id2, endpointName, marketplaceHit, config2, f
87981
88275
  try {
87982
88276
  return registeredEndpoint(await resolveServiceListing(id2, config2, fetchImpl, endpointName));
87983
88277
  } catch (error61) {
87984
- if (!(error61 instanceof DiscoveryCatalogError) || error61.code !== "service_not_found") {
88278
+ if (!isDiscoveryCatalogError(error61) || error61.code !== "service_not_found") {
87985
88279
  throw error61;
87986
88280
  }
87987
88281
  const discovered = await findMarketplaceApiByRef(id2, config2, fetchImpl);
@@ -88021,6 +88315,7 @@ function registeredEndpoint(listing, verification) {
88021
88315
  return {
88022
88316
  ...listing.endpoint,
88023
88317
  verification: verification ?? listing.service.verification,
88318
+ serviceNetworks: listing.service.networks,
88024
88319
  registered: true,
88025
88320
  resolvedListing: true
88026
88321
  };
@@ -88259,14 +88554,17 @@ async function inspectService(input2, config2, fetchImpl) {
88259
88554
  try {
88260
88555
  listing = await resolveServiceListing(input2.id, config2, fetchImpl, input2.endpoint);
88261
88556
  } catch (error61) {
88262
- if (input2.endpoint || !(error61 instanceof DiscoveryCatalogError) || error61.code !== "service_not_found") {
88557
+ assertSupportedListingResolution(error61);
88558
+ if (input2.endpoint || !isDiscoveryCatalogError(error61) || error61.code !== "service_not_found") {
88263
88559
  throw error61;
88264
88560
  }
88265
88561
  const hit = await findMarketplaceApiByRef(input2.id, config2, fetchImpl);
88266
88562
  if (!hit || hit.kind !== "api" || hit.provenance !== "indexed") throw error61;
88563
+ assertSupportedListingNetwork(hit.execution.network);
88267
88564
  return inspectIndexedHit(hit);
88268
88565
  }
88269
88566
  const { endpoint, service } = listing;
88567
+ assertSupportedListingNetwork(listingPaymentNetwork(endpoint.payment?.network, service.networks));
88270
88568
  return {
88271
88569
  name: endpoint.name,
88272
88570
  method: endpoint.method,
@@ -92036,6 +92334,7 @@ var moneyParticipant = {
92036
92334
  "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."
92037
92335
  ).optional()
92038
92336
  };
92337
+ var waitForIndexer = external_exports.boolean().default(true).describe("Wait up to 60 seconds for vAPI to index the chain result before returning.");
92039
92338
  var cursor = external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
92040
92339
  function usdWithinEscrow(value, positive = false) {
92041
92340
  try {
@@ -92082,7 +92381,10 @@ var tasksPostTool = descriptor(
92082
92381
  deadline: external_exports.string(),
92083
92382
  intake: external_exports.enum(["proposals", "submissions"]).optional(),
92084
92383
  maxAwards: external_exports.number().int().min(TASK_LIMITS.maxAwardsMin).max(TASK_LIMITS.maxAwardsMax).optional(),
92085
- webhookUrl: httpsUrl.optional()
92384
+ webhookUrl: httpsUrl.optional(),
92385
+ vendor: external_exports.string().regex(/^0x[0-9a-fA-F]{40}$/u).describe(
92386
+ "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."
92387
+ ).optional()
92086
92388
  }
92087
92389
  );
92088
92390
  var tasksProposeTool = descriptor(
@@ -92107,42 +92409,43 @@ var tasksAwardTool = descriptor(
92107
92409
  { ...participant, proposalId: id }
92108
92410
  );
92109
92411
  var tasksSignTool = descriptor(
92110
- "Does not move money. Sign the current counterparty scope locally after the human confirms the money direction via counterparty; a worker may also create the unfunded escrow with the local vault wallet.",
92111
- moneyParticipant
92412
+ "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.",
92413
+ { ...moneyParticipant, wait: waitForIndexer }
92112
92414
  );
92113
92415
  var tasksFundTool = descriptor(
92114
- "Moves money: locks the task amount in USDC escrow subject to the acting wallet's policy and daily cap. MCP cannot grant human approval; amounts above the approval threshold are refused with approval:true.",
92115
- moneyParticipant
92416
+ "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.",
92417
+ { ...moneyParticipant, wait: waitForIndexer }
92116
92418
  );
92117
92419
  var tasksDeliverTool = descriptor(
92118
- "Does not move money. Upload local delivery files, freeze the manifest and record delivery with the local vault wallet.",
92420
+ "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.",
92119
92421
  {
92120
92422
  ...moneyParticipant,
92423
+ wait: waitForIndexer,
92121
92424
  files: external_exports.array(localPath).min(TASK_LIMITS.deliveryFilesMin).max(TASK_LIMITS.deliveryFilesMax),
92122
92425
  note: external_exports.string().max(TASK_LIMITS.deliveryNoteMax).refine((value) => value.trim().length > 0)
92123
92426
  }
92124
92427
  );
92125
92428
  var tasksReleaseTool = descriptor(
92126
- "Moves money: pays the worker from escrow with the local vault wallet. Returns gross \xB7 fee \xB7 net using the deployed fee.",
92127
- moneyParticipant
92429
+ "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.",
92430
+ { ...moneyParticipant, wait: waitForIndexer }
92128
92431
  );
92129
92432
  var tasksRefundTool = descriptor(
92130
- "Moves money: returns escrowed USDC to the poster with the local vault wallet. Returns gross \xB7 fee \xB7 net using the deployed fee.",
92433
+ "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.",
92131
92434
  moneyParticipant
92132
92435
  );
92133
92436
  var tasksDisputeTool = descriptor(
92134
- "Moves money: approves the verified dispute fee and raises a dispute with the local vault wallet. Applies task and daily caps; MCP refuses human approval with approval:true. Accepts a precomputed evidence hash.",
92437
+ "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.",
92135
92438
  {
92136
92439
  ...moneyParticipant,
92137
92440
  evidenceHash: external_exports.string().regex(TASK_LIMITS.disputeEvidenceHash)
92138
92441
  }
92139
92442
  );
92140
92443
  var tasksCounterEvidenceTool = descriptor(
92141
- "Moves money: approves the verified dispute fee and submits counter-evidence as the non-opener before the onchain deadline. Applies task and daily caps; MCP refuses human approval with approval:true.",
92444
+ "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.",
92142
92445
  { ...moneyParticipant, evidenceHash: external_exports.string().regex(TASK_LIMITS.disputeEvidenceHash) }
92143
92446
  );
92144
92447
  var tasksResolveUnmatchedTool = descriptor(
92145
- "Moves money: resolves an unmatched dispute after the onchain counter-evidence deadline when no counter-evidence was submitted.",
92448
+ "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.",
92146
92449
  moneyParticipant
92147
92450
  );
92148
92451
  var tasksMessageTool = descriptor(
@@ -92166,8 +92469,8 @@ var tasksWatchTool = descriptor(
92166
92469
  }
92167
92470
  );
92168
92471
  var tasksStatusTool = descriptor(
92169
- "Does not move money. Read the public task card and receipt URL when settled; sign-in is not required.",
92170
- { id }
92472
+ "Does not move money. Read signed-in chain state and participant events, or the public task card without sign-in.",
92473
+ participant
92171
92474
  );
92172
92475
  var signInHint = "Call auth.link for the acting wallet.";
92173
92476
  function lazyTasksChain(factory, pending) {
@@ -92307,6 +92610,22 @@ function createTasksTools(options) {
92307
92610
  };
92308
92611
  };
92309
92612
  }
92613
+ async function waitAfterChain(ctx, orderId, milestoneId, target) {
92614
+ return await taskRequest(
92615
+ target,
92616
+ "getOrder",
92617
+ () => waitForMilestone(ctx.client, {
92618
+ orderId,
92619
+ milestoneId,
92620
+ target,
92621
+ timeoutMs: 6e4,
92622
+ intervalMs: 3e3,
92623
+ ...options.sleep === void 0 ? {} : { sleep: options.sleep },
92624
+ now
92625
+ }),
92626
+ ctx
92627
+ );
92628
+ }
92310
92629
  async function feeAction(verb, input2) {
92311
92630
  const ctx = await acting(input2.wallet);
92312
92631
  const policy = await taskPolicyForWallet({
@@ -92349,7 +92668,12 @@ function createTasksTools(options) {
92349
92668
  throw new TaskInputError("deadline must be at least 10 minutes from now.");
92350
92669
  const ctx = await acting(input2.wallet);
92351
92670
  const outcome = await postTask(ctx, {
92352
- order: { title: input2.title, description: input2.brief, policyFamily: "general-digital" },
92671
+ order: {
92672
+ title: input2.title,
92673
+ description: input2.brief,
92674
+ policyFamily: "general-digital",
92675
+ ...input2.vendor === void 0 ? {} : { invitedProviderAddress: input2.vendor }
92676
+ },
92353
92677
  amount: parseUsdToBaseUnits(input2.amountUsd),
92354
92678
  deadlineAt: new Date(postedAt.getTime() + deadlineDuration).toISOString(),
92355
92679
  ...input2.intake === void 0 ? {} : { intake: input2.intake },
@@ -92407,15 +92731,15 @@ function createTasksTools(options) {
92407
92731
  const ctx = await acting(input2.wallet);
92408
92732
  const signerAddress = (await options.session.addressesFor(ctx.selected.name)).address;
92409
92733
  try {
92410
- return taskResult(
92411
- await signTaskScope(ctx, {
92412
- id: input2.id,
92413
- counterparty: input2.counterparty,
92414
- signerAddress,
92415
- bindings: createScopeBindings(home),
92416
- signMessage: async (message) => (await unlock(ctx.selected.name)()).signMessage(message)
92417
- })
92418
- );
92734
+ const outcome = await signTaskScope(ctx, {
92735
+ id: input2.id,
92736
+ counterparty: input2.counterparty,
92737
+ signerAddress,
92738
+ bindings: createScopeBindings(home),
92739
+ signMessage: async (message) => (await unlock(ctx.selected.name)()).signMessage(message)
92740
+ });
92741
+ const wait2 = input2.wait && outcome.escrowCreation ? await waitAfterChain(ctx, input2.id, outcome.escrowCreation.milestone.id, "created") : null;
92742
+ return taskResult({ ...outcome, wait: wait2 });
92419
92743
  } catch (error61) {
92420
92744
  if (!(error61 instanceof TasksScopeCreationError)) throw error61;
92421
92745
  try {
@@ -92451,28 +92775,31 @@ function createTasksTools(options) {
92451
92775
  // Stdio has no human approval channel. Model arguments cannot grant approval.
92452
92776
  approval: { granted: false }
92453
92777
  });
92454
- return taskResult(outcome, !outcome.ok);
92778
+ const wait2 = input2.wait && outcome.ok ? await waitAfterChain(ctx, input2.id, outcome.result.milestone.id, "locked") : null;
92779
+ return taskResult({ ...outcome, wait: wait2 }, !outcome.ok);
92455
92780
  },
92456
92781
  async deliver(input2) {
92457
92782
  const files = (await Promise.all(input2.files.map(readTaskFile))).map(
92458
92783
  ({ fileName: name, bytes, contentType }) => ({ name, bytes, contentType })
92459
92784
  );
92460
- return taskResult(
92461
- await deliverTaskOperation(await acting(input2.wallet), {
92462
- id: input2.id,
92463
- ...input2.counterparty === void 0 ? {} : { counterparty: input2.counterparty },
92464
- files,
92465
- note: input2.note
92466
- })
92467
- );
92785
+ const ctx = await acting(input2.wallet);
92786
+ const outcome = await deliverTaskOperation(ctx, {
92787
+ id: input2.id,
92788
+ ...input2.counterparty === void 0 ? {} : { counterparty: input2.counterparty },
92789
+ files,
92790
+ note: input2.note
92791
+ });
92792
+ const wait2 = input2.wait ? await waitAfterChain(ctx, input2.id, outcome.result.milestone.id, "delivered") : null;
92793
+ return taskResult({ ...outcome, wait: wait2 });
92468
92794
  },
92469
92795
  async release(input2) {
92470
- return taskResult(
92471
- await releaseTaskOperation(await acting(input2.wallet), {
92472
- id: input2.id,
92473
- ...input2.counterparty === void 0 ? {} : { counterparty: input2.counterparty }
92474
- })
92475
- );
92796
+ const ctx = await acting(input2.wallet);
92797
+ const outcome = await releaseTaskOperation(ctx, {
92798
+ id: input2.id,
92799
+ ...input2.counterparty === void 0 ? {} : { counterparty: input2.counterparty }
92800
+ });
92801
+ const wait2 = input2.wait ? await waitAfterChain(ctx, input2.id, outcome.result.milestone.id, "released") : null;
92802
+ return taskResult({ ...outcome, wait: wait2 });
92476
92803
  },
92477
92804
  async refund(input2) {
92478
92805
  return taskResult(
@@ -92539,7 +92866,11 @@ function createTasksTools(options) {
92539
92866
  }
92540
92867
  },
92541
92868
  async status(input2) {
92542
- return taskResult(await taskStatus(await context(void 0, true), { id: input2.id }));
92869
+ await options.wallets?.reload();
92870
+ const publicOnly = input2.wallet === void 0 && options.session.activeName === void 0 && options.wallets !== void 0 && options.wallets.names().length === 0;
92871
+ const candidate = await context(input2.wallet, publicOnly);
92872
+ const ctx = candidate.token || publicOnly ? candidate : await context(void 0, true);
92873
+ return taskResult(await taskStatus(ctx, { id: input2.id, signedIn: Boolean(ctx.token) }));
92543
92874
  }
92544
92875
  };
92545
92876
  }
@@ -93296,6 +93627,11 @@ var statsToolResultSchema = external_exports.object({
93296
93627
  )
93297
93628
  })
93298
93629
  });
93630
+ function objectOutputSchema(schema) {
93631
+ if (!schema) return {};
93632
+ const json2 = external_exports.toJSONSchema(schema);
93633
+ return json2.type === "object" ? { outputSchema: json2 } : {};
93634
+ }
93299
93635
  var VapiMcpServer = class {
93300
93636
  #tools = /* @__PURE__ */ new Map();
93301
93637
  #onClose;
@@ -93319,7 +93655,7 @@ var VapiMcpServer = class {
93319
93655
  name,
93320
93656
  ...tool.description ? { description: tool.description } : {},
93321
93657
  inputSchema: external_exports.toJSONSchema(tool.inputSchema),
93322
- ...tool.outputSchema ? { outputSchema: external_exports.toJSONSchema(tool.outputSchema) } : {}
93658
+ ...objectOutputSchema(tool.outputSchema)
93323
93659
  }))
93324
93660
  };
93325
93661
  }
@@ -97681,7 +98017,7 @@ async function readProcessStdin() {
97681
98017
  }
97682
98018
 
97683
98019
  // src/version.ts
97684
- var CLI_VERSION = "0.9.0";
98020
+ var CLI_VERSION = "0.9.2";
97685
98021
 
97686
98022
  // src/status.ts
97687
98023
  async function statusCommand(argv, json2, io, dependencies) {
@@ -102630,10 +102966,10 @@ var TASK_HELP = `Usage:
102630
102966
  vapi task propose <id> --price <usd> --duration <duration> --note <text> [--account <name>] [--json]
102631
102967
  vapi task submit <id> --proof <https-url> [--proof <https-url>...] [--file <path>...] [--account <name>] [--json]
102632
102968
  vapi task award <id> <proposalId> [--account <name>] [--json]
102633
- vapi task sign <id> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
102634
- vapi task fund <id> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
102635
- vapi task deliver <id> --files <path...> --note <text> [--counterparty <0x\u2026>] [--account <name>] [--json]
102636
- vapi task release <id> [--counterparty <0x\u2026>] [--account <name>] [--json]
102969
+ vapi task sign <id> [--yes] [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
102970
+ vapi task fund <id> [--yes] [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
102971
+ vapi task deliver <id> --files <path...> --note <text> [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
102972
+ vapi task release <id> [--no-wait] [--timeout 120s] [--counterparty <0x\u2026>] [--account <name>] [--json]
102637
102973
  vapi task refund <id> [--counterparty <0x\u2026>] [--account <name>] [--json]
102638
102974
  vapi task dispute <id> --evidence-hash <0x + 64 hex> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
102639
102975
  vapi task counter-evidence <id> --evidence-hash <0x + 64 hex> [--yes] [--counterparty <0x\u2026>] [--account <name>] [--json]
@@ -102656,23 +102992,25 @@ Exit codes:
102656
102992
  2 policy refusal only (JSON ok:false with reason policy.perTask or policy.perDay)
102657
102993
  3 approval needed in non-interactive mode
102658
102994
 
102659
- 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.`;
102995
+ 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.`;
102660
102996
  var IMPLEMENTED_VERBS = TASKS_CLIENT_VERBS;
102661
102997
  var USAGE = `Usage: vapi task <${IMPLEMENTED_VERBS.join("|")}>. Run vapi task --help.`;
102662
102998
  var TaskCommandError = class extends Error {
102663
- constructor(code, message, manifestHash) {
102999
+ constructor(code, message, manifestHash, prefixCode = false) {
102664
103000
  super(message);
102665
103001
  this.code = code;
102666
103002
  this.manifestHash = manifestHash;
103003
+ this.prefixCode = prefixCode;
102667
103004
  this.name = "TaskCommandError";
102668
103005
  }
102669
103006
  code;
102670
103007
  manifestHash;
103008
+ prefixCode;
102671
103009
  };
102672
103010
  function mapTaskError(error61) {
102673
103011
  if (error61 instanceof TaskInputError) return new UsageError(error61.message);
102674
103012
  if (error61 instanceof TaskOperationError)
102675
- return new TaskCommandError(error61.code, error61.message, error61.manifestHash);
103013
+ return new TaskCommandError(error61.code, error61.message, error61.manifestHash, true);
102676
103014
  return error61;
102677
103015
  }
102678
103016
  async function mapped(operation) {
@@ -102891,11 +103229,13 @@ async function taskCommandInner(argv, json2, io, dependencies) {
102891
103229
  "--intake",
102892
103230
  "--max-awards",
102893
103231
  "--webhook"
102894
- ] : 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"] : []
103232
+ ] : 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"] : [],
103233
+ ...["sign", "fund", "deliver", "release"].includes(verb) ? ["--timeout"] : []
102895
103234
  ]),
102896
103235
  booleanOptions: /* @__PURE__ */ new Set([
102897
103236
  ...verb === "search" ? ["--open"] : [],
102898
103237
  ...["sign", "fund", "dispute", "counter-evidence"].includes(verb) ? ["--yes"] : [],
103238
+ ...["sign", "fund", "deliver", "release"].includes(verb) ? ["--no-wait"] : [],
102899
103239
  ...verb === "watch" ? ["--auto-release"] : []
102900
103240
  ]),
102901
103241
  repeatableOptions: /* @__PURE__ */ new Set([
@@ -103051,7 +103391,7 @@ async function taskCommandInner(argv, json2, io, dependencies) {
103051
103391
  throw new UsageError("message needs text between 1 and 10000 characters.");
103052
103392
  }
103053
103393
  if (verb === "thread") cursor2 = optionalInteger(parsed.one("--after"), "--after");
103054
- const context = await taskContext(parsed, io, dependencies, verb === "status");
103394
+ const context = await taskContext(parsed, io, dependencies);
103055
103395
  if (verb === "show" || verb === "status") {
103056
103396
  if (verb === "show" && context.token) {
103057
103397
  const result = await showTask(context, { id: id2, signedIn: true });
@@ -103061,7 +103401,21 @@ async function taskCommandInner(argv, json2, io, dependencies) {
103061
103401
  ...receipts.map((receipt) => `Receipt (from escrow): ${receipt.receiptUrl}`)
103062
103402
  ]);
103063
103403
  } else {
103064
- const result = verb === "status" ? await taskStatus(context, { id: id2 }) : await showTask(context, { id: id2, signedIn: false });
103404
+ const result = verb === "status" ? await taskStatus(context, { id: id2, signedIn: Boolean(context.token) }) : await showTask(context, { id: id2, signedIn: false });
103405
+ if ("chainState" in result) {
103406
+ const milestoneLines = result.chainState.milestones.map((milestone) => {
103407
+ const ordinal = "ordinal" in milestone && typeof milestone.ordinal === "number" && Number.isFinite(milestone.ordinal) ? milestone.ordinal : milestone.milestoneId;
103408
+ const state = "state" in milestone.read ? ` ${milestone.read.state}` : "";
103409
+ const explorer = milestone.explorerUrl ? ` ${milestone.explorerUrl}` : "";
103410
+ return `milestone ${ordinal}: ${milestone.read.status}${state}${explorer}`;
103411
+ });
103412
+ const eventLines = (result.events ?? []).slice(-10).map((event) => {
103413
+ const createdAt = "createdAt" in event && typeof event.createdAt === "string" ? event.createdAt : event.at;
103414
+ return `${event.sequence} ${event.type} ${createdAt}`;
103415
+ });
103416
+ taskOutput(io, json2, context, verb, result, [...milestoneLines, ...eventLines]);
103417
+ return;
103418
+ }
103065
103419
  const task = result.task;
103066
103420
  taskOutput(
103067
103421
  io,
@@ -103105,6 +103459,11 @@ async function taskCommandInner(argv, json2, io, dependencies) {
103105
103459
  async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now) {
103106
103460
  taskCounterparty(parsed);
103107
103461
  if (verb === "watch") return await watchTask(id2, parsed, json2, io, dependencies, now);
103462
+ const waitsForIndex = ["sign", "fund", "deliver", "release"].includes(verb);
103463
+ const waitTimeoutText = parsed.one("--timeout") ?? "120s";
103464
+ const waitTimeoutMs = waitsForIndex ? parseTaskDuration2(waitTimeoutText, now) : void 0;
103465
+ if (waitTimeoutMs !== void 0 && waitTimeoutMs <= 0)
103466
+ throw new UsageError("--timeout must be positive.");
103108
103467
  const disputeEvidenceHash = ["dispute", "counter-evidence"].includes(verb) ? required3(parsed, "--evidence-hash") : void 0;
103109
103468
  const counterparty = taskCounterparty(parsed);
103110
103469
  if (disputeEvidenceHash !== void 0 && !TASK_LIMITS.disputeEvidenceHash.test(disputeEvidenceHash))
@@ -103154,9 +103513,24 @@ async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now
103154
103513
  return await account.signMessage({ message });
103155
103514
  }
103156
103515
  });
103157
- taskOutput(io, json2, displayContext, verb, result2, [
103516
+ if (!json2 && result2.escrowCreation?.resumedFromServer)
103517
+ io.stdout("The server had already prepared escrow creation; resumed from it.");
103518
+ const wait3 = result2.escrowCreation ? await waitForTaskIndex(
103519
+ context,
103520
+ dependencies,
103521
+ parsed,
103522
+ json2,
103523
+ io,
103524
+ id2,
103525
+ result2.escrowCreation,
103526
+ "created",
103527
+ "escrow creation",
103528
+ waitTimeoutText,
103529
+ waitTimeoutMs
103530
+ ) : null;
103531
+ taskOutput(io, json2, displayContext, verb, { ...result2, wait: wait3 }, [
103158
103532
  `Accepted scope for task ${id2}.`,
103159
- ...result2.escrowCreation ? ["Created the task escrow."] : []
103533
+ ...result2.escrowCreation && (wait3 === null || wait3.reached) ? ["escrow created"] : []
103160
103534
  ]);
103161
103535
  return;
103162
103536
  } catch (error61) {
@@ -103190,7 +103564,23 @@ async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now
103190
103564
  taskOutput(io, false, context, verb, {}, [`Prepared delivery manifest ${manifestHash}.`]);
103191
103565
  }
103192
103566
  });
103193
- taskOutput(io, json2, context, verb, outcome, [`Delivered task ${id2}.`]);
103567
+ const wait3 = await waitForTaskIndex(
103568
+ context,
103569
+ dependencies,
103570
+ parsed,
103571
+ json2,
103572
+ io,
103573
+ id2,
103574
+ outcome.result,
103575
+ "delivered",
103576
+ "delivery",
103577
+ waitTimeoutText,
103578
+ waitTimeoutMs
103579
+ );
103580
+ taskOutput(io, json2, context, verb, { ...outcome, wait: wait3 }, [
103581
+ ...wait3 === null || wait3.reached ? ["delivery recorded"] : [],
103582
+ ...outcome.result.resumedFromServer === true ? ["The server had already recorded this delivery; resumed from it."] : []
103583
+ ]);
103194
103584
  return;
103195
103585
  }
103196
103586
  const snapshot = await taskMoneySnapshot(context.client, id2, void 0, {
@@ -103253,15 +103643,82 @@ async function escrowTaskCommand(verb, id2, parsed, json2, io, dependencies, now
103253
103643
  }
103254
103644
  if (!outcome.ok && "declined" in outcome)
103255
103645
  throw new TaskCommandError("not_approved", "Not approved; nothing was signed.");
103256
- taskOutput(io, json2, context, verb, outcome, [
103257
- verb === "fund" ? `Funded task ${id2}.` : `Completed task ${verb} for ${id2}.`
103258
- ]);
103646
+ if (!json2 && outcome.result.resumedFromServer)
103647
+ io.stdout("The server had already prepared this task operation; resumed from it.");
103648
+ const wait3 = verb === "fund" ? await waitForTaskIndex(
103649
+ context,
103650
+ dependencies,
103651
+ parsed,
103652
+ json2,
103653
+ io,
103654
+ id2,
103655
+ outcome.result,
103656
+ "locked",
103657
+ "funding",
103658
+ waitTimeoutText,
103659
+ waitTimeoutMs
103660
+ ) : void 0;
103661
+ taskOutput(
103662
+ io,
103663
+ json2,
103664
+ context,
103665
+ verb,
103666
+ wait3 === void 0 ? outcome : { ...outcome, wait: wait3 },
103667
+ verb === "fund" ? wait3 === null || wait3?.reached ? ["escrow funded"] : [] : [`Completed task ${verb} for ${id2}.`]
103668
+ );
103259
103669
  return;
103260
103670
  }
103261
103671
  if (!json2) io.stdout("Policy: explicit user instruction.");
103262
103672
  const settlementInput = { id: id2, snapshot, ...counterparty === void 0 ? {} : { counterparty } };
103263
103673
  const result = verb === "release" ? await releaseTaskOperation(context, settlementInput) : verb === "refund" ? await refundTaskOperation(context, settlementInput) : await resolveUnmatchedTaskOperation(context, settlementInput);
103264
- taskOutput(io, json2, context, verb, result, [`Completed task ${verb} for ${id2}.`]);
103674
+ if (!json2 && result.result.resumedFromServer)
103675
+ io.stdout("The server had already prepared this task operation; resumed from it.");
103676
+ const wait2 = verb === "release" ? await waitForTaskIndex(
103677
+ context,
103678
+ dependencies,
103679
+ parsed,
103680
+ json2,
103681
+ io,
103682
+ id2,
103683
+ result.result,
103684
+ "released",
103685
+ "release",
103686
+ waitTimeoutText,
103687
+ waitTimeoutMs
103688
+ ) : void 0;
103689
+ taskOutput(
103690
+ io,
103691
+ json2,
103692
+ context,
103693
+ verb,
103694
+ wait2 === void 0 ? result : { ...result, wait: wait2 },
103695
+ verb === "release" ? wait2 === null || wait2?.reached ? ["funds released"] : [] : [`Completed task ${verb} for ${id2}.`]
103696
+ );
103697
+ }
103698
+ async function waitForTaskIndex(context, dependencies, parsed, json2, io, orderId, result, target, description, timeoutText, timeoutMs) {
103699
+ if (parsed.has("--no-wait")) return null;
103700
+ if (!json2)
103701
+ io.stdout(
103702
+ `confirmed on chain${result.blockNumber === void 0 ? "" : ` in block ${result.blockNumber}`}, waiting for vAPI to index\u2026`
103703
+ );
103704
+ const wait2 = await taskRequest2(
103705
+ description,
103706
+ "getOrder",
103707
+ () => waitForMilestone(context.client, {
103708
+ orderId,
103709
+ milestoneId: result.milestone.id,
103710
+ target,
103711
+ timeoutMs,
103712
+ intervalMs: 3e3,
103713
+ sleep: context.sleep,
103714
+ now: dependencies.now ?? (() => /* @__PURE__ */ new Date())
103715
+ })
103716
+ );
103717
+ if (!wait2.reached)
103718
+ io.stderr(
103719
+ `vAPI has not indexed the ${description} yet after ${timeoutText}; run vapi task status ${orderId} later.`
103720
+ );
103721
+ return wait2;
103265
103722
  }
103266
103723
  var ScopeApprovalNeeded = class extends Error {
103267
103724
  constructor(terms) {
@@ -105193,6 +105650,7 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
105193
105650
  error: message,
105194
105651
  exitCode: code,
105195
105652
  ...error61 instanceof RuntimeError ? { code: error61.code } : {},
105653
+ ...error61 instanceof VapiCallError ? { code: error61.code } : {},
105196
105654
  ...error61 instanceof DocsError ? { code: error61.code } : {},
105197
105655
  ...error61 instanceof RemoteKeyRefusedError ? { code: error61.code } : {},
105198
105656
  ...error61 instanceof TransferError ? { code: error61.code, moneyMoved: error61.moneyMoved } : {}
@@ -105200,7 +105658,10 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
105200
105658
  );
105201
105659
  }
105202
105660
  } else {
105203
- runIo.stderr(message);
105661
+ const errorCode2 = taskInvocation && error61 instanceof TaskCommandError && error61.prefixCode ? errorCodeOf(error61) : void 0;
105662
+ runIo.stderr(
105663
+ errorCode2 !== void 0 && !message.startsWith(`${errorCode2}: `) ? `${errorCode2}: ${message}` : message
105664
+ );
105204
105665
  }
105205
105666
  if (shouldAutoUploadAfterFailure(argv.filter((argument) => argument !== "--json"))) {
105206
105667
  await autoUploadBackup(io, json2, dependencies);