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