@elsoul/erpc-sdk 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -9,11 +9,88 @@ var credentialVariants = (credential) => {
9
9
  componentEncoded = encodeURIComponent(credential);
10
10
  } catch {
11
11
  }
12
- return [.../* @__PURE__ */ new Set([credential, componentEncoded, queryEncoded])].filter((value) => Boolean(value)).sort((left, right) => right.length - left.length);
12
+ return [
13
+ .../* @__PURE__ */ new Set([
14
+ credential,
15
+ componentEncoded,
16
+ queryEncoded
17
+ ])
18
+ ].filter((value) => Boolean(value)).sort((left, right) => right.length - left.length);
19
+ };
20
+ var directEndpointVariants = (endpoint) => {
21
+ const values = [];
22
+ const add = (value) => {
23
+ if (value) values.push(value);
24
+ };
25
+ for (const value of endpoint.searchParams.values()) add(value);
26
+ const rawQuery = endpoint.search.startsWith("?") ? endpoint.search.slice(1) : endpoint.search;
27
+ for (const part of rawQuery.split("&")) {
28
+ const separator = part.indexOf("=");
29
+ const rawValue = separator === -1 ? "" : part.slice(separator + 1);
30
+ add(rawValue);
31
+ if (rawValue) {
32
+ try {
33
+ add(decodeURIComponent(rawValue.replaceAll("+", " ")));
34
+ } catch {
35
+ }
36
+ }
37
+ }
38
+ return values;
39
+ };
40
+ var headerVariants = (headers) => {
41
+ const values = [];
42
+ for (const [name, value] of Object.entries(headers)) {
43
+ values.push(value);
44
+ if (name.toLowerCase() !== "authorization" && name.toLowerCase() !== "proxy-authorization") continue;
45
+ const match = /^\s*[^\s]+\s+(.+?)\s*$/u.exec(value);
46
+ if (match?.[1]) values.push(match[1]);
47
+ if (match?.[1] && /^basic$/iu.test(value.trim().split(/\s+/u, 1)[0] ?? "")) {
48
+ try {
49
+ const decoded = globalThis.atob(match[1]);
50
+ values.push(decoded);
51
+ const separator = decoded.indexOf(":");
52
+ if (separator !== -1) {
53
+ values.push(decoded.slice(0, separator), decoded.slice(separator + 1));
54
+ }
55
+ } catch {
56
+ }
57
+ }
58
+ }
59
+ return values;
60
+ };
61
+ var directRedactionVariants = (endpoint, headers = {}) => [.../* @__PURE__ */ new Set([...directEndpointVariants(endpoint), ...headerVariants(headers)])].flatMap((value) => credentialVariants(value)).filter((value, index, all) => all.indexOf(value) === index).sort((left, right) => right.length - left.length);
62
+ var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
63
+ var hexCharacterPattern = (value) => {
64
+ const lower = value.toLowerCase();
65
+ const upper = value.toUpperCase();
66
+ if (lower === upper) return escapeRegex(value);
67
+ return `[${lower}${upper}]`;
68
+ };
69
+ var percentTripletPattern = (value) => {
70
+ const pattern = /%([0-9a-f])([0-9a-f])/giu;
71
+ let result = "";
72
+ let offset = 0;
73
+ for (const match of value.matchAll(pattern)) {
74
+ const index = match.index ?? 0;
75
+ result += escapeRegex(value.slice(offset, index));
76
+ result += `%${hexCharacterPattern(match[1] ?? "")}${hexCharacterPattern(
77
+ match[2] ?? ""
78
+ )}`;
79
+ offset = index + match[0].length;
80
+ }
81
+ return result + escapeRegex(value.slice(offset));
13
82
  };
14
83
  var redactString = (value, variants) => {
15
84
  let redacted = value;
16
- for (const variant of variants) redacted = redacted.replaceAll(variant, REDACTED);
85
+ for (const variant of variants) {
86
+ if (!variant) continue;
87
+ const pattern = percentTripletPattern(variant);
88
+ if (pattern === escapeRegex(variant)) {
89
+ redacted = redacted.replaceAll(variant, REDACTED);
90
+ } else {
91
+ redacted = redacted.replace(new RegExp(pattern, "gu"), REDACTED);
92
+ }
93
+ }
17
94
  return redacted;
18
95
  };
19
96
  var redactValue = (value, variants, seen, depth) => {
@@ -26,7 +103,7 @@ var redactValue = (value, variants, seen, depth) => {
26
103
  }
27
104
  const result = {};
28
105
  for (const [key, item] of Object.entries(value)) {
29
- Object.defineProperty(result, key, {
106
+ Object.defineProperty(result, redactString(key, variants), {
30
107
  configurable: true,
31
108
  enumerable: true,
32
109
  value: redactValue(item, variants, seen, depth + 1),
@@ -35,9 +112,12 @@ var redactValue = (value, variants, seen, depth) => {
35
112
  }
36
113
  return result;
37
114
  };
38
- var redactJsonRpcError = (error, credential) => {
39
- if (!credential) return error;
40
- const variants = credentialVariants(credential);
115
+ var redactJsonRpcError = (error, credential, additionalCredentials = []) => {
116
+ const variants = [.../* @__PURE__ */ new Set([
117
+ ...credential ? credentialVariants(credential) : [],
118
+ ...additionalCredentials
119
+ ])].sort((left, right) => right.length - left.length);
120
+ if (variants.length === 0) return error;
41
121
  const result = {
42
122
  code: error.code,
43
123
  message: redactString(error.message, variants)
@@ -61,6 +141,14 @@ var ErpcConfigError = class extends ErpcError {
61
141
  this.name = "ErpcConfigError";
62
142
  }
63
143
  };
144
+ var ErpcNotConfiguredError = class extends ErpcError {
145
+ namespace;
146
+ constructor(namespace) {
147
+ super("ERPC_NOT_CONFIGURED", `ERPC namespace '${namespace}' is not configured`);
148
+ this.name = "ErpcNotConfiguredError";
149
+ this.namespace = namespace;
150
+ }
151
+ };
64
152
  var ErpcTransportError = class extends ErpcError {
65
153
  constructor(message, options) {
66
154
  super("ERPC_TRANSPORT", message, options);
@@ -167,12 +255,14 @@ var RestTransport = class {
167
255
  #fetch;
168
256
  #headers;
169
257
  #timeoutMs;
258
+ #unavailableNamespace;
170
259
  constructor(config) {
171
- this.#apiKey = config.apiKey;
260
+ this.#apiKey = config.apiKey ?? "";
172
261
  this.#endpoint = new URL(config.endpoint);
173
262
  this.#fetch = config.fetch;
174
263
  this.#headers = config.headers;
175
264
  this.#timeoutMs = config.timeoutMs;
265
+ this.#unavailableNamespace = config.unavailableNamespace;
176
266
  const endpoint = new URL(config.endpoint);
177
267
  endpoint.search = "";
178
268
  endpoint.hash = "";
@@ -186,6 +276,9 @@ var RestTransport = class {
186
276
  return url;
187
277
  }
188
278
  async get(path, query, options = {}) {
279
+ if (this.#unavailableNamespace !== void 0) {
280
+ throw new ErpcNotConfiguredError(this.#unavailableNamespace);
281
+ }
189
282
  const controlled = controlledSignal(this.#timeoutMs, options.signal);
190
283
  try {
191
284
  const response = await this.#get(path, query, controlled.signal);
@@ -203,6 +296,9 @@ var RestTransport = class {
203
296
  }
204
297
  }
205
298
  async stream(path, query, options = {}) {
299
+ if (this.#unavailableNamespace !== void 0) {
300
+ throw new ErpcNotConfiguredError(this.#unavailableNamespace);
301
+ }
206
302
  const controlled = controlledSignal(this.#timeoutMs, options.signal);
207
303
  try {
208
304
  const response = await this.#get(path, query, controlled.signal);
@@ -219,13 +315,16 @@ var RestTransport = class {
219
315
  }
220
316
  }
221
317
  #get(path, query, signal) {
318
+ const headers = {
319
+ ...this.#headers,
320
+ accept: "application/json"
321
+ };
322
+ if (this.#unavailableNamespace === void 0) {
323
+ headers.authorization = `Bearer ${this.#apiKey}`;
324
+ }
222
325
  return this.#fetch(this.url(path, query), {
223
326
  method: "GET",
224
- headers: {
225
- ...this.#headers,
226
- authorization: `Bearer ${this.#apiKey}`,
227
- accept: "application/json"
228
- },
327
+ headers,
229
328
  signal
230
329
  });
231
330
  }
@@ -2434,6 +2533,9 @@ var CloudCatalogClient = class {
2434
2533
  }
2435
2534
  };
2436
2535
 
2536
+ // src/transport/fetch.ts
2537
+ var wrapFetch = (implementation) => (input, init) => implementation(input, init);
2538
+
2437
2539
  // src/config.ts
2438
2540
  var DEFAULT_ENDPOINT = "https://edge.erpc.global";
2439
2541
  var DEFAULT_AVALANCHE_ENDPOINT = "https://ava-rpc.erpc.global";
@@ -2447,24 +2549,99 @@ var requireFetch = (provided) => {
2447
2549
  "A Fetch API implementation is required in this runtime"
2448
2550
  );
2449
2551
  }
2450
- return implementation;
2552
+ return wrapFetch(implementation);
2553
+ };
2554
+ var normalizeLegacyEndpoint = (endpoint) => {
2555
+ endpoint.search = "";
2556
+ endpoint.hash = "";
2557
+ endpoint.pathname = endpoint.pathname.replace(/\/+$/, "") || "/";
2558
+ return endpoint;
2559
+ };
2560
+ var explicitAuthority = (value) => /^[a-z][a-z\d+.-]*:\/\//iu.test(value);
2561
+ var hasUserInfo = (value) => {
2562
+ const separator = value.indexOf("://");
2563
+ if (separator === -1) return false;
2564
+ const authorityAndPath = value.slice(separator + 3);
2565
+ const authority = authorityAndPath.split(/[/?#]/u, 1)[0] ?? "";
2566
+ return authority.length === 0 || authority.includes("@");
2567
+ };
2568
+ var parseDirectUrl = (value, namespace, kind) => {
2569
+ if (typeof value !== "string") {
2570
+ throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
2571
+ }
2572
+ const input = value.trim();
2573
+ if (!input || !explicitAuthority(input) || input.includes("#") || hasUserInfo(input)) {
2574
+ throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
2575
+ }
2576
+ let url;
2577
+ try {
2578
+ url = new URL(input);
2579
+ } catch {
2580
+ throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
2581
+ }
2582
+ const allowed = kind === "HTTP(S)" ? url.protocol === "http:" || url.protocol === "https:" : url.protocol === "ws:" || url.protocol === "wss:";
2583
+ if (!allowed || !url.hostname || url.username || url.password) {
2584
+ throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
2585
+ }
2586
+ return url;
2587
+ };
2588
+ var directHeaders = (value, namespace) => {
2589
+ if (value === void 0) return {};
2590
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2591
+ throw new ErpcConfigError(`${namespace} headers must be string values`);
2592
+ }
2593
+ const result = {};
2594
+ for (const [name, header] of Object.entries(value)) {
2595
+ if (typeof header !== "string") {
2596
+ throw new ErpcConfigError(`${namespace} headers must be string values`);
2597
+ }
2598
+ result[name] = header;
2599
+ }
2600
+ return Object.freeze(result);
2601
+ };
2602
+ var resolveRpcEndpoint = (value, namespace) => {
2603
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2604
+ throw new ErpcConfigError(`${namespace} must define an HTTP(S) URL`);
2605
+ }
2606
+ const config = value;
2607
+ const httpUrl = parseDirectUrl(config.httpUrl, `${namespace}.httpUrl`, "HTTP(S)");
2608
+ const webSocketUrl = config.webSocketUrl === void 0 ? void 0 : parseDirectUrl(
2609
+ config.webSocketUrl,
2610
+ `${namespace}.webSocketUrl`,
2611
+ "WS(S)"
2612
+ );
2613
+ const headers = directHeaders(config.headers, namespace);
2614
+ return {
2615
+ headers,
2616
+ httpUrl,
2617
+ ...webSocketUrl === void 0 ? {} : { webSocketUrl }
2618
+ };
2451
2619
  };
2452
2620
  var resolveConfig = (config) => {
2453
- const apiKey = config.apiKey.trim();
2454
- if (!apiKey) throw new ErpcConfigError("apiKey must not be empty");
2621
+ const configuredApiKey = config.apiKey === void 0 ? void 0 : typeof config.apiKey === "string" ? config.apiKey.trim() : (() => {
2622
+ throw new ErpcConfigError("apiKey must be a string");
2623
+ })();
2624
+ const solanaRpc = config.solanaRpc === void 0 ? void 0 : resolveRpcEndpoint(config.solanaRpc, "solanaRpc");
2625
+ const ethereumRpc = config.ethereumRpc === void 0 ? void 0 : resolveRpcEndpoint(config.ethereumRpc, "ethereumRpc");
2626
+ const avalancheCRpc = config.avalancheCRpc === void 0 ? void 0 : resolveRpcEndpoint(config.avalancheCRpc, "avalancheCRpc");
2627
+ const hasDirectRpc = solanaRpc !== void 0 || ethereumRpc !== void 0 || avalancheCRpc !== void 0;
2628
+ if (!configuredApiKey && !hasDirectRpc) {
2629
+ throw new ErpcConfigError("apiKey must not be empty");
2630
+ }
2631
+ const apiKey = configuredApiKey || void 0;
2455
2632
  let endpoint;
2456
2633
  let avalancheEndpoint;
2457
2634
  let accountEndpoint;
2458
2635
  let userEndpoint;
2459
2636
  try {
2460
- endpoint = new URL(config.endpoint ?? DEFAULT_ENDPOINT);
2461
- avalancheEndpoint = new URL(
2637
+ endpoint = normalizeLegacyEndpoint(new URL(config.endpoint ?? DEFAULT_ENDPOINT));
2638
+ avalancheEndpoint = normalizeLegacyEndpoint(new URL(
2462
2639
  config.avalancheEndpoint ?? DEFAULT_AVALANCHE_ENDPOINT
2463
- );
2464
- accountEndpoint = new URL(
2640
+ ));
2641
+ accountEndpoint = normalizeLegacyEndpoint(new URL(
2465
2642
  config.accountEndpoint ?? DEFAULT_ACCOUNT_ENDPOINT
2466
- );
2467
- userEndpoint = new URL(config.userEndpoint ?? DEFAULT_USER_ENDPOINT);
2643
+ ));
2644
+ userEndpoint = normalizeLegacyEndpoint(new URL(config.userEndpoint ?? DEFAULT_USER_ENDPOINT));
2468
2645
  } catch {
2469
2646
  throw new ErpcConfigError("endpoint must be an absolute HTTP(S) URL");
2470
2647
  }
@@ -2480,31 +2657,22 @@ var resolveConfig = (config) => {
2480
2657
  if (userEndpoint.protocol !== "https:" && userEndpoint.protocol !== "http:") {
2481
2658
  throw new ErpcConfigError("userEndpoint must use HTTP or HTTPS");
2482
2659
  }
2483
- endpoint.search = "";
2484
- endpoint.hash = "";
2485
- endpoint.pathname = endpoint.pathname.replace(/\/+$/, "") || "/";
2486
- avalancheEndpoint.search = "";
2487
- avalancheEndpoint.hash = "";
2488
- avalancheEndpoint.pathname = avalancheEndpoint.pathname.replace(/\/+$/, "") || "/";
2489
- accountEndpoint.search = "";
2490
- accountEndpoint.hash = "";
2491
- accountEndpoint.pathname = accountEndpoint.pathname.replace(/\/+$/, "") || "/";
2492
- userEndpoint.search = "";
2493
- userEndpoint.hash = "";
2494
- userEndpoint.pathname = userEndpoint.pathname.replace(/\/+$/, "") || "/";
2495
2660
  const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
2496
2661
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
2497
2662
  throw new ErpcConfigError("timeoutMs must be a positive finite number");
2498
2663
  }
2499
2664
  return {
2500
2665
  accountEndpoint,
2501
- apiKey,
2502
2666
  avalancheEndpoint,
2503
2667
  endpoint,
2504
2668
  fetch: requireFetch(config.fetch),
2505
2669
  headers: config.headers ?? {},
2506
2670
  timeoutMs,
2507
2671
  userEndpoint,
2672
+ ...apiKey === void 0 ? {} : { apiKey },
2673
+ ...avalancheCRpc === void 0 ? {} : { avalancheCRpc },
2674
+ ...ethereumRpc === void 0 ? {} : { ethereumRpc },
2675
+ ...solanaRpc === void 0 ? {} : { solanaRpc },
2508
2676
  ...config.webSocket === void 0 ? {} : { webSocket: config.webSocket }
2509
2677
  };
2510
2678
  };
@@ -2846,16 +3014,16 @@ var nativeNamespace = (transport, methodPrefix) => createRpcNamespace({
2846
3014
  transport,
2847
3015
  validateBatch: rejectNativeBatch
2848
3016
  });
2849
- var createAvalancheClient = (transport, indexTransports) => ({
3017
+ var createAvalancheClient = (transport, indexTransports, nativeTransport = transport) => ({
2850
3018
  ...createEthereumClient(transport),
2851
- avax: nativeNamespace(transport, "avax"),
2852
- xChain: nativeNamespace(transport, "avm"),
2853
- pChain: nativeNamespace(transport, "platform"),
3019
+ avax: nativeNamespace(nativeTransport, "avax"),
3020
+ xChain: nativeNamespace(nativeTransport, "avm"),
3021
+ pChain: nativeNamespace(nativeTransport, "platform"),
2854
3022
  proposerVm: nativeNamespace(
2855
- transport,
3023
+ nativeTransport,
2856
3024
  "proposervm"
2857
3025
  ),
2858
- info: nativeNamespace(transport, "info"),
3026
+ info: nativeNamespace(nativeTransport, "info"),
2859
3027
  index: {
2860
3028
  cChainBlocks: nativeNamespace(
2861
3029
  indexTransports.cChainBlocks,
@@ -3030,7 +3198,9 @@ var WebSocketJsonRpcTransport = class {
3030
3198
  #credential;
3031
3199
  #listeners = /* @__PURE__ */ new Set();
3032
3200
  #pending = /* @__PURE__ */ new Map();
3201
+ #redactionVariants;
3033
3202
  #timeoutMs;
3203
+ #unavailableNamespace;
3034
3204
  #webSocket;
3035
3205
  #connectPromise;
3036
3206
  #nextId = 1;
@@ -3042,21 +3212,38 @@ var WebSocketJsonRpcTransport = class {
3042
3212
  this.#connectionUrl = config.endpoint.toString();
3043
3213
  this.endpoint = publicEndpoint(config.endpoint);
3044
3214
  this.maxBatchSize = config.maxBatchSize ?? 256;
3215
+ this.#redactionVariants = directRedactionVariants(
3216
+ config.endpoint,
3217
+ config.redactionHeaders
3218
+ );
3045
3219
  this.#timeoutMs = config.timeoutMs;
3220
+ this.#unavailableNamespace = config.unavailableNamespace;
3046
3221
  }
3047
3222
  async connect() {
3048
3223
  if (this.#socket?.readyState === 1) return;
3049
3224
  if (this.#connectPromise) return this.#connectPromise;
3225
+ if (this.#unavailableNamespace !== void 0) {
3226
+ throw new ErpcNotConfiguredError(this.#unavailableNamespace);
3227
+ }
3050
3228
  if (!this.#webSocket) {
3051
3229
  throw new ErpcConfigError(
3052
3230
  "A WebSocket implementation is required for subscriptions"
3053
3231
  );
3054
3232
  }
3055
3233
  this.#connectPromise = new Promise((resolve, reject) => {
3056
- const socket = new this.#webSocket(this.#connectionUrl);
3234
+ let socket;
3235
+ try {
3236
+ socket = new this.#webSocket(this.#connectionUrl);
3237
+ } catch {
3238
+ reject(new ErpcTransportError("Unable to connect to ERPC WebSocket"));
3239
+ return;
3240
+ }
3057
3241
  this.#socket = socket;
3058
3242
  const timeout = setTimeout(() => {
3059
- socket.close();
3243
+ try {
3244
+ socket.close();
3245
+ } catch {
3246
+ }
3060
3247
  reject(new ErpcTimeoutError(this.#timeoutMs));
3061
3248
  }, this.#timeoutMs);
3062
3249
  socket.addEventListener(
@@ -3110,6 +3297,9 @@ var WebSocketJsonRpcTransport = class {
3110
3297
  return promise;
3111
3298
  }
3112
3299
  async batch(calls, options = {}) {
3300
+ if (this.#unavailableNamespace !== void 0) {
3301
+ throw new ErpcNotConfiguredError(this.#unavailableNamespace);
3302
+ }
3113
3303
  if (calls.length === 0) return [];
3114
3304
  if (calls.length > this.maxBatchSize) {
3115
3305
  throw new ErpcInvalidResponseError(
@@ -3216,7 +3406,11 @@ var WebSocketJsonRpcTransport = class {
3216
3406
  if (isRpcError(message.error)) {
3217
3407
  pending.reject(
3218
3408
  new ErpcJsonRpcError(
3219
- redactJsonRpcError(message.error, this.#credential)
3409
+ redactJsonRpcError(
3410
+ message.error,
3411
+ this.#credential,
3412
+ this.#redactionVariants
3413
+ )
3220
3414
  )
3221
3415
  );
3222
3416
  } else if ("result" in message) pending.resolve(message.result);
@@ -3907,6 +4101,13 @@ function normalizeEvmAddress2(address) {
3907
4101
  return address.toLowerCase();
3908
4102
  }
3909
4103
 
4104
+ // src/generated/swap_execution_capabilities.ts
4105
+ var SWAP_EXECUTION_CAPABILITIES_JSON = '[{"swapExecutionCapabilityId":"swap-execution-0001","chainId":"eip155:1","dexDeploymentId":"dex-deployment-0001","poolDefinitionId":"pool-0001","factoryAddress":"0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f","routerAddress":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","routerKind":"uniswap-v2-router02","adapterKind":"evm-constant-product-v2","token0DeploymentId":"deployment-0008","token0Address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","token0Standard":"erc20","token1DeploymentId":"deployment-0002","token1Address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","token1Standard":"erc20","wrappedNativeTokenDeploymentId":"deployment-0002","wrappedNativeTokenAddress":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","wrappedNativeFunctionSelector":"0xad5c4648","functionKind":"exact-input-erc20-to-erc20","functionSignature":"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)","functionSelector":"0x38ed1739","status":"active"},{"swapExecutionCapabilityId":"swap-execution-0002","chainId":"eip155:43114","dexDeploymentId":"dex-deployment-0002","poolDefinitionId":"pool-0002","factoryAddress":"0x9ad6c38be94206ca50bb0d90783181662f0cfa10","routerAddress":"0x60ae616a2155ee3d9a68541ba4544862310933d4","routerKind":"joe-v1-router02","adapterKind":"evm-constant-product-v2","token0DeploymentId":"deployment-0004","token0Address":"0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7","token0Standard":"erc20","token1DeploymentId":"deployment-0009","token1Address":"0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e","token1Standard":"erc20","wrappedNativeTokenDeploymentId":"deployment-0004","wrappedNativeTokenAddress":"0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7","wrappedNativeFunctionSelector":"0x73b295c2","functionKind":"exact-input-erc20-to-erc20","functionSignature":"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)","functionSelector":"0x38ed1739","status":"active"}]';
4106
+ var SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST = "84424dc48687e2cb1dd0c9a2446f820efd2c311e71ce5acacfeb6e882811875f";
4107
+ var SWAP_EXECUTION_CAPABILITIES_AS_OF_DATE = "2026-09-16";
4108
+ var SWAP_EXECUTION_FUNCTION_SIGNATURE = "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)";
4109
+ var SWAP_EXECUTION_FUNCTION_SELECTOR = "0x38ed1739";
4110
+
3910
4111
  // src/swap.ts
3911
4112
  var SWAP_QUOTE_ERROR_MESSAGES = Object.freeze({
3912
4113
  SWAP_INVALID_ARGUMENT: "Swap request is invalid",
@@ -3933,6 +4134,22 @@ var SwapQuoteError = class extends Error {
3933
4134
  this.code = code;
3934
4135
  }
3935
4136
  };
4137
+ var SWAP_EXECUTION_ERROR_MESSAGES = Object.freeze({
4138
+ SWAP_EXECUTION_INVALID_ARGUMENT: "Swap execution request is invalid",
4139
+ SWAP_UNSUPPORTED_EXECUTION: "Swap execution is unsupported for the selected records",
4140
+ SWAP_PROGRAM_MISMATCH: "Swap program does not match the selected records",
4141
+ SWAP_INSUFFICIENT_ALLOWANCE: "Swap allowance is insufficient",
4142
+ SWAP_SIMULATION_REVERTED: "Swap simulation reverted",
4143
+ SWAP_INVALID_SIMULATION: "Swap simulation result is invalid"
4144
+ });
4145
+ var SwapExecutionError = class extends Error {
4146
+ code;
4147
+ constructor(code) {
4148
+ super(SWAP_EXECUTION_ERROR_MESSAGES[code]);
4149
+ this.name = "SwapExecutionError";
4150
+ this.code = code;
4151
+ }
4152
+ };
3936
4153
  var SUPPORTED_QUOTE_ADAPTER = "evm-constant-product-v2";
3937
4154
  var SUPPORTED_QUOTE_CAPABILITIES = Object.freeze([
3938
4155
  Object.freeze({
@@ -4025,9 +4242,15 @@ var PAIR_FACTORY_SELECTOR = "0xc45a0155";
4025
4242
  var PAIR_TOKEN0_SELECTOR = "0x0dfe1681";
4026
4243
  var PAIR_TOKEN1_SELECTOR = "0xd21220a7";
4027
4244
  var PAIR_GET_RESERVES_SELECTOR = "0x0902f1ac";
4245
+ var ROUTER_FACTORY_SELECTOR = "0xc45a0155";
4246
+ var ROUTER_GET_AMOUNTS_OUT_SELECTOR = "0xd06ca61f";
4247
+ var ERC20_ALLOWANCE_SELECTOR = "0xdd62ed3e";
4028
4248
  function swapFail(code) {
4029
4249
  throw new SwapQuoteError(code);
4030
4250
  }
4251
+ function executionFail(code) {
4252
+ throw new SwapExecutionError(code);
4253
+ }
4031
4254
  var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
4032
4255
  var isKnownChain2 = (value) => value === DEX_CHAIN_IDS.ethereum || value === DEX_CHAIN_IDS.solana || value === DEX_CHAIN_IDS.avalancheC;
4033
4256
  var isOpaqueId = (value) => /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u.test(value);
@@ -4217,6 +4440,43 @@ var uintWord = (value, maximum = UINT256_MAX) => {
4217
4440
  if (parsed > maximum) swapFail("SWAP_INVALID_POOL_STATE");
4218
4441
  return parsed;
4219
4442
  };
4443
+ var parseExecutionHexBytes = (value, expectedBytes, code = "SWAP_INVALID_SIMULATION") => {
4444
+ if (typeof value !== "string") executionFail(code);
4445
+ if (!HEX_BYTES.test(value) || value.length % 2 !== 0 || expectedBytes !== void 0 && value.length !== expectedBytes * 2 + 2) {
4446
+ executionFail(code);
4447
+ }
4448
+ return value.toLowerCase();
4449
+ };
4450
+ var executionAddressWord = (value, code = "SWAP_INVALID_SIMULATION") => {
4451
+ const bytes = parseExecutionHexBytes(value, 32, code);
4452
+ const word = bytes.slice(2);
4453
+ if (!/^0{24}[0-9a-f]{40}$/u.test(word)) executionFail(code);
4454
+ return `0x${word.slice(24)}`;
4455
+ };
4456
+ var executionUintWord = (value, code = "SWAP_INVALID_SIMULATION") => {
4457
+ const bytes = parseExecutionHexBytes(value, 32, code);
4458
+ try {
4459
+ return BigInt(`0x${bytes.slice(2)}`);
4460
+ } catch {
4461
+ executionFail(code);
4462
+ }
4463
+ };
4464
+ var executionUintArrayOfTwo = (value) => {
4465
+ const bytes = parseExecutionHexBytes(value);
4466
+ const payload = bytes.slice(2);
4467
+ if (payload.length % 64 !== 0 || payload.length < 256) {
4468
+ executionFail("SWAP_INVALID_SIMULATION");
4469
+ }
4470
+ const offset = BigInt(`0x${payload.slice(0, 64)}`);
4471
+ const length = BigInt(`0x${payload.slice(64, 128)}`);
4472
+ if (offset !== 0x20n || length !== 2n || payload.length !== 256) {
4473
+ executionFail("SWAP_INVALID_SIMULATION");
4474
+ }
4475
+ return [
4476
+ executionUintWord(`0x${payload.slice(128, 192)}`),
4477
+ executionUintWord(`0x${payload.slice(192, 256)}`)
4478
+ ];
4479
+ };
4220
4480
  var reserveWords = (value) => {
4221
4481
  const bytes = parseHexBytes(value, 96);
4222
4482
  const payload = bytes.slice(2);
@@ -4262,8 +4522,101 @@ var currentClockSeconds = (clock) => {
4262
4522
  if (!Number.isSafeInteger(value)) swapFail("SWAP_INVALID_ARGUMENT");
4263
4523
  return value;
4264
4524
  };
4265
- var assertFreshness = (state, freshness, clock) => {
4266
- const now = BigInt(currentClockSeconds(clock));
4525
+ var EXECUTION_REQUEST_KEYS = /* @__PURE__ */ new Set([
4526
+ "chainId",
4527
+ "poolDefinitionId",
4528
+ "inputTokenDeploymentId",
4529
+ "outputTokenDeploymentId",
4530
+ "amountIn",
4531
+ "freshness",
4532
+ "sender",
4533
+ "recipient",
4534
+ "slippageBps",
4535
+ "deadline"
4536
+ ]);
4537
+ var snapshotExecutionRequest = (request) => {
4538
+ if (!isRecord3(request)) executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4539
+ if (Object.keys(request).some((key) => !EXECUTION_REQUEST_KEYS.has(key))) {
4540
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4541
+ }
4542
+ const freshness = request.freshness;
4543
+ const freshnessSnapshot = isRecord3(freshness) ? { ...freshness } : freshness;
4544
+ const quoteRequest = {
4545
+ chainId: request.chainId,
4546
+ poolDefinitionId: request.poolDefinitionId,
4547
+ inputTokenDeploymentId: request.inputTokenDeploymentId,
4548
+ outputTokenDeploymentId: request.outputTokenDeploymentId,
4549
+ amountIn: request.amountIn,
4550
+ ...freshnessSnapshot === void 0 ? {} : { freshness: freshnessSnapshot }
4551
+ };
4552
+ return {
4553
+ quoteRequest,
4554
+ sender: request.sender,
4555
+ recipient: request.recipient,
4556
+ slippageBps: request.slippageBps,
4557
+ deadline: request.deadline
4558
+ };
4559
+ };
4560
+ var normalizeExecutionAddress = (value) => {
4561
+ if (typeof value !== "string" || !/^0x[0-9a-fA-F]{40}$/u.test(value)) {
4562
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4563
+ }
4564
+ const normalized = value.toLowerCase();
4565
+ if (normalized === `0x${"0".repeat(40)}`) {
4566
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4567
+ }
4568
+ return normalized;
4569
+ };
4570
+ var normalizeExecutionSlippage = (value) => {
4571
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 9999) {
4572
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4573
+ }
4574
+ return value;
4575
+ };
4576
+ var parseExecutionDeadline = (value) => {
4577
+ if (typeof value !== "string" || !UINT256_DECIMAL.test(value) || value.length > 78) {
4578
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4579
+ }
4580
+ let parsed;
4581
+ try {
4582
+ parsed = BigInt(value);
4583
+ } catch {
4584
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4585
+ }
4586
+ if (parsed <= 0n || parsed > UINT256_MAX) {
4587
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4588
+ }
4589
+ return { source: value, value: parsed };
4590
+ };
4591
+ var normalizeExecutionRequest = (request, clock) => {
4592
+ const snapshot = snapshotExecutionRequest(request);
4593
+ const sender = normalizeExecutionAddress(snapshot.sender);
4594
+ const recipient = normalizeExecutionAddress(snapshot.recipient);
4595
+ const slippageBps = normalizeExecutionSlippage(snapshot.slippageBps);
4596
+ const deadline = parseExecutionDeadline(snapshot.deadline);
4597
+ const initialClock = BigInt(currentClockSeconds(clock));
4598
+ if (deadline.value <= initialClock) {
4599
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4600
+ }
4601
+ let normalized;
4602
+ try {
4603
+ normalized = normalizeQuoteRequest(snapshot.quoteRequest);
4604
+ } catch (error) {
4605
+ if (error instanceof SwapQuoteError && (error.code === "SWAP_UNKNOWN_POOL" || error.code === "SWAP_UNSUPPORTED_ADAPTER" || error.code === "SWAP_UNSUPPORTED_TOKEN" || error.code === "SWAP_UNSUPPORTED_TOKEN_STANDARD")) {
4606
+ executionFail("SWAP_UNSUPPORTED_EXECUTION");
4607
+ }
4608
+ throw error;
4609
+ }
4610
+ return {
4611
+ normalized,
4612
+ sender,
4613
+ recipient,
4614
+ slippageBps,
4615
+ deadline: deadline.source,
4616
+ deadlineValue: deadline.value
4617
+ };
4618
+ };
4619
+ var assertFreshnessAtNow = (state, freshness, now) => {
4267
4620
  const initialAge = now - state.initial.timestamp;
4268
4621
  if (initialAge < -BigInt(freshness.maxClockSkewSeconds) || initialAge > BigInt(freshness.maxBlockAgeSeconds)) {
4269
4622
  swapFail("SWAP_STATE_STALE");
@@ -4285,6 +4638,54 @@ var assertFreshness = (state, freshness, clock) => {
4285
4638
  swapFail("SWAP_STATE_STALE");
4286
4639
  }
4287
4640
  };
4641
+ var assertFreshness = (state, freshness, clock) => {
4642
+ assertFreshnessAtNow(
4643
+ state,
4644
+ freshness,
4645
+ BigInt(currentClockSeconds(clock))
4646
+ );
4647
+ };
4648
+ var executionCapabilityFor = (normalized) => {
4649
+ const capability = EXECUTION_CAPABILITIES.find(
4650
+ (entry) => entry.poolDefinitionId === normalized.pool.poolDefinitionId
4651
+ );
4652
+ if (!capability || capability.status !== "active") {
4653
+ executionFail("SWAP_UNSUPPORTED_EXECUTION");
4654
+ }
4655
+ const token0 = getTokenDeployment(capability.token0DeploymentId);
4656
+ const token1 = getTokenDeployment(capability.token1DeploymentId);
4657
+ const wrapped = getTokenDeployment(capability.wrappedNativeTokenDeploymentId);
4658
+ const nativeWrap = NATIVE_WRAP_DEFINITIONS.find(
4659
+ (entry) => entry.chainId === capability.chainId && entry.wrappedTokenDeploymentId === capability.wrappedNativeTokenDeploymentId
4660
+ );
4661
+ const matchesCapabilityToken = (token, deploymentId, address, standard) => token?.deploymentId === deploymentId && token.chainId === capability.chainId && token.address === address && token.standard === standard && token.status === "active";
4662
+ const inputMatches = matchesCapabilityToken(
4663
+ normalized.input,
4664
+ capability.token0DeploymentId,
4665
+ capability.token0Address,
4666
+ capability.token0Standard
4667
+ ) || matchesCapabilityToken(
4668
+ normalized.input,
4669
+ capability.token1DeploymentId,
4670
+ capability.token1Address,
4671
+ capability.token1Standard
4672
+ );
4673
+ const outputMatches = matchesCapabilityToken(
4674
+ normalized.output,
4675
+ capability.token0DeploymentId,
4676
+ capability.token0Address,
4677
+ capability.token0Standard
4678
+ ) || matchesCapabilityToken(
4679
+ normalized.output,
4680
+ capability.token1DeploymentId,
4681
+ capability.token1Address,
4682
+ capability.token1Standard
4683
+ );
4684
+ if (capability.chainId !== normalized.pool.chainId || capability.dexDeploymentId !== normalized.pool.dexDeploymentId || capability.adapterKind !== SUPPORTED_QUOTE_ADAPTER || capability.functionKind !== "exact-input-erc20-to-erc20" || capability.functionSignature !== SWAP_EXECUTION_FUNCTION_SIGNATURE || capability.functionSelector !== SWAP_EXECUTION_FUNCTION_SELECTOR || normalized.dex.status !== "active" || normalized.dex.programAddress !== capability.factoryAddress || normalized.dex.adapterKind !== capability.adapterKind || normalized.pool.status !== "active" || normalized.pool.adapter.kind !== capability.adapterKind || normalized.pool.adapter.feeNumerator !== "3" || normalized.pool.adapter.feeDenominator !== "1000" || normalized.pool.token0DeploymentId !== capability.token0DeploymentId || normalized.pool.token1DeploymentId !== capability.token1DeploymentId || !inputMatches || !outputMatches || !token0 || !token1 || !wrapped || wrapped.chainId !== capability.chainId || wrapped.address !== capability.wrappedNativeTokenAddress || wrapped.standard !== "erc20" || wrapped.status !== "active" || !nativeWrap || nativeWrap.status !== "active" || nativeWrap.wrappedTokenDeploymentId !== capability.wrappedNativeTokenDeploymentId) {
4685
+ executionFail("SWAP_UNSUPPORTED_EXECUTION");
4686
+ }
4687
+ return capability;
4688
+ };
4288
4689
  var readEvmState = async (transport, normalized, clock, options) => {
4289
4690
  const { pool, dex } = normalized;
4290
4691
  const chainId = await rpcRequest(transport, "eth_chainId", [], options);
@@ -4417,14 +4818,269 @@ var quoteResult = (normalized, state, result) => {
4417
4818
  };
4418
4819
  return deepFreeze5(output);
4419
4820
  };
4821
+ var transportForNormalized = (normalized, options) => {
4822
+ const transport = normalized.pool.chainId === DEX_CHAIN_IDS.ethereum ? options.ethereum : normalized.pool.chainId === DEX_CHAIN_IDS.avalancheC ? options.avalanche : void 0;
4823
+ if (!transport) swapFail("SWAP_UNSUPPORTED_ADAPTER");
4824
+ return transport;
4825
+ };
4826
+ var encodeUint256Word = (value) => ensureUint256(value).toString(16).padStart(64, "0");
4827
+ var executionTokenAddress = (token) => {
4828
+ if (typeof token.address !== "string" || !EVM_ADDRESS.test(token.address)) {
4829
+ executionFail("SWAP_INVALID_SIMULATION");
4830
+ }
4831
+ return token.address.toLowerCase();
4832
+ };
4833
+ var executionGetAmountsOutData = (amountIn, inputAddress, outputAddress) => `${ROUTER_GET_AMOUNTS_OUT_SELECTOR}${encodeUint256Word(amountIn)}${encodeUint256Word(
4834
+ 0x40n
4835
+ )}${encodeUint256Word(2n)}${encodeAddressArgument(
4836
+ inputAddress
4837
+ )}${encodeAddressArgument(outputAddress)}`;
4838
+ var executionSwapData = (amountIn, minimumAmountOut, inputAddress, outputAddress, recipient, deadline) => `${SWAP_EXECUTION_FUNCTION_SELECTOR}${encodeUint256Word(
4839
+ amountIn
4840
+ )}${encodeUint256Word(minimumAmountOut)}${encodeUint256Word(
4841
+ 0xa0n
4842
+ )}${encodeAddressArgument(recipient)}${encodeUint256Word(
4843
+ deadline
4844
+ )}${encodeUint256Word(2n)}${encodeAddressArgument(
4845
+ inputAddress
4846
+ )}${encodeAddressArgument(outputAddress)}`;
4847
+ var buildExecutionPreparation = (execution, capability, quote) => {
4848
+ const inputAddress = executionTokenAddress(execution.normalized.input);
4849
+ const outputAddress = executionTokenAddress(execution.normalized.output);
4850
+ const quoteAmountOut = parseDecimalQuantity(quote.amountOut, "SWAP_ARITHMETIC");
4851
+ const minimumAmountOut = ensureUint256(
4852
+ quoteAmountOut * BigInt(1e4 - execution.slippageBps),
4853
+ "SWAP_ARITHMETIC"
4854
+ ) / 10000n;
4855
+ if (minimumAmountOut <= 0n) {
4856
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4857
+ }
4858
+ const path = [
4859
+ {
4860
+ tokenDeploymentId: execution.normalized.input.deploymentId,
4861
+ address: inputAddress,
4862
+ standard: "erc20",
4863
+ representationKind: execution.normalized.input.representationKind
4864
+ },
4865
+ {
4866
+ tokenDeploymentId: execution.normalized.output.deploymentId,
4867
+ address: outputAddress,
4868
+ standard: "erc20",
4869
+ representationKind: execution.normalized.output.representationKind
4870
+ }
4871
+ ];
4872
+ const transaction = {
4873
+ kind: "evm-unsigned-transaction",
4874
+ chainId: quote.chainId,
4875
+ from: execution.sender,
4876
+ to: capability.routerAddress,
4877
+ data: executionSwapData(
4878
+ execution.normalized.amountIn,
4879
+ minimumAmountOut,
4880
+ inputAddress,
4881
+ outputAddress,
4882
+ execution.recipient,
4883
+ execution.deadlineValue
4884
+ ),
4885
+ value: "0"
4886
+ };
4887
+ return deepFreeze5({
4888
+ preparationKind: "evm-router-v2-exact-input",
4889
+ executionCapabilityId: capability.swapExecutionCapabilityId,
4890
+ executionCapabilityDigest: SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST,
4891
+ quote,
4892
+ minimumAmountOut: minimumAmountOut.toString(10),
4893
+ slippageBps: execution.slippageBps,
4894
+ deadline: execution.deadline,
4895
+ recipient: execution.recipient,
4896
+ path,
4897
+ transaction,
4898
+ allowance: {
4899
+ tokenDeploymentId: execution.normalized.input.deploymentId,
4900
+ tokenAddress: inputAddress,
4901
+ owner: execution.sender,
4902
+ spender: capability.routerAddress,
4903
+ requiredAmount: quote.amountIn
4904
+ }
4905
+ });
4906
+ };
4907
+ var assertExecutionDeadline = (execution, quoteTimestamp, completionClock) => {
4908
+ if (execution.deadlineValue <= quoteTimestamp || execution.deadlineValue <= completionClock) {
4909
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4910
+ }
4911
+ };
4912
+ var prepareExecutionContext = async (execution, capability, transport, options, requestOptions) => {
4913
+ const state = await readEvmState(
4914
+ transport,
4915
+ execution.normalized,
4916
+ options.clock,
4917
+ requestOptions
4918
+ );
4919
+ assertFreshness(state, execution.normalized.freshness, options.clock);
4920
+ const quote = quoteResult(
4921
+ execution.normalized,
4922
+ state,
4923
+ calculateQuote(execution.normalized, state)
4924
+ );
4925
+ if (execution.deadlineValue <= state.initial.timestamp) {
4926
+ executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
4927
+ }
4928
+ const inputAddress = executionTokenAddress(execution.normalized.input);
4929
+ const outputAddress = executionTokenAddress(execution.normalized.output);
4930
+ const selector = rpcSelector(state.initial.hash);
4931
+ const routerCodeRaw = await rpcRequest(transport, "eth_getCode", [
4932
+ capability.routerAddress,
4933
+ selector
4934
+ ], requestOptions);
4935
+ const routerCode = parseExecutionHexBytes(routerCodeRaw);
4936
+ if (routerCode.length <= 2) executionFail("SWAP_INVALID_SIMULATION");
4937
+ const routerFactoryRaw = await rpcRequest(transport, "eth_call", [
4938
+ abiCall(capability.routerAddress, ROUTER_FACTORY_SELECTOR),
4939
+ selector
4940
+ ], requestOptions);
4941
+ const routerFactory = executionAddressWord(routerFactoryRaw);
4942
+ if (routerFactory !== capability.factoryAddress) {
4943
+ executionFail("SWAP_PROGRAM_MISMATCH");
4944
+ }
4945
+ const wrappedNativeRaw = await rpcRequest(transport, "eth_call", [
4946
+ abiCall(capability.routerAddress, capability.wrappedNativeFunctionSelector),
4947
+ selector
4948
+ ], requestOptions);
4949
+ const wrappedNative = executionAddressWord(wrappedNativeRaw);
4950
+ if (wrappedNative !== capability.wrappedNativeTokenAddress) {
4951
+ executionFail("SWAP_PROGRAM_MISMATCH");
4952
+ }
4953
+ const amountsOutRaw = await rpcRequest(transport, "eth_call", [
4954
+ abiCall(
4955
+ capability.routerAddress,
4956
+ executionGetAmountsOutData(
4957
+ execution.normalized.amountIn,
4958
+ inputAddress,
4959
+ outputAddress
4960
+ )
4961
+ ),
4962
+ selector
4963
+ ], requestOptions);
4964
+ const amountsOut = executionUintArrayOfTwo(amountsOutRaw);
4965
+ const quoteAmountOut = parseDecimalQuantity(quote.amountOut, "SWAP_ARITHMETIC");
4966
+ if (amountsOut[0] !== execution.normalized.amountIn || amountsOut[1] !== quoteAmountOut) {
4967
+ executionFail("SWAP_INVALID_SIMULATION");
4968
+ }
4969
+ const latestAfterRouterReads = blockHeader(
4970
+ await rpcRequest(
4971
+ transport,
4972
+ "eth_getBlockByNumber",
4973
+ ["latest", false],
4974
+ requestOptions
4975
+ )
4976
+ );
4977
+ const completionClock = BigInt(currentClockSeconds(options.clock));
4978
+ assertFreshnessAtNow(
4979
+ {
4980
+ initial: state.initial,
4981
+ latestAfterReads: latestAfterRouterReads
4982
+ },
4983
+ execution.normalized.freshness,
4984
+ completionClock
4985
+ );
4986
+ const preparation = buildExecutionPreparation(execution, capability, quote);
4987
+ assertExecutionDeadline(
4988
+ execution,
4989
+ state.initial.timestamp,
4990
+ BigInt(currentClockSeconds(options.clock))
4991
+ );
4992
+ return { normalized: execution, capability, transport, state, quote, preparation };
4993
+ };
4994
+ var isRecognizedExecutionRevert = (error) => {
4995
+ if (!(error instanceof ErpcJsonRpcError)) return false;
4996
+ if (![3, -32e3, -32015, -32603].includes(error.rpcCode)) return false;
4997
+ const message = error.message.toLowerCase();
4998
+ return message.includes("execution reverted") || message.includes("transaction reverted") || message.includes("vm execution error") || /^revert(?:ed)?(?:\b|:)/u.test(message);
4999
+ };
5000
+ var simulateExecutionContext = async (context, options, requestOptions) => {
5001
+ const { normalized, capability, transport, state, preparation } = context;
5002
+ const selector = rpcSelector(state.initial.hash);
5003
+ const inputAddress = preparation.allowance.tokenAddress;
5004
+ const allowanceData = `${ERC20_ALLOWANCE_SELECTOR}${encodeAddressArgument(
5005
+ normalized.sender
5006
+ )}${encodeAddressArgument(capability.routerAddress)}`;
5007
+ const allowanceRaw = await rpcRequest(transport, "eth_call", [
5008
+ abiCall(inputAddress, allowanceData),
5009
+ selector
5010
+ ], requestOptions);
5011
+ const currentAllowance = executionUintWord(
5012
+ allowanceRaw,
5013
+ "SWAP_INSUFFICIENT_ALLOWANCE"
5014
+ );
5015
+ if (currentAllowance < normalized.normalized.amountIn) {
5016
+ executionFail("SWAP_INSUFFICIENT_ALLOWANCE");
5017
+ }
5018
+ let simulationRaw;
5019
+ try {
5020
+ simulationRaw = await rpcRequest(transport, "eth_call", [
5021
+ {
5022
+ from: preparation.transaction.from,
5023
+ to: preparation.transaction.to,
5024
+ data: preparation.transaction.data,
5025
+ value: "0x0"
5026
+ },
5027
+ selector
5028
+ ], requestOptions);
5029
+ } catch (error) {
5030
+ if (isRecognizedExecutionRevert(error)) {
5031
+ executionFail("SWAP_SIMULATION_REVERTED");
5032
+ }
5033
+ throw error;
5034
+ }
5035
+ const latestAfterSimulation = blockHeader(
5036
+ await rpcRequest(
5037
+ transport,
5038
+ "eth_getBlockByNumber",
5039
+ ["latest", false],
5040
+ requestOptions
5041
+ )
5042
+ );
5043
+ const completionClock = BigInt(currentClockSeconds(options.clock));
5044
+ assertFreshnessAtNow(
5045
+ { initial: state.initial, latestAfterReads: latestAfterSimulation },
5046
+ normalized.normalized.freshness,
5047
+ completionClock
5048
+ );
5049
+ const amounts = executionUintArrayOfTwo(simulationRaw);
5050
+ const quoteAmountOut = parseDecimalQuantity(
5051
+ preparation.quote.amountOut,
5052
+ "SWAP_ARITHMETIC"
5053
+ );
5054
+ const minimumAmountOut = parseDecimalQuantity(
5055
+ preparation.minimumAmountOut,
5056
+ "SWAP_ARITHMETIC"
5057
+ );
5058
+ if (amounts[0] !== normalized.normalized.amountIn || amounts[1] !== quoteAmountOut || amounts[1] < minimumAmountOut) {
5059
+ executionFail("SWAP_INVALID_SIMULATION");
5060
+ }
5061
+ assertExecutionDeadline(
5062
+ normalized,
5063
+ state.initial.timestamp,
5064
+ BigInt(currentClockSeconds(options.clock))
5065
+ );
5066
+ return deepFreeze5({
5067
+ simulationKind: "evm-call",
5068
+ preparation,
5069
+ snapshot: preparation.quote.snapshot,
5070
+ currentAllowance: currentAllowance.toString(10),
5071
+ amounts: [
5072
+ amounts[0].toString(10),
5073
+ amounts[1].toString(10)
5074
+ ],
5075
+ amountOut: amounts[1].toString(10)
5076
+ });
5077
+ };
4420
5078
  var quoteExactInputWithTransports = async (request, options, requestOptions) => {
4421
5079
  const normalized = normalizeQuoteRequest(request);
4422
5080
  if (normalized.pool.adapter.kind !== SUPPORTED_QUOTE_ADAPTER) {
4423
5081
  swapFail("SWAP_UNSUPPORTED_ADAPTER");
4424
5082
  }
4425
- const transport = normalized.pool.chainId === DEX_CHAIN_IDS.ethereum ? options.ethereum : normalized.pool.chainId === DEX_CHAIN_IDS.avalancheC ? options.avalanche : void 0;
4426
- if (!transport) swapFail("SWAP_UNSUPPORTED_ADAPTER");
4427
- const selectedTransport = transport;
5083
+ const selectedTransport = transportForNormalized(normalized, options);
4428
5084
  const state = await readEvmState(
4429
5085
  selectedTransport,
4430
5086
  normalized,
@@ -4434,6 +5090,32 @@ var quoteExactInputWithTransports = async (request, options, requestOptions) =>
4434
5090
  assertFreshness(state, normalized.freshness, options.clock);
4435
5091
  return quoteResult(normalized, state, calculateQuote(normalized, state));
4436
5092
  };
5093
+ var prepareExactInputSwapWithTransports = async (request, options, requestOptions) => {
5094
+ const normalized = normalizeExecutionRequest(request, options.clock);
5095
+ const capability = executionCapabilityFor(normalized.normalized);
5096
+ const transport = transportForNormalized(normalized.normalized, options);
5097
+ const context = await prepareExecutionContext(
5098
+ normalized,
5099
+ capability,
5100
+ transport,
5101
+ options,
5102
+ requestOptions
5103
+ );
5104
+ return context.preparation;
5105
+ };
5106
+ var simulateExactInputSwapWithTransports = async (request, options, requestOptions) => {
5107
+ const normalized = normalizeExecutionRequest(request, options.clock);
5108
+ const capability = executionCapabilityFor(normalized.normalized);
5109
+ const transport = transportForNormalized(normalized.normalized, options);
5110
+ const context = await prepareExecutionContext(
5111
+ normalized,
5112
+ capability,
5113
+ transport,
5114
+ options,
5115
+ requestOptions
5116
+ );
5117
+ return simulateExecutionContext(context, options, requestOptions);
5118
+ };
4437
5119
  var deepFreeze5 = (value) => {
4438
5120
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
4439
5121
  Object.freeze(value);
@@ -4443,8 +5125,13 @@ var deepFreeze5 = (value) => {
4443
5125
  }
4444
5126
  return value;
4445
5127
  };
5128
+ var EXECUTION_CAPABILITIES = deepFreeze5(
5129
+ JSON.parse(SWAP_EXECUTION_CAPABILITIES_JSON)
5130
+ );
4446
5131
  var createSwapClient = (options) => Object.freeze({
4447
- quoteExactInput: (request, requestOptions) => quoteExactInputWithTransports(request, options, requestOptions)
5132
+ quoteExactInput: (request, requestOptions) => quoteExactInputWithTransports(request, options, requestOptions),
5133
+ prepareExactInputSwap: (request, requestOptions) => prepareExactInputSwapWithTransports(request, options, requestOptions),
5134
+ simulateExactInputSwap: (request, requestOptions) => simulateExactInputSwapWithTransports(request, options, requestOptions)
4448
5135
  });
4449
5136
 
4450
5137
  // src/transport/http.ts
@@ -4476,19 +5163,45 @@ var parseJson = (text) => {
4476
5163
  throw new ErpcInvalidResponseError("ERPC returned malformed JSON");
4477
5164
  }
4478
5165
  };
5166
+ var directRequestHeaders = (headers) => {
5167
+ try {
5168
+ const result = new Headers(headers);
5169
+ result.set("accept", "application/json");
5170
+ result.set("content-type", "application/json");
5171
+ return result;
5172
+ } catch {
5173
+ const result = {};
5174
+ for (const [name, value] of Object.entries(headers)) {
5175
+ const lowerName = name.toLowerCase();
5176
+ if (lowerName === "accept" || lowerName === "content-type") continue;
5177
+ result[name] = value;
5178
+ }
5179
+ result.accept = "application/json";
5180
+ result["content-type"] = "application/json";
5181
+ return result;
5182
+ }
5183
+ };
4479
5184
  var HttpJsonRpcTransport = class {
4480
5185
  endpoint;
4481
5186
  maxBatchSize;
4482
5187
  #apiKey;
5188
+ #direct;
5189
+ #requestEndpoint;
4483
5190
  #fetch;
4484
5191
  #headers;
5192
+ #redactionVariants;
4485
5193
  #timeoutMs;
5194
+ #unavailableNamespace;
4486
5195
  #nextId = 1;
4487
5196
  constructor(config) {
4488
- this.#apiKey = config.apiKey;
5197
+ this.#apiKey = config.apiKey ?? "";
5198
+ this.#direct = config.direct ?? false;
5199
+ this.#requestEndpoint = new URL(config.endpoint);
4489
5200
  this.#fetch = config.fetch;
4490
5201
  this.#headers = config.headers;
5202
+ this.#redactionVariants = this.#direct ? directRedactionVariants(this.#requestEndpoint, this.#headers) : [];
4491
5203
  this.#timeoutMs = config.timeoutMs;
5204
+ this.#unavailableNamespace = config.unavailableNamespace;
4492
5205
  this.maxBatchSize = config.maxBatchSize ?? 256;
4493
5206
  const endpoint = new URL(config.endpoint);
4494
5207
  endpoint.search = "";
@@ -4496,12 +5209,14 @@ var HttpJsonRpcTransport = class {
4496
5209
  this.endpoint = endpoint.toString();
4497
5210
  }
4498
5211
  async request(method, params, options = {}) {
5212
+ this.#ensureConfigured();
4499
5213
  const id = this.#id();
4500
5214
  const request = this.#request(id, method, params);
4501
5215
  const response = await this.#post(request, options);
4502
5216
  return this.#unwrap(response, id);
4503
5217
  }
4504
5218
  async batch(calls, options = {}) {
5219
+ this.#ensureConfigured();
4505
5220
  if (calls.length === 0) return [];
4506
5221
  if (calls.length > this.maxBatchSize) {
4507
5222
  throw new ErpcInvalidResponseError(
@@ -4515,7 +5230,13 @@ var HttpJsonRpcTransport = class {
4515
5230
  const raw = await this.#post(requests, options);
4516
5231
  if (!Array.isArray(raw)) {
4517
5232
  if (isFailure(raw)) {
4518
- throw new ErpcJsonRpcError(redactJsonRpcError(raw.error, this.#apiKey));
5233
+ throw new ErpcJsonRpcError(
5234
+ redactJsonRpcError(
5235
+ raw.error,
5236
+ this.#direct ? void 0 : this.#apiKey,
5237
+ this.#redactionVariants
5238
+ )
5239
+ );
4519
5240
  }
4520
5241
  throw new ErpcInvalidResponseError("ERPC returned a non-array batch response");
4521
5242
  }
@@ -4557,24 +5278,34 @@ var HttpJsonRpcTransport = class {
4557
5278
  this.#nextId = id >= Number.MAX_SAFE_INTEGER ? 1 : id + 1;
4558
5279
  return id;
4559
5280
  }
5281
+ #ensureConfigured() {
5282
+ if (this.#unavailableNamespace !== void 0) {
5283
+ throw new ErpcNotConfiguredError(this.#unavailableNamespace);
5284
+ }
5285
+ }
4560
5286
  #request(id, method, params) {
4561
5287
  const request = { jsonrpc: "2.0", id, method };
4562
5288
  if (params !== void 0) request.params = params;
4563
5289
  return request;
4564
5290
  }
4565
5291
  async #post(body, options) {
4566
- const url = new URL(this.endpoint);
4567
- url.searchParams.set("api-key", this.#apiKey);
5292
+ this.#ensureConfigured();
5293
+ const url = new URL(this.#requestEndpoint);
5294
+ if (!this.#direct) url.searchParams.set("api-key", this.#apiKey);
4568
5295
  const controlled = controlledSignal2(this.#timeoutMs, options.signal);
4569
5296
  try {
4570
5297
  const response = await this.#fetch(url, {
4571
5298
  method: "POST",
4572
- headers: {
5299
+ headers: this.#direct ? directRequestHeaders(this.#headers) : {
4573
5300
  ...this.#headers,
4574
5301
  "content-type": "application/json"
4575
5302
  },
4576
5303
  body: JSON.stringify(body),
4577
- signal: controlled.signal
5304
+ signal: controlled.signal,
5305
+ ...this.#direct ? {
5306
+ credentials: "omit",
5307
+ redirect: "manual"
5308
+ } : {}
4578
5309
  });
4579
5310
  const text = await response.text();
4580
5311
  if (!response.ok) throw new ErpcHttpError(response.status);
@@ -4597,7 +5328,11 @@ var HttpJsonRpcTransport = class {
4597
5328
  }
4598
5329
  if (isFailure(response)) {
4599
5330
  throw new ErpcJsonRpcError(
4600
- redactJsonRpcError(response.error, this.#apiKey)
5331
+ redactJsonRpcError(
5332
+ response.error,
5333
+ this.#direct ? void 0 : this.#apiKey,
5334
+ this.#redactionVariants
5335
+ )
4601
5336
  );
4602
5337
  }
4603
5338
  if (!("result" in response)) throw new ErpcInvalidResponseError();
@@ -4691,62 +5426,81 @@ var UsageClient = class {
4691
5426
  };
4692
5427
 
4693
5428
  // src/client.ts
5429
+ var unavailableEndpoint = (namespace) => new URL(
5430
+ `https://unconfigured.invalid/${namespace.replace(/[^a-z\d._-]+/giu, "-")}`
5431
+ );
4694
5432
  var createErpcClient = (config) => {
4695
5433
  const resolved = resolveConfig(config);
4696
- const sharedTransport = {
4697
- apiKey: resolved.apiKey,
5434
+ const legacyTransport = {
4698
5435
  fetch: resolved.fetch,
4699
5436
  headers: resolved.headers,
4700
- timeoutMs: resolved.timeoutMs
5437
+ timeoutMs: resolved.timeoutMs,
5438
+ ...resolved.apiKey === void 0 ? {} : { apiKey: resolved.apiKey }
4701
5439
  };
4702
- const solanaTransport = new HttpJsonRpcTransport({
4703
- ...sharedTransport,
4704
- endpoint: resolved.endpoint
4705
- });
4706
- const ethereumEndpoint = endpointWithPath(resolved.endpoint, "/eth");
4707
- const ethereumTransport = new HttpJsonRpcTransport({
4708
- ...sharedTransport,
4709
- endpoint: ethereumEndpoint
4710
- });
4711
- const avalancheTransport = new HttpJsonRpcTransport({
4712
- ...sharedTransport,
4713
- endpoint: endpointWithPath(resolved.avalancheEndpoint, "/ava")
4714
- });
4715
- const avalancheIndexTransport = (path) => new HttpJsonRpcTransport({
4716
- ...sharedTransport,
4717
- endpoint: endpointWithPath(resolved.avalancheEndpoint, path)
4718
- });
4719
- const solanaWebSocket = new WebSocketJsonRpcTransport({
4720
- endpoint: websocketUrl(resolved.endpoint, resolved.apiKey),
5440
+ const createUnavailableHttp = (namespace) => new HttpJsonRpcTransport({
5441
+ endpoint: unavailableEndpoint(namespace),
5442
+ fetch: resolved.fetch,
5443
+ headers: {},
4721
5444
  timeoutMs: resolved.timeoutMs,
4722
- ...resolved.webSocket === void 0 ? {} : { webSocket: resolved.webSocket }
5445
+ unavailableNamespace: namespace
4723
5446
  });
4724
- const ethereumWebSocket = new WebSocketJsonRpcTransport({
4725
- endpoint: websocketUrl(resolved.endpoint, resolved.apiKey, "/eth"),
5447
+ const createUnavailableWebSocket = (namespace) => new WebSocketJsonRpcTransport({
5448
+ endpoint: unavailableEndpoint(namespace),
4726
5449
  timeoutMs: resolved.timeoutMs,
4727
- ...resolved.webSocket === void 0 ? {} : { webSocket: resolved.webSocket }
5450
+ unavailableNamespace: namespace
4728
5451
  });
4729
- const avalancheWebSocket = new WebSocketJsonRpcTransport({
4730
- endpoint: websocketUrl(
4731
- resolved.avalancheEndpoint,
4732
- resolved.apiKey,
4733
- "/ava-ws"
4734
- ),
5452
+ const createDirectHttp = (endpoint) => new HttpJsonRpcTransport({
5453
+ direct: true,
5454
+ endpoint: endpoint.httpUrl,
5455
+ fetch: resolved.fetch,
5456
+ headers: endpoint.headers,
5457
+ timeoutMs: resolved.timeoutMs
5458
+ });
5459
+ const createDirectWebSocket = (endpoint, namespace) => {
5460
+ if (endpoint.webSocketUrl === void 0) {
5461
+ return createUnavailableWebSocket(namespace);
5462
+ }
5463
+ return new WebSocketJsonRpcTransport({
5464
+ endpoint: endpoint.webSocketUrl,
5465
+ redactionHeaders: endpoint.headers,
5466
+ timeoutMs: resolved.timeoutMs,
5467
+ ...resolved.webSocket === void 0 ? {} : { webSocket: resolved.webSocket }
5468
+ });
5469
+ };
5470
+ const createLegacyHttp = (endpoint) => new HttpJsonRpcTransport({ ...legacyTransport, endpoint });
5471
+ const createLegacyWebSocket = (endpoint) => new WebSocketJsonRpcTransport({
5472
+ endpoint,
4735
5473
  timeoutMs: resolved.timeoutMs,
4736
5474
  ...resolved.webSocket === void 0 ? {} : { webSocket: resolved.webSocket }
4737
5475
  });
4738
- const priceTransport = new RestTransport({
4739
- ...sharedTransport,
4740
- endpoint: resolved.endpoint
5476
+ const solanaTransport = resolved.solanaRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("solana.rpc") : createLegacyHttp(resolved.endpoint) : createDirectHttp(resolved.solanaRpc);
5477
+ const ethereumTransport = resolved.ethereumRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("ethereum.rpc") : createLegacyHttp(endpointWithPath(resolved.endpoint, "/eth")) : createDirectHttp(resolved.ethereumRpc);
5478
+ const avalancheTransport = resolved.avalancheCRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("avalanche.rpc") : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, "/ava")) : createDirectHttp(resolved.avalancheCRpc);
5479
+ const avalancheNativeTransport = resolved.apiKey === void 0 ? createUnavailableHttp("avalanche.native") : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, "/ava"));
5480
+ const avalancheIndexTransport = (path, namespace) => resolved.apiKey === void 0 ? createUnavailableHttp(namespace) : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, path));
5481
+ const solanaWebSocket = resolved.solanaRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("solana.subscriptions") : createLegacyWebSocket(websocketUrl(resolved.endpoint, resolved.apiKey)) : createDirectWebSocket(resolved.solanaRpc, "solana.subscriptions");
5482
+ const ethereumWebSocket = resolved.ethereumRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("ethereum.subscriptions") : createLegacyWebSocket(
5483
+ websocketUrl(resolved.endpoint, resolved.apiKey, "/eth")
5484
+ ) : createDirectWebSocket(resolved.ethereumRpc, "ethereum.subscriptions");
5485
+ const avalancheWebSocket = resolved.avalancheCRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("avalanche.subscriptions") : createLegacyWebSocket(
5486
+ websocketUrl(resolved.avalancheEndpoint, resolved.apiKey, "/ava-ws")
5487
+ ) : createDirectWebSocket(
5488
+ resolved.avalancheCRpc,
5489
+ "avalanche.subscriptions"
5490
+ );
5491
+ const createUnavailableRest = (namespace) => new RestTransport({
5492
+ endpoint: unavailableEndpoint(namespace),
5493
+ fetch: resolved.fetch,
5494
+ headers: {},
5495
+ timeoutMs: resolved.timeoutMs,
5496
+ unavailableNamespace: namespace
4741
5497
  });
4742
- const accountTransport = new RestTransport({
4743
- ...sharedTransport,
5498
+ const priceTransport = resolved.apiKey === void 0 ? createUnavailableRest("price") : new RestTransport({ ...legacyTransport, endpoint: resolved.endpoint });
5499
+ const accountTransport = resolved.apiKey === void 0 ? createUnavailableRest("account") : new RestTransport({
5500
+ ...legacyTransport,
4744
5501
  endpoint: resolved.accountEndpoint
4745
5502
  });
4746
- const userTransport = new RestTransport({
4747
- ...sharedTransport,
4748
- endpoint: resolved.userEndpoint
4749
- });
5503
+ const userTransport = resolved.apiKey === void 0 ? createUnavailableRest("usage") : new RestTransport({ ...legacyTransport, endpoint: resolved.userEndpoint });
4750
5504
  const solana = {
4751
5505
  ...createSolanaClient(solanaTransport),
4752
5506
  subscriptions: new SolanaSubscriptions(solanaWebSocket)
@@ -4757,11 +5511,23 @@ var createErpcClient = (config) => {
4757
5511
  };
4758
5512
  const avalanche = {
4759
5513
  ...createAvalancheClient(avalancheTransport, {
4760
- cChainBlocks: avalancheIndexTransport("/ava/ext/index/C/block"),
4761
- pChainBlocks: avalancheIndexTransport("/ava/ext/index/P/block"),
4762
- xChainBlocks: avalancheIndexTransport("/ava/ext/index/X/block"),
4763
- xChainTransactions: avalancheIndexTransport("/ava/ext/index/X/tx")
4764
- }),
5514
+ cChainBlocks: avalancheIndexTransport(
5515
+ "/ava/ext/index/C/block",
5516
+ "avalanche.index.cChainBlocks"
5517
+ ),
5518
+ pChainBlocks: avalancheIndexTransport(
5519
+ "/ava/ext/index/P/block",
5520
+ "avalanche.index.pChainBlocks"
5521
+ ),
5522
+ xChainBlocks: avalancheIndexTransport(
5523
+ "/ava/ext/index/X/block",
5524
+ "avalanche.index.xChainBlocks"
5525
+ ),
5526
+ xChainTransactions: avalancheIndexTransport(
5527
+ "/ava/ext/index/X/tx",
5528
+ "avalanche.index.xChainTransactions"
5529
+ )
5530
+ }, avalancheNativeTransport),
4765
5531
  subscriptions: new EthereumSubscriptions(avalancheWebSocket)
4766
5532
  };
4767
5533
  const swap = createSwapClient({
@@ -4958,7 +5724,7 @@ var requireFetch2 = (provided) => {
4958
5724
  "A Fetch API implementation is required in this runtime"
4959
5725
  );
4960
5726
  }
4961
- return implementation;
5727
+ return wrapFetch(implementation);
4962
5728
  };
4963
5729
  var cloudEndpoint = (value) => {
4964
5730
  let endpoint;
@@ -5000,6 +5766,1611 @@ var createErpcCloudClient = (config) => {
5000
5766
  };
5001
5767
  };
5002
5768
 
5769
+ // src/generated/bridge_capabilities.ts
5770
+ var BRIDGE_CAPABILITIES_JSON = '[{"bridgeCapabilityId":"bridge-mayan-swift-v2-eurc-eth-sol","providerId":"mayan-swift-v2","capabilityKind":"external-provider-dynamic","sourceChainId":"eip155:1","destinationChainId":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","sourceTokenDeploymentId":"deployment-0011","destinationTokenDeploymentId":"deployment-0013","sourceTokenAddress":"0x1abaea1f7c830bd89acc67ec4af516284b1bc33c","destinationTokenAddress":"HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr","sourceTokenStandard":"erc20","destinationTokenStandard":"spl-token","sourceTokenDecimals":6,"destinationTokenDecimals":6,"sourceProviderChainName":"ethereum","destinationProviderChainName":"solana","sourceProviderChainId":1,"destinationProviderChainId":0,"sourceWormholeChainId":2,"destinationWormholeChainId":1,"sourceUsdcDeploymentId":"deployment-0008","sourceUsdcAddress":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","sourceUsdcStandard":"erc20","sourceUsdcDecimals":6,"swiftContract":"0x40ffe85a28dc9993541449464d7529a922142960","forwarderAddress":"0x337685fdab40d39bd02028545a4ffa7d287cc3e2","forwarderFunctionSelector":"0x30dedc57","jupiterProgramAddress":null,"builderEndpoint":"https://tx-builder.mayan.finance","explorerEndpoint":"https://explorer-api.mayan.finance/v3","dependencies":["mayan-hosted-quote-api","mayan-hosted-transaction-builder","mayan-hosted-source-swap-builder","swift-auction-solvers","relayers","wormhole-guardian-messaging","mayan-explorer-indexer"],"status":"active"},{"bridgeCapabilityId":"bridge-mayan-swift-v2-eurc-sol-eth","providerId":"mayan-swift-v2","capabilityKind":"external-provider-dynamic","sourceChainId":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","destinationChainId":"eip155:1","sourceTokenDeploymentId":"deployment-0013","destinationTokenDeploymentId":"deployment-0011","sourceTokenAddress":"HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr","destinationTokenAddress":"0x1abaea1f7c830bd89acc67ec4af516284b1bc33c","sourceTokenStandard":"spl-token","destinationTokenStandard":"erc20","sourceTokenDecimals":6,"destinationTokenDecimals":6,"sourceProviderChainName":"solana","destinationProviderChainName":"ethereum","sourceProviderChainId":0,"destinationProviderChainId":1,"sourceWormholeChainId":1,"destinationWormholeChainId":2,"sourceUsdcDeploymentId":"deployment-0010","sourceUsdcAddress":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","sourceUsdcStandard":"spl-token","sourceUsdcDecimals":6,"swiftContract":"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny","forwarderAddress":null,"forwarderFunctionSelector":null,"jupiterProgramAddress":"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4","builderEndpoint":"https://tx-builder.mayan.finance","explorerEndpoint":"https://explorer-api.mayan.finance/v3","dependencies":["mayan-hosted-quote-api","mayan-hosted-transaction-builder","mayan-hosted-source-swap-builder","swift-auction-solvers","relayers","wormhole-guardian-messaging","mayan-explorer-indexer","jupiter-v6-source-swap"],"status":"active"}]';
5771
+ var BRIDGE_CAPABILITIES_CONTENT_DIGEST = "fe698f99218057f8cb40b3e24421d1d78e4e2cd7508cf6e3eb2457b329e5141b";
5772
+ var BRIDGE_CAPABILITIES_AS_OF_DATE = "2026-09-16";
5773
+
5774
+ // src/bridge.ts
5775
+ var BRIDGE_ERROR_MESSAGES = Object.freeze({
5776
+ BRIDGE_INVALID_ARGUMENT: "Bridge request is invalid",
5777
+ BRIDGE_UNSUPPORTED_ROUTE: "Bridge route is unsupported",
5778
+ BRIDGE_PROVIDER_AUTH_REQUIRED: "Bridge provider authentication is required",
5779
+ BRIDGE_PROVIDER_TRANSPORT: "Bridge provider transport failed",
5780
+ BRIDGE_PROVIDER_HTTP: "Bridge provider HTTP request failed",
5781
+ BRIDGE_PROVIDER_INVALID_RESPONSE: "Bridge provider response is invalid",
5782
+ BRIDGE_QUOTE_UNAVAILABLE: "Bridge quote is unavailable",
5783
+ BRIDGE_QUOTE_EXPIRED: "Bridge quote is expired",
5784
+ BRIDGE_QUOTE_MISMATCH: "Bridge quote does not match the request",
5785
+ BRIDGE_BUILD_INVALID: "Bridge provider build is invalid",
5786
+ BRIDGE_STATUS_NOT_FOUND: "Bridge status was not found",
5787
+ BRIDGE_TIMEOUT: "Bridge provider request timed out",
5788
+ BRIDGE_ABORTED: "Bridge provider request was aborted"
5789
+ });
5790
+ var BridgeError = class extends Error {
5791
+ code;
5792
+ status;
5793
+ constructor(code, status) {
5794
+ super(BRIDGE_ERROR_MESSAGES[code]);
5795
+ this.name = "BridgeError";
5796
+ this.code = code;
5797
+ if (status !== void 0) this.status = status;
5798
+ }
5799
+ };
5800
+ var ETHEREUM_CHAIN_ID = TOKEN_CHAIN_IDS.ethereumMainnet;
5801
+ var SOLANA_CHAIN_ID = TOKEN_CHAIN_IDS.solanaMainnet;
5802
+ var ETHEREUM_NAME = "ethereum";
5803
+ var SOLANA_NAME = "solana";
5804
+ var ETHEREUM_PROVIDER_CHAIN_ID = 1;
5805
+ var SOLANA_PROVIDER_CHAIN_ID = 0;
5806
+ var ETHEREUM_WORMHOLE_CHAIN_ID = 2;
5807
+ var SOLANA_WORMHOLE_CHAIN_ID = 1;
5808
+ var ETHEREUM_EURC_DEPLOYMENT_ID = "deployment-0011";
5809
+ var SOLANA_EURC_DEPLOYMENT_ID = "deployment-0013";
5810
+ var ETHEREUM_USDC_DEPLOYMENT_ID = "deployment-0008";
5811
+ var SOLANA_USDC_DEPLOYMENT_ID = "deployment-0010";
5812
+ var ETHEREUM_EURC_ADDRESS = "0x1abaea1f7c830bd89acc67ec4af516284b1bc33c";
5813
+ var SOLANA_EURC_ADDRESS = "HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr";
5814
+ var ETHEREUM_USDC_ADDRESS = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
5815
+ var SOLANA_USDC_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
5816
+ var ETHEREUM_SWIFT_CONTRACT = "0x40ffe85a28dc9993541449464d7529a922142960";
5817
+ var SOLANA_SWIFT_PROGRAM = "mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny";
5818
+ var ETHEREUM_FORWARDER = "0x337685fdab40d39bd02028545a4ffa7d287cc3e2";
5819
+ var SOLANA_JUPITER_V6 = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
5820
+ var ETHEREUM_FORWARDER_SELECTOR = "0x30dedc57";
5821
+ var DEFAULT_BUILDER_ENDPOINT = "https://tx-builder.mayan.finance";
5822
+ var DEFAULT_EXPLORER_ENDPOINT = "https://explorer-api.mayan.finance/v3";
5823
+ var DEFAULT_TIMEOUT_MS2 = 3e4;
5824
+ var MAX_RESPONSE_BYTES = 1024 * 1024;
5825
+ var MAX_RAW_QUOTE_BYTES = 256 * 1024;
5826
+ var MAX_JSON_DEPTH = 32;
5827
+ var MAX_QUOTES = 16;
5828
+ var UINT64_MAX = (1n << 64n) - 1n;
5829
+ var CANONICAL_UINT64 = /^(0|[1-9][0-9]*)$/u;
5830
+ var POSITIVE_UINT64 = /^[1-9][0-9]*$/u;
5831
+ var EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/u;
5832
+ var EVM_HASH = /^0x[0-9a-fA-F]{64}$/u;
5833
+ var EVM_SIGNATURE = /^0x[0-9a-fA-F]{130}$/u;
5834
+ var HEX_BYTES2 = /^0x[0-9a-fA-F]*$/u;
5835
+ var BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
5836
+ var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
5837
+ var DEPENDENCIES = Object.freeze([
5838
+ "mayan-hosted-quote-api",
5839
+ "mayan-hosted-transaction-builder",
5840
+ "mayan-hosted-source-swap-builder",
5841
+ "swift-auction-solvers",
5842
+ "relayers",
5843
+ "wormhole-guardian-messaging",
5844
+ "mayan-explorer-indexer"
5845
+ ]);
5846
+ var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5847
+ var deepFreeze6 = (value) => {
5848
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
5849
+ Object.freeze(value);
5850
+ for (const child of Object.values(value)) deepFreeze6(child);
5851
+ }
5852
+ return value;
5853
+ };
5854
+ var parsedCapabilities = JSON.parse(BRIDGE_CAPABILITIES_JSON);
5855
+ var BRIDGE_CAPABILITIES = deepFreeze6(
5856
+ Array.isArray(parsedCapabilities) ? parsedCapabilities : isRecord4(parsedCapabilities) && Array.isArray(parsedCapabilities.capabilities) ? parsedCapabilities.capabilities : []
5857
+ );
5858
+ var fail = (code, status) => {
5859
+ throw new BridgeError(code, status);
5860
+ };
5861
+ var requireRecord = (value, code) => {
5862
+ if (!isRecord4(value)) fail(code);
5863
+ return value;
5864
+ };
5865
+ var requireString = (value, code, nonempty = true) => {
5866
+ if (typeof value !== "string" || nonempty && value.length === 0) fail(code);
5867
+ return value;
5868
+ };
5869
+ var normalizeEvmAddress3 = (value, code) => {
5870
+ const address = requireString(value, code);
5871
+ if (!EVM_ADDRESS2.test(address) || /^0x0{40}$/iu.test(address)) fail(code);
5872
+ return address.toLowerCase();
5873
+ };
5874
+ var normalizePositiveUint64 = (value, code) => {
5875
+ const source = requireString(value, code);
5876
+ if (!POSITIVE_UINT64.test(source) || source.length > 20) fail(code);
5877
+ let parsed;
5878
+ try {
5879
+ parsed = BigInt(source);
5880
+ } catch {
5881
+ return fail(code);
5882
+ }
5883
+ const valueParsed = parsed;
5884
+ if (valueParsed <= 0n || valueParsed > UINT64_MAX) fail(code);
5885
+ return { source, value: valueParsed };
5886
+ };
5887
+ var normalizeCanonicalUint64 = (value, code) => {
5888
+ const source = requireString(value, code);
5889
+ if (!CANONICAL_UINT64.test(source) || source.length > 20) fail(code);
5890
+ let parsed;
5891
+ try {
5892
+ parsed = BigInt(source);
5893
+ } catch {
5894
+ return fail(code);
5895
+ }
5896
+ const valueParsed = parsed;
5897
+ if (valueParsed > UINT64_MAX) fail(code);
5898
+ return { source, value: valueParsed };
5899
+ };
5900
+ var normalizeSlippage = (value, code) => {
5901
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 500) {
5902
+ fail(code);
5903
+ }
5904
+ return value;
5905
+ };
5906
+ var providerAddressEquals = (value, expected) => typeof value === "string" && (EVM_ADDRESS2.test(value) ? value.toLowerCase() === expected.toLowerCase() : value === expected);
5907
+ var catalogTokenMatches = (token, expected) => token?.deploymentId === expected.deploymentId && token.chainId === expected.chainId && token.address !== null && (expected.chainId === ETHEREUM_CHAIN_ID ? token.address.toLowerCase() === expected.address.toLowerCase() : token.address === expected.address) && token.standard === expected.standard && token.decimals === expected.decimals && token.status === "active";
5908
+ var directionFacts = (sourceChainId, destinationChainId) => {
5909
+ if (sourceChainId === ETHEREUM_CHAIN_ID && destinationChainId === SOLANA_CHAIN_ID) {
5910
+ return {
5911
+ sourceChainId,
5912
+ destinationChainId,
5913
+ bridgeCapabilityId: "bridge-mayan-swift-v2-eurc-eth-sol",
5914
+ sourceTokenDeploymentId: ETHEREUM_EURC_DEPLOYMENT_ID,
5915
+ destinationTokenDeploymentId: SOLANA_EURC_DEPLOYMENT_ID,
5916
+ sourceTokenAddress: ETHEREUM_EURC_ADDRESS,
5917
+ destinationTokenAddress: SOLANA_EURC_ADDRESS,
5918
+ sourceTokenStandard: "erc20",
5919
+ destinationTokenStandard: "spl-token",
5920
+ sourceProviderChainId: ETHEREUM_PROVIDER_CHAIN_ID,
5921
+ destinationProviderChainId: SOLANA_PROVIDER_CHAIN_ID,
5922
+ sourceWormholeChainId: ETHEREUM_WORMHOLE_CHAIN_ID,
5923
+ destinationWormholeChainId: SOLANA_WORMHOLE_CHAIN_ID,
5924
+ sourceName: ETHEREUM_NAME,
5925
+ destinationName: SOLANA_NAME,
5926
+ sourceEurcMint: "",
5927
+ destinationEurcMint: SOLANA_EURC_ADDRESS,
5928
+ sourceUsdcDeploymentId: ETHEREUM_USDC_DEPLOYMENT_ID,
5929
+ sourceUsdcAddress: ETHEREUM_USDC_ADDRESS,
5930
+ sourceUsdcStandard: "erc20",
5931
+ swiftContract: ETHEREUM_SWIFT_CONTRACT
5932
+ };
5933
+ }
5934
+ if (sourceChainId === SOLANA_CHAIN_ID && destinationChainId === ETHEREUM_CHAIN_ID) {
5935
+ return {
5936
+ sourceChainId,
5937
+ destinationChainId,
5938
+ bridgeCapabilityId: "bridge-mayan-swift-v2-eurc-sol-eth",
5939
+ sourceTokenDeploymentId: SOLANA_EURC_DEPLOYMENT_ID,
5940
+ destinationTokenDeploymentId: ETHEREUM_EURC_DEPLOYMENT_ID,
5941
+ sourceTokenAddress: SOLANA_EURC_ADDRESS,
5942
+ destinationTokenAddress: ETHEREUM_EURC_ADDRESS,
5943
+ sourceTokenStandard: "spl-token",
5944
+ destinationTokenStandard: "erc20",
5945
+ sourceProviderChainId: SOLANA_PROVIDER_CHAIN_ID,
5946
+ destinationProviderChainId: ETHEREUM_PROVIDER_CHAIN_ID,
5947
+ sourceWormholeChainId: SOLANA_WORMHOLE_CHAIN_ID,
5948
+ destinationWormholeChainId: ETHEREUM_WORMHOLE_CHAIN_ID,
5949
+ sourceName: SOLANA_NAME,
5950
+ destinationName: ETHEREUM_NAME,
5951
+ sourceEurcMint: SOLANA_EURC_ADDRESS,
5952
+ destinationEurcMint: "",
5953
+ sourceUsdcDeploymentId: SOLANA_USDC_DEPLOYMENT_ID,
5954
+ sourceUsdcAddress: SOLANA_USDC_ADDRESS,
5955
+ sourceUsdcStandard: "spl-token",
5956
+ swiftContract: SOLANA_SWIFT_PROGRAM
5957
+ };
5958
+ }
5959
+ return fail("BRIDGE_UNSUPPORTED_ROUTE");
5960
+ };
5961
+ var findCapability = (facts) => {
5962
+ const capability = BRIDGE_CAPABILITIES.find(
5963
+ (entry) => entry.bridgeCapabilityId === facts.bridgeCapabilityId && entry.sourceChainId === facts.sourceChainId && entry.destinationChainId === facts.destinationChainId && entry.sourceTokenDeploymentId === facts.sourceTokenDeploymentId && entry.destinationTokenDeploymentId === facts.destinationTokenDeploymentId
5964
+ );
5965
+ if (!capability) fail("BRIDGE_UNSUPPORTED_ROUTE");
5966
+ return capability;
5967
+ };
5968
+ var validateCatalogDirection = (facts) => {
5969
+ const sourceToken = getTokenDeployment(facts.sourceTokenDeploymentId);
5970
+ const destinationToken = getTokenDeployment(facts.destinationTokenDeploymentId);
5971
+ const sourceUsdc = getTokenDeployment(facts.sourceUsdcDeploymentId);
5972
+ if (!catalogTokenMatches(sourceToken, {
5973
+ deploymentId: facts.sourceTokenDeploymentId,
5974
+ chainId: facts.sourceChainId,
5975
+ address: facts.sourceTokenAddress,
5976
+ standard: facts.sourceTokenStandard,
5977
+ decimals: 6
5978
+ }) || !catalogTokenMatches(destinationToken, {
5979
+ deploymentId: facts.destinationTokenDeploymentId,
5980
+ chainId: facts.destinationChainId,
5981
+ address: facts.destinationTokenAddress,
5982
+ standard: facts.destinationTokenStandard,
5983
+ decimals: 6
5984
+ }) || !catalogTokenMatches(sourceUsdc, {
5985
+ deploymentId: facts.sourceUsdcDeploymentId,
5986
+ chainId: facts.sourceChainId,
5987
+ address: facts.sourceUsdcAddress,
5988
+ standard: facts.sourceUsdcStandard,
5989
+ decimals: 6
5990
+ })) {
5991
+ fail("BRIDGE_UNSUPPORTED_ROUTE");
5992
+ }
5993
+ };
5994
+ var validateCapability = (capability, facts) => {
5995
+ const expected = {
5996
+ bridgeCapabilityId: facts.bridgeCapabilityId,
5997
+ providerId: "mayan-swift-v2",
5998
+ capabilityKind: "external-provider-dynamic",
5999
+ sourceChainId: facts.sourceChainId,
6000
+ destinationChainId: facts.destinationChainId,
6001
+ sourceTokenDeploymentId: facts.sourceTokenDeploymentId,
6002
+ destinationTokenDeploymentId: facts.destinationTokenDeploymentId,
6003
+ sourceTokenAddress: facts.sourceTokenAddress,
6004
+ destinationTokenAddress: facts.destinationTokenAddress,
6005
+ sourceTokenStandard: facts.sourceTokenStandard,
6006
+ destinationTokenStandard: facts.destinationTokenStandard,
6007
+ sourceTokenDecimals: 6,
6008
+ destinationTokenDecimals: 6,
6009
+ sourceProviderChainName: facts.sourceName,
6010
+ destinationProviderChainName: facts.destinationName,
6011
+ sourceProviderChainId: facts.sourceProviderChainId,
6012
+ destinationProviderChainId: facts.destinationProviderChainId,
6013
+ sourceWormholeChainId: facts.sourceWormholeChainId,
6014
+ destinationWormholeChainId: facts.destinationWormholeChainId,
6015
+ sourceUsdcDeploymentId: facts.sourceUsdcDeploymentId,
6016
+ sourceUsdcAddress: facts.sourceUsdcAddress,
6017
+ sourceUsdcStandard: facts.sourceUsdcStandard,
6018
+ sourceUsdcDecimals: 6,
6019
+ swiftContract: facts.swiftContract,
6020
+ forwarderAddress: facts.sourceChainId === ETHEREUM_CHAIN_ID ? ETHEREUM_FORWARDER : null,
6021
+ forwarderFunctionSelector: facts.sourceChainId === ETHEREUM_CHAIN_ID ? "0x30dedc57" : null,
6022
+ jupiterProgramAddress: facts.sourceChainId === SOLANA_CHAIN_ID ? SOLANA_JUPITER_V6 : null,
6023
+ builderEndpoint: DEFAULT_BUILDER_ENDPOINT,
6024
+ explorerEndpoint: DEFAULT_EXPLORER_ENDPOINT,
6025
+ dependencies: facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES],
6026
+ status: "active"
6027
+ };
6028
+ const actualKeys = Object.keys(capability).sort();
6029
+ const expectedKeys = Object.keys(expected).sort();
6030
+ if (actualKeys.length !== expectedKeys.length || actualKeys.some((key, index) => key !== expectedKeys[index])) {
6031
+ fail("BRIDGE_UNSUPPORTED_ROUTE");
6032
+ }
6033
+ for (const key of expectedKeys) {
6034
+ const actual = capability[key];
6035
+ const wanted = expected[key];
6036
+ if (Array.isArray(actual) || Array.isArray(wanted)) {
6037
+ if (JSON.stringify(actual) !== JSON.stringify(wanted)) fail("BRIDGE_UNSUPPORTED_ROUTE");
6038
+ } else if (actual !== wanted) {
6039
+ fail("BRIDGE_UNSUPPORTED_ROUTE");
6040
+ }
6041
+ }
6042
+ };
6043
+ var validateBridgeRoute = (request) => {
6044
+ const value = requireRecord(request, "BRIDGE_INVALID_ARGUMENT");
6045
+ const keys = /* @__PURE__ */ new Set([
6046
+ "sourceChainId",
6047
+ "destinationChainId",
6048
+ "sourceTokenDeploymentId",
6049
+ "destinationTokenDeploymentId",
6050
+ "amountIn",
6051
+ "slippageBps"
6052
+ ]);
6053
+ if (Object.keys(value).some((key) => !keys.has(key))) fail("BRIDGE_INVALID_ARGUMENT");
6054
+ const sourceChainId = requireString(value.sourceChainId, "BRIDGE_INVALID_ARGUMENT");
6055
+ const destinationChainId = requireString(value.destinationChainId, "BRIDGE_INVALID_ARGUMENT");
6056
+ const sourceTokenDeploymentId = requireString(
6057
+ value.sourceTokenDeploymentId,
6058
+ "BRIDGE_INVALID_ARGUMENT"
6059
+ );
6060
+ const destinationTokenDeploymentId = requireString(
6061
+ value.destinationTokenDeploymentId,
6062
+ "BRIDGE_INVALID_ARGUMENT"
6063
+ );
6064
+ const amountIn = normalizePositiveUint64(value.amountIn, "BRIDGE_INVALID_ARGUMENT");
6065
+ const slippageBps = normalizeSlippage(value.slippageBps, "BRIDGE_INVALID_ARGUMENT");
6066
+ const facts = directionFacts(sourceChainId, destinationChainId);
6067
+ if (sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) {
6068
+ fail("BRIDGE_UNSUPPORTED_ROUTE");
6069
+ }
6070
+ validateCatalogDirection(facts);
6071
+ const capability = findCapability(facts);
6072
+ validateCapability(capability, facts);
6073
+ return {
6074
+ request: {
6075
+ sourceChainId,
6076
+ destinationChainId,
6077
+ sourceTokenDeploymentId,
6078
+ destinationTokenDeploymentId,
6079
+ amountIn: amountIn.source,
6080
+ slippageBps
6081
+ },
6082
+ facts,
6083
+ capability
6084
+ };
6085
+ };
6086
+ var isJsonWhitespace = (character) => character === " " || character === "\n" || character === "\r" || character === " ";
6087
+ var StrictJsonParser = class {
6088
+ #source;
6089
+ #index = 0;
6090
+ constructor(source) {
6091
+ this.#source = source;
6092
+ }
6093
+ parse() {
6094
+ this.#skipWhitespace();
6095
+ const value = this.#value(0);
6096
+ this.#skipWhitespace();
6097
+ if (this.#index !== this.#source.length) this.#invalid();
6098
+ return value;
6099
+ }
6100
+ #value(depth) {
6101
+ if (depth > MAX_JSON_DEPTH) this.#invalid();
6102
+ const start = this.#index;
6103
+ const character = this.#source[this.#index];
6104
+ if (character === "{") return this.#object(start, depth);
6105
+ if (character === "[") return this.#array(start, depth);
6106
+ if (character === '"') {
6107
+ const value = this.#string();
6108
+ return { value, start, end: this.#index };
6109
+ }
6110
+ if (character === "t" && this.#source.startsWith("true", this.#index)) {
6111
+ this.#index += 4;
6112
+ return { value: true, start, end: this.#index };
6113
+ }
6114
+ if (character === "f" && this.#source.startsWith("false", this.#index)) {
6115
+ this.#index += 5;
6116
+ return { value: false, start, end: this.#index };
6117
+ }
6118
+ if (character === "n" && this.#source.startsWith("null", this.#index)) {
6119
+ this.#index += 4;
6120
+ return { value: null, start, end: this.#index };
6121
+ }
6122
+ if (character === "-" || character !== void 0 && /[0-9]/u.test(character)) {
6123
+ const rawNumber = this.#number();
6124
+ const value = Number(rawNumber);
6125
+ if (!Number.isFinite(value)) this.#invalid();
6126
+ return { value, start, end: this.#index, rawNumber };
6127
+ }
6128
+ return this.#invalid();
6129
+ }
6130
+ #object(start, depth) {
6131
+ this.#index += 1;
6132
+ this.#skipWhitespace();
6133
+ const object = /* @__PURE__ */ Object.create(null);
6134
+ const entries = /* @__PURE__ */ new Map();
6135
+ if (this.#source[this.#index] === "}") {
6136
+ this.#index += 1;
6137
+ return { value: object, start, end: this.#index, objectEntries: entries };
6138
+ }
6139
+ while (true) {
6140
+ if (this.#source[this.#index] !== '"') this.#invalid();
6141
+ const key = this.#string();
6142
+ if (entries.has(key)) this.#invalid();
6143
+ this.#skipWhitespace();
6144
+ if (this.#source[this.#index] !== ":") this.#invalid();
6145
+ this.#index += 1;
6146
+ this.#skipWhitespace();
6147
+ const child = this.#value(depth + 1);
6148
+ Object.defineProperty(object, key, {
6149
+ configurable: true,
6150
+ enumerable: true,
6151
+ value: child.value,
6152
+ writable: true
6153
+ });
6154
+ entries.set(key, child);
6155
+ this.#skipWhitespace();
6156
+ const delimiter = this.#source[this.#index];
6157
+ if (delimiter === "}") {
6158
+ this.#index += 1;
6159
+ return {
6160
+ value: object,
6161
+ start,
6162
+ end: this.#index,
6163
+ objectEntries: entries
6164
+ };
6165
+ }
6166
+ if (delimiter !== ",") this.#invalid();
6167
+ this.#index += 1;
6168
+ this.#skipWhitespace();
6169
+ }
6170
+ }
6171
+ #array(start, depth) {
6172
+ this.#index += 1;
6173
+ this.#skipWhitespace();
6174
+ const items = [];
6175
+ if (this.#source[this.#index] === "]") {
6176
+ this.#index += 1;
6177
+ return { value: items, start, end: this.#index, arrayItems: items };
6178
+ }
6179
+ while (true) {
6180
+ items.push(this.#value(depth + 1));
6181
+ this.#skipWhitespace();
6182
+ const delimiter = this.#source[this.#index];
6183
+ if (delimiter === "]") {
6184
+ this.#index += 1;
6185
+ return { value: items, start, end: this.#index, arrayItems: items };
6186
+ }
6187
+ if (delimiter !== ",") this.#invalid();
6188
+ this.#index += 1;
6189
+ this.#skipWhitespace();
6190
+ }
6191
+ }
6192
+ #string() {
6193
+ const start = this.#index;
6194
+ this.#index += 1;
6195
+ while (this.#index < this.#source.length) {
6196
+ const character = this.#source[this.#index];
6197
+ if (character === '"') {
6198
+ this.#index += 1;
6199
+ const raw = this.#source.slice(start, this.#index);
6200
+ try {
6201
+ return JSON.parse(raw);
6202
+ } catch {
6203
+ this.#invalid();
6204
+ }
6205
+ }
6206
+ if (character === "\\") {
6207
+ this.#index += 1;
6208
+ const escape = this.#source[this.#index];
6209
+ if (escape === "u") {
6210
+ const digits = this.#source.slice(this.#index + 1, this.#index + 5);
6211
+ if (!/^[0-9a-fA-F]{4}$/u.test(digits)) this.#invalid();
6212
+ this.#index += 5;
6213
+ continue;
6214
+ }
6215
+ if (escape === void 0 || !'"\\/bfnrt'.includes(escape)) this.#invalid();
6216
+ this.#index += 1;
6217
+ continue;
6218
+ }
6219
+ if (character === void 0 || character.charCodeAt(0) < 32) this.#invalid();
6220
+ this.#index += 1;
6221
+ }
6222
+ return this.#invalid();
6223
+ }
6224
+ #number() {
6225
+ const match = /-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/uy.exec(
6226
+ this.#source.slice(this.#index)
6227
+ );
6228
+ if (!match) this.#invalid();
6229
+ const raw = match?.[0];
6230
+ this.#index += raw.length;
6231
+ return raw;
6232
+ }
6233
+ #skipWhitespace() {
6234
+ while (this.#index < this.#source.length && isJsonWhitespace(this.#source[this.#index] ?? "")) {
6235
+ this.#index += 1;
6236
+ }
6237
+ }
6238
+ #invalid() {
6239
+ return fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6240
+ }
6241
+ };
6242
+ var parseProviderResponse = (text) => {
6243
+ let root;
6244
+ try {
6245
+ root = new StrictJsonParser(text).parse();
6246
+ } catch (error) {
6247
+ if (error instanceof BridgeError) throw error;
6248
+ return fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6249
+ }
6250
+ return { text, root };
6251
+ };
6252
+ var objectEntry = (node, key) => node.objectEntries?.get(key);
6253
+ var objectValue5 = (node, key) => objectEntry(node, key)?.value;
6254
+ var byteLength = (value) => new TextEncoder().encode(value).byteLength;
6255
+ var requestAbortError = () => new DOMException("The bridge provider request was aborted", "AbortError");
6256
+ var throwIfRequestAborted = (controlled, external) => {
6257
+ if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
6258
+ if (external?.aborted) fail("BRIDGE_ABORTED");
6259
+ };
6260
+ var readWithSignal = async (reader, signal) => {
6261
+ if (signal.aborted) throw signal.reason ?? requestAbortError();
6262
+ return new Promise((resolve, reject) => {
6263
+ let settled = false;
6264
+ const cleanup = () => {
6265
+ signal.removeEventListener("abort", onAbort);
6266
+ };
6267
+ const onAbort = () => {
6268
+ if (settled) return;
6269
+ settled = true;
6270
+ cleanup();
6271
+ reject(signal.reason ?? requestAbortError());
6272
+ };
6273
+ signal.addEventListener("abort", onAbort, { once: true });
6274
+ let read;
6275
+ try {
6276
+ read = reader.read();
6277
+ } catch (error) {
6278
+ if (settled) return;
6279
+ settled = true;
6280
+ cleanup();
6281
+ reject(error);
6282
+ return;
6283
+ }
6284
+ void read.then(
6285
+ (result) => {
6286
+ if (settled) return;
6287
+ settled = true;
6288
+ cleanup();
6289
+ resolve(result);
6290
+ },
6291
+ (error) => {
6292
+ if (settled) return;
6293
+ settled = true;
6294
+ cleanup();
6295
+ reject(error);
6296
+ }
6297
+ );
6298
+ });
6299
+ };
6300
+ var cancelResponseBody = (response) => {
6301
+ const body = response.body;
6302
+ if (body === null || response.bodyUsed) return;
6303
+ try {
6304
+ void body.cancel().catch(() => void 0);
6305
+ } catch {
6306
+ }
6307
+ };
6308
+ var decodeResponseBody = async (response, controlled, external) => {
6309
+ throwIfRequestAborted(controlled, external);
6310
+ const contentLength = response.headers.get("content-length");
6311
+ if (contentLength !== null && /^\d+$/u.test(contentLength)) {
6312
+ try {
6313
+ if (BigInt(contentLength) > BigInt(MAX_RESPONSE_BYTES)) {
6314
+ fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6315
+ }
6316
+ } catch {
6317
+ }
6318
+ }
6319
+ const body = response.body;
6320
+ if (body === null) return "";
6321
+ let reader;
6322
+ try {
6323
+ reader = body.getReader();
6324
+ } catch {
6325
+ return fail("BRIDGE_PROVIDER_TRANSPORT");
6326
+ }
6327
+ const chunks = [];
6328
+ let totalBytes = 0;
6329
+ let bodyComplete = false;
6330
+ const releaseReader = () => {
6331
+ try {
6332
+ reader.releaseLock();
6333
+ } catch {
6334
+ }
6335
+ };
6336
+ try {
6337
+ while (true) {
6338
+ let result;
6339
+ try {
6340
+ result = await readWithSignal(reader, controlled.signal);
6341
+ } catch (error) {
6342
+ throwIfRequestAborted(controlled, external);
6343
+ if (error instanceof BridgeError) throw error;
6344
+ return fail("BRIDGE_PROVIDER_TRANSPORT");
6345
+ }
6346
+ throwIfRequestAborted(controlled, external);
6347
+ if (result.done) {
6348
+ bodyComplete = true;
6349
+ break;
6350
+ }
6351
+ const chunk = result.value;
6352
+ if (!(chunk instanceof Uint8Array)) return fail("BRIDGE_PROVIDER_TRANSPORT");
6353
+ totalBytes += chunk.byteLength;
6354
+ if (totalBytes > MAX_RESPONSE_BYTES) {
6355
+ fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6356
+ }
6357
+ chunks.push(chunk);
6358
+ }
6359
+ throwIfRequestAborted(controlled, external);
6360
+ const bytes = new Uint8Array(totalBytes);
6361
+ let offset = 0;
6362
+ for (const chunk of chunks) {
6363
+ bytes.set(chunk, offset);
6364
+ offset += chunk.byteLength;
6365
+ }
6366
+ try {
6367
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
6368
+ } catch {
6369
+ return fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6370
+ }
6371
+ } finally {
6372
+ if (!bodyComplete) {
6373
+ try {
6374
+ const cancellation = reader.cancel();
6375
+ void cancellation.then(releaseReader, releaseReader);
6376
+ } catch {
6377
+ }
6378
+ }
6379
+ releaseReader();
6380
+ }
6381
+ };
6382
+ var CONFIG_KEYS = /* @__PURE__ */ new Set([
6383
+ "builderEndpoint",
6384
+ "explorerEndpoint",
6385
+ "builderApiKey",
6386
+ "allowUnauthenticatedBuild",
6387
+ "minimumQuoteValiditySeconds",
6388
+ "timeoutMs",
6389
+ "fetch"
6390
+ ]);
6391
+ var endpointWithPath2 = (base, path) => new URL(path.replace(/^\/+/, ""), `${base.toString().replace(/\/+$/u, "")}/`);
6392
+ var normalizeProviderEndpoint = (value, fallback, label) => {
6393
+ const sourceValue = value === void 0 ? fallback : value;
6394
+ if (typeof sourceValue !== "string") return fail("BRIDGE_INVALID_ARGUMENT");
6395
+ const source = sourceValue;
6396
+ if (source.length === 0 || source.trim() !== source) {
6397
+ fail("BRIDGE_INVALID_ARGUMENT");
6398
+ }
6399
+ if (!/^[a-z][a-z\d+.-]*:\/\//iu.test(source) || source.includes("#")) {
6400
+ fail("BRIDGE_INVALID_ARGUMENT");
6401
+ }
6402
+ const authorityStart = source.indexOf("://") + 3;
6403
+ const authority = source.slice(authorityStart).split(/[/?#]/u, 1)[0] ?? "";
6404
+ if (authority.length === 0 || authority.includes("@")) fail("BRIDGE_INVALID_ARGUMENT");
6405
+ let endpoint;
6406
+ try {
6407
+ endpoint = new URL(source);
6408
+ } catch {
6409
+ return fail("BRIDGE_INVALID_ARGUMENT");
6410
+ }
6411
+ if (endpoint.protocol !== "https:" && !(endpoint.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]", "::1"].includes(endpoint.hostname))) {
6412
+ fail("BRIDGE_INVALID_ARGUMENT");
6413
+ }
6414
+ if (!endpoint.hostname || endpoint.username || endpoint.password || source.includes("?") || endpoint.search || endpoint.hash) {
6415
+ fail("BRIDGE_INVALID_ARGUMENT");
6416
+ }
6417
+ if (endpoint.port !== "" && (!/^\d+$/u.test(endpoint.port) || Number(endpoint.port) > 65535)) {
6418
+ fail("BRIDGE_INVALID_ARGUMENT");
6419
+ }
6420
+ endpoint.pathname = endpoint.pathname.replace(/\/+$/u, "") || "/";
6421
+ if (!endpoint.pathname.startsWith("/")) fail("BRIDGE_INVALID_ARGUMENT");
6422
+ return endpoint;
6423
+ };
6424
+ var normalizeBridgeConfig = (config) => {
6425
+ const value = config === void 0 ? {} : requireRecord(config, "BRIDGE_INVALID_ARGUMENT");
6426
+ if (Object.keys(value).some((key) => !CONFIG_KEYS.has(key))) {
6427
+ fail("BRIDGE_INVALID_ARGUMENT");
6428
+ }
6429
+ const builderEndpoint = normalizeProviderEndpoint(
6430
+ value.builderEndpoint,
6431
+ DEFAULT_BUILDER_ENDPOINT);
6432
+ const explorerEndpoint = normalizeProviderEndpoint(
6433
+ value.explorerEndpoint,
6434
+ DEFAULT_EXPLORER_ENDPOINT);
6435
+ let builderApiKey;
6436
+ if (value.builderApiKey !== void 0) {
6437
+ const builderApiKeyValue = value.builderApiKey;
6438
+ if (typeof builderApiKeyValue !== "string" || /[\u0000-\u001f\u007f]/u.test(builderApiKeyValue)) {
6439
+ fail("BRIDGE_INVALID_ARGUMENT");
6440
+ }
6441
+ const validatedBuilderApiKey = builderApiKeyValue;
6442
+ builderApiKey = validatedBuilderApiKey.length === 0 ? void 0 : validatedBuilderApiKey;
6443
+ }
6444
+ const allowUnauthenticatedBuildValue = value.allowUnauthenticatedBuild ?? false;
6445
+ if (typeof allowUnauthenticatedBuildValue !== "boolean") {
6446
+ fail("BRIDGE_INVALID_ARGUMENT");
6447
+ }
6448
+ const allowUnauthenticatedBuild = allowUnauthenticatedBuildValue;
6449
+ const minimumQuoteValiditySecondsValue = value.minimumQuoteValiditySeconds ?? 60;
6450
+ if (typeof minimumQuoteValiditySecondsValue !== "number" || !Number.isSafeInteger(minimumQuoteValiditySecondsValue) || minimumQuoteValiditySecondsValue < 0 || minimumQuoteValiditySecondsValue > 300) {
6451
+ fail("BRIDGE_INVALID_ARGUMENT");
6452
+ }
6453
+ const minimumQuoteValiditySeconds = minimumQuoteValiditySecondsValue;
6454
+ const timeoutMsValue = value.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
6455
+ if (typeof timeoutMsValue !== "number" || !Number.isSafeInteger(timeoutMsValue) || timeoutMsValue <= 0) {
6456
+ fail("BRIDGE_INVALID_ARGUMENT");
6457
+ }
6458
+ const timeoutMs = timeoutMsValue;
6459
+ const implementation = value.fetch ?? globalThis.fetch;
6460
+ if (typeof implementation !== "function") fail("BRIDGE_INVALID_ARGUMENT");
6461
+ return Object.freeze({
6462
+ builderEndpoint,
6463
+ explorerEndpoint,
6464
+ ...builderApiKey === void 0 ? {} : { builderApiKey },
6465
+ allowUnauthenticatedBuild,
6466
+ minimumQuoteValiditySeconds,
6467
+ timeoutMs,
6468
+ fetch: wrapFetch(implementation)
6469
+ });
6470
+ };
6471
+ var requestSignal = (timeoutMs, external) => {
6472
+ const controller = new AbortController();
6473
+ let timedOut = false;
6474
+ const timeout = setTimeout(() => {
6475
+ timedOut = true;
6476
+ controller.abort();
6477
+ }, timeoutMs);
6478
+ const onAbort = () => controller.abort();
6479
+ if (external?.aborted) controller.abort();
6480
+ else external?.addEventListener("abort", onAbort, { once: true });
6481
+ return {
6482
+ signal: controller.signal,
6483
+ timedOut: () => timedOut,
6484
+ cleanup: () => {
6485
+ clearTimeout(timeout);
6486
+ external?.removeEventListener("abort", onAbort);
6487
+ }
6488
+ };
6489
+ };
6490
+ var providerRequest = async (config, endpoint, method, body, includeBuilderKey, options) => {
6491
+ if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
6492
+ const controlled = requestSignal(config.timeoutMs, options?.signal);
6493
+ try {
6494
+ const headers = {};
6495
+ headers.accept = "application/json";
6496
+ if (body !== void 0) headers["content-type"] = "application/json";
6497
+ if (includeBuilderKey && config.builderApiKey !== void 0) {
6498
+ headers["x-api-key"] = config.builderApiKey;
6499
+ }
6500
+ let response;
6501
+ try {
6502
+ response = await config.fetch(endpoint, {
6503
+ method,
6504
+ headers,
6505
+ ...body === void 0 ? {} : { body },
6506
+ signal: controlled.signal,
6507
+ credentials: "omit",
6508
+ redirect: "manual"
6509
+ });
6510
+ if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
6511
+ if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
6512
+ } catch {
6513
+ if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
6514
+ if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
6515
+ return fail("BRIDGE_PROVIDER_TRANSPORT");
6516
+ }
6517
+ return {
6518
+ response,
6519
+ controlled,
6520
+ external: options?.signal
6521
+ };
6522
+ } catch (error) {
6523
+ controlled.cleanup();
6524
+ if (error instanceof BridgeError) throw error;
6525
+ if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
6526
+ if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
6527
+ return fail("BRIDGE_PROVIDER_TRANSPORT");
6528
+ }
6529
+ };
6530
+ var providerHttpStatus = (response, kind) => {
6531
+ if (kind === "status" && response.status === 404) fail("BRIDGE_STATUS_NOT_FOUND");
6532
+ if (response.status >= 300 && response.status < 400) {
6533
+ fail("BRIDGE_PROVIDER_TRANSPORT");
6534
+ }
6535
+ if (kind === "build" && (response.status === 401 || response.status === 403)) {
6536
+ fail("BRIDGE_PROVIDER_AUTH_REQUIRED");
6537
+ }
6538
+ if (response.status !== 200 && response.status !== 201) {
6539
+ fail("BRIDGE_PROVIDER_HTTP", response.status);
6540
+ }
6541
+ };
6542
+ var providerJson = async (request, kind) => {
6543
+ try {
6544
+ providerHttpStatus(request.response, kind);
6545
+ const text = await decodeResponseBody(
6546
+ request.response,
6547
+ request.controlled,
6548
+ request.external
6549
+ );
6550
+ throwIfRequestAborted(request.controlled, request.external);
6551
+ const parsed = parseProviderResponse(text);
6552
+ throwIfRequestAborted(request.controlled, request.external);
6553
+ return parsed;
6554
+ } finally {
6555
+ cancelResponseBody(request.response);
6556
+ request.controlled.cleanup();
6557
+ }
6558
+ };
6559
+ var encodeBase58 = (bytes) => {
6560
+ let zeroes = 0;
6561
+ while (zeroes < bytes.length && bytes[zeroes] === 0) zeroes += 1;
6562
+ if (zeroes === bytes.length) return "1".repeat(zeroes);
6563
+ const digits = [0];
6564
+ for (const byte of bytes) {
6565
+ let carry = byte;
6566
+ for (let index = 0; index < digits.length; index += 1) {
6567
+ const value = (digits[index] ?? 0) * 256 + carry;
6568
+ digits[index] = value % 58;
6569
+ carry = Math.floor(value / 58);
6570
+ }
6571
+ while (carry > 0) {
6572
+ digits.push(carry % 58);
6573
+ carry = Math.floor(carry / 58);
6574
+ }
6575
+ }
6576
+ let result = "1".repeat(zeroes);
6577
+ for (let index = digits.length - 1; index >= 0; index -= 1) {
6578
+ result += BASE58_ALPHABET[digits[index] ?? 0] ?? "";
6579
+ }
6580
+ return result === "" ? "1" : result;
6581
+ };
6582
+ var decodeBase58 = (value, expectedBytes, code) => {
6583
+ const text = requireString(value, code);
6584
+ if (text.length > expectedBytes * 2 || [...text].some((char) => !BASE58_ALPHABET.includes(char))) {
6585
+ fail(code);
6586
+ }
6587
+ const bytes = [0];
6588
+ for (const char of text) {
6589
+ const digit = BASE58_ALPHABET.indexOf(char);
6590
+ let carry = digit;
6591
+ for (let index = 0; index < bytes.length; index += 1) {
6592
+ const current = (bytes[index] ?? 0) * 58 + carry;
6593
+ bytes[index] = current % 256;
6594
+ carry = Math.floor(current / 256);
6595
+ }
6596
+ while (carry > 0) {
6597
+ bytes.push(carry % 256);
6598
+ carry = Math.floor(carry / 256);
6599
+ }
6600
+ }
6601
+ let zeroes = 0;
6602
+ while (zeroes < text.length && text[zeroes] === "1") zeroes += 1;
6603
+ const result = new Uint8Array(zeroes + (bytes.length === 1 && bytes[0] === 0 ? 0 : bytes.length));
6604
+ for (let index = 0; index < bytes.length && !(bytes.length === 1 && bytes[0] === 0); index += 1) {
6605
+ result[result.length - 1 - index] = bytes[index] ?? 0;
6606
+ }
6607
+ if (result.length !== expectedBytes || encodeBase58(result) !== text) fail(code);
6608
+ return result;
6609
+ };
6610
+ var decodeBase64 = (value, code) => {
6611
+ const text = requireString(value, code);
6612
+ if (!BASE64.test(text)) fail(code);
6613
+ let binary;
6614
+ try {
6615
+ binary = globalThis.atob(text);
6616
+ } catch {
6617
+ return fail(code);
6618
+ }
6619
+ const result = Uint8Array.from(binary, (character) => character.charCodeAt(0));
6620
+ let canonical;
6621
+ try {
6622
+ canonical = globalThis.btoa(binary);
6623
+ } catch {
6624
+ return fail(code);
6625
+ }
6626
+ if (canonical !== text) fail(code);
6627
+ return result;
6628
+ };
6629
+ var readBytes = (cursor, count, code) => {
6630
+ if (!Number.isSafeInteger(count) || count < 0 || cursor.index + count > cursor.bytes.length) fail(code);
6631
+ const value = cursor.bytes.slice(cursor.index, cursor.index + count);
6632
+ cursor.index += count;
6633
+ return value;
6634
+ };
6635
+ var readShortVec = (cursor, maximum, code) => {
6636
+ let value = 0;
6637
+ let shift = 0;
6638
+ for (let count = 0; count < 5; count += 1) {
6639
+ const byte = readBytes(cursor, 1, code)[0] ?? 0;
6640
+ const payload = byte & 127;
6641
+ if (shift >= 28 || payload > Math.floor(Number.MAX_SAFE_INTEGER / 2 ** shift)) fail(code);
6642
+ value += payload * 2 ** shift;
6643
+ if ((byte & 128) === 0) {
6644
+ if (count > 0 && payload === 0) fail(code);
6645
+ if (!Number.isSafeInteger(value) || value > maximum) fail(code);
6646
+ return value;
6647
+ }
6648
+ shift += 7;
6649
+ }
6650
+ return fail(code);
6651
+ };
6652
+ var allZero = (bytes) => bytes.every((byte) => byte === 0);
6653
+ var validateSolanaTransaction = (encoded, feePayer) => {
6654
+ const bytes = decodeBase64(encoded, "BRIDGE_BUILD_INVALID");
6655
+ if (bytes.byteLength === 0 || bytes.byteLength > 1232) fail("BRIDGE_BUILD_INVALID");
6656
+ const cursor = { bytes, index: 0 };
6657
+ const signatureCount = readShortVec(cursor, 1, "BRIDGE_BUILD_INVALID");
6658
+ if (signatureCount !== 1 || !allZero(readBytes(cursor, 64, "BRIDGE_BUILD_INVALID"))) {
6659
+ fail("BRIDGE_BUILD_INVALID");
6660
+ }
6661
+ const version = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0];
6662
+ if (version !== 128) fail("BRIDGE_BUILD_INVALID");
6663
+ const requiredSignatures = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0;
6664
+ const readonlySigned = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0;
6665
+ const readonlyUnsigned = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0;
6666
+ if (requiredSignatures !== 1 || readonlySigned !== 0) fail("BRIDGE_BUILD_INVALID");
6667
+ const staticKeyCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
6668
+ if (staticKeyCount === 0 || readonlyUnsigned >= staticKeyCount) fail("BRIDGE_BUILD_INVALID");
6669
+ const staticKeys = readBytes(cursor, staticKeyCount * 32, "BRIDGE_BUILD_INVALID");
6670
+ const payerBytes = decodeBase58(feePayer, 32, "BRIDGE_BUILD_INVALID");
6671
+ if (!staticKeys.slice(0, 32).every((byte, index) => byte === payerBytes[index])) fail("BRIDGE_BUILD_INVALID");
6672
+ readBytes(cursor, 32, "BRIDGE_BUILD_INVALID");
6673
+ const instructionCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
6674
+ let largestAccountIndex = -1;
6675
+ for (let instruction = 0; instruction < instructionCount; instruction += 1) {
6676
+ largestAccountIndex = Math.max(
6677
+ largestAccountIndex,
6678
+ readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0
6679
+ );
6680
+ const accountCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
6681
+ const accountIndices = readBytes(cursor, accountCount, "BRIDGE_BUILD_INVALID");
6682
+ for (const index of accountIndices) largestAccountIndex = Math.max(largestAccountIndex, index);
6683
+ const dataLength = readShortVec(cursor, 1024, "BRIDGE_BUILD_INVALID");
6684
+ readBytes(cursor, dataLength, "BRIDGE_BUILD_INVALID");
6685
+ }
6686
+ const lookupCount = readShortVec(cursor, 32, "BRIDGE_BUILD_INVALID");
6687
+ let loadedAddressCount = 0;
6688
+ for (let lookup = 0; lookup < lookupCount; lookup += 1) {
6689
+ readBytes(cursor, 32, "BRIDGE_BUILD_INVALID");
6690
+ const writableCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
6691
+ readBytes(cursor, writableCount, "BRIDGE_BUILD_INVALID");
6692
+ const readonlyCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
6693
+ readBytes(cursor, readonlyCount, "BRIDGE_BUILD_INVALID");
6694
+ loadedAddressCount += writableCount + readonlyCount;
6695
+ if (loadedAddressCount > 256) fail("BRIDGE_BUILD_INVALID");
6696
+ }
6697
+ if (largestAccountIndex >= staticKeyCount + loadedAddressCount || cursor.index !== bytes.length) {
6698
+ fail("BRIDGE_BUILD_INVALID");
6699
+ }
6700
+ return requireString(encoded, "BRIDGE_BUILD_INVALID");
6701
+ };
6702
+ var providerInvalid = () => fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6703
+ var requiredNode = (node, key) => {
6704
+ const child = objectEntry(node, key);
6705
+ if (!child) providerInvalid();
6706
+ return child;
6707
+ };
6708
+ var providerString = (node, key, allowEmpty = false) => {
6709
+ const value = requiredNode(node, key).value;
6710
+ if (typeof value !== "string" || !allowEmpty && value.length === 0) {
6711
+ providerInvalid();
6712
+ }
6713
+ return value;
6714
+ };
6715
+ var providerBoolean = (node, key) => {
6716
+ const value = requiredNode(node, key).value;
6717
+ if (typeof value !== "boolean") providerInvalid();
6718
+ return value;
6719
+ };
6720
+ var providerNumber = (node, key) => {
6721
+ const value = requiredNode(node, key).value;
6722
+ if (typeof value !== "number" || !Number.isFinite(value)) providerInvalid();
6723
+ return value;
6724
+ };
6725
+ var providerInteger = (node, key) => {
6726
+ const value = providerNumber(node, key);
6727
+ if (!Number.isSafeInteger(value)) providerInvalid();
6728
+ return value;
6729
+ };
6730
+ var providerAddress = (node, key, expected) => {
6731
+ const value = providerString(node, key);
6732
+ if (!providerAddressEquals(value, expected)) providerInvalid();
6733
+ return EVM_ADDRESS2.test(value) ? value.toLowerCase() : value;
6734
+ };
6735
+ var providerUint64 = (node, key, positive) => {
6736
+ const value = providerString(node, key);
6737
+ try {
6738
+ return positive ? normalizePositiveUint64(value, "BRIDGE_PROVIDER_INVALID_RESPONSE") : normalizeCanonicalUint64(value, "BRIDGE_PROVIDER_INVALID_RESPONSE");
6739
+ } catch (error) {
6740
+ if (error instanceof BridgeError) throw error;
6741
+ return providerInvalid();
6742
+ }
6743
+ };
6744
+ var providerToken = (node, expected) => {
6745
+ if (!isRecord4(node.value)) providerInvalid();
6746
+ const contract = providerString(node, "contract");
6747
+ if (!providerAddressEquals(contract, expected.address)) providerInvalid();
6748
+ const mint = providerString(node, "mint", true);
6749
+ if (mint !== expected.mint) providerInvalid();
6750
+ const realOrigin = providerString(node, "realOriginContractAddress");
6751
+ if (!providerAddressEquals(realOrigin, expected.address)) providerInvalid();
6752
+ if (providerString(node, "name") !== "EuroC") providerInvalid();
6753
+ if (providerString(node, "standard") !== expected.standard) providerInvalid();
6754
+ if (providerInteger(node, "chainId") !== expected.chainId) providerInvalid();
6755
+ if (providerInteger(node, "wChainId") !== expected.wormholeChainId) providerInvalid();
6756
+ if (providerInteger(node, "realOriginChainId") !== expected.wormholeChainId) providerInvalid();
6757
+ if (providerInteger(node, "decimals") !== 6) providerInvalid();
6758
+ };
6759
+ var quoteProviderStandard = (facts) => facts.sourceChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl";
6760
+ var ensureQuoteDeadline = (deadlineValue, margin) => {
6761
+ const now = BigInt(Math.floor(Date.now() / 1e3));
6762
+ if (!Number.isSafeInteger(Number(now)) || deadlineValue < now + BigInt(margin)) {
6763
+ fail("BRIDGE_QUOTE_EXPIRED");
6764
+ }
6765
+ };
6766
+ var validateProviderQuote = (node, text, request, facts, config) => {
6767
+ if (!isRecord4(node.value)) providerInvalid();
6768
+ const raw = text.slice(node.start, node.end);
6769
+ if (byteLength(raw) > MAX_RAW_QUOTE_BYTES) providerInvalid();
6770
+ if (providerString(node, "type") !== "SWIFT") providerInvalid();
6771
+ if (providerString(node, "swiftVersion") !== "V2") providerInvalid();
6772
+ if (providerBoolean(node, "gasless")) providerInvalid();
6773
+ if (providerString(node, "fromChain") !== facts.sourceName) providerInvalid();
6774
+ if (providerString(node, "toChain") !== facts.destinationName) providerInvalid();
6775
+ if (providerInteger(node, "slippageBps") !== request.slippageBps) providerInvalid();
6776
+ if (providerBoolean(node, "onlyBridging")) providerInvalid();
6777
+ const effectiveAmount = providerUint64(node, "effectiveAmountIn64", true);
6778
+ if (effectiveAmount.source !== request.amountIn) providerInvalid();
6779
+ const expectedAmountOut = providerUint64(node, "expectedAmountOutBaseUnits", true);
6780
+ const minimumAmountOut = providerUint64(node, "minAmountOutBaseUnits", true);
6781
+ const minimumReceived = providerUint64(node, "minReceivedBaseUnits", true);
6782
+ if (minimumAmountOut.value > expectedAmountOut.value || minimumReceived.value > minimumAmountOut.value) {
6783
+ providerInvalid();
6784
+ }
6785
+ const deadline = providerUint64(node, "deadline64", true);
6786
+ ensureQuoteDeadline(deadline.value, config.minimumQuoteValiditySeconds);
6787
+ const sourceToken = requiredNode(node, "fromToken");
6788
+ const destinationToken = requiredNode(node, "toToken");
6789
+ providerToken(sourceToken, {
6790
+ address: facts.sourceTokenAddress,
6791
+ standard: facts.sourceChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl",
6792
+ chainId: facts.sourceProviderChainId,
6793
+ wormholeChainId: facts.sourceWormholeChainId,
6794
+ mint: facts.sourceEurcMint
6795
+ });
6796
+ providerToken(destinationToken, {
6797
+ address: facts.destinationTokenAddress,
6798
+ standard: facts.destinationChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl",
6799
+ chainId: facts.destinationProviderChainId,
6800
+ wormholeChainId: facts.destinationWormholeChainId,
6801
+ mint: facts.destinationEurcMint
6802
+ });
6803
+ const sourceUsdcStandard = quoteProviderStandard(facts);
6804
+ if (providerAddress(node, "swiftInputContract", facts.sourceUsdcAddress) !== facts.sourceUsdcAddress) {
6805
+ providerInvalid();
6806
+ }
6807
+ if (providerString(node, "swiftInputContractStandard") !== sourceUsdcStandard) providerInvalid();
6808
+ if (providerInteger(node, "swiftInputDecimals") !== 6) providerInvalid();
6809
+ if (providerAddress(node, "swiftMayanContract", facts.swiftContract) !== facts.swiftContract) {
6810
+ providerInvalid();
6811
+ }
6812
+ const middleNode = requiredNode(node, "minMiddleAmount");
6813
+ if (middleNode.rawNumber === void 0 || typeof middleNode.value !== "number" || !Number.isFinite(middleNode.value) || middleNode.value <= 0) {
6814
+ providerInvalid();
6815
+ }
6816
+ let routerAddress;
6817
+ let routerKind;
6818
+ if (facts.sourceChainId === ETHEREUM_CHAIN_ID) {
6819
+ routerAddress = normalizeEvmAddress3(
6820
+ providerString(node, "evmSwapRouterAddress"),
6821
+ "BRIDGE_PROVIDER_INVALID_RESPONSE"
6822
+ );
6823
+ routerKind = "provider-selected-evm";
6824
+ } else {
6825
+ routerAddress = SOLANA_JUPITER_V6;
6826
+ routerKind = "jupiter-v6";
6827
+ const evmRouter = objectValue5(node, "evmSwapRouterAddress");
6828
+ if (evmRouter !== void 0 && evmRouter !== null) providerInvalid();
6829
+ }
6830
+ const quoteId = providerString(node, "quoteId");
6831
+ if (!/^0x[0-9a-fA-F]{32}$/u.test(quoteId)) providerInvalid();
6832
+ const signature = providerString(node, "signature");
6833
+ if (!EVM_SIGNATURE.test(signature)) providerInvalid();
6834
+ const dependencies = facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
6835
+ const quote = {
6836
+ quoteKind: "mayan-swift-v2",
6837
+ providerId: "mayan-swift-v2",
6838
+ sourceChainId: request.sourceChainId,
6839
+ destinationChainId: request.destinationChainId,
6840
+ sourceTokenDeploymentId: request.sourceTokenDeploymentId,
6841
+ destinationTokenDeploymentId: request.destinationTokenDeploymentId,
6842
+ amountIn: effectiveAmount.source,
6843
+ expectedAmountOut: expectedAmountOut.source,
6844
+ minimumAmountOut: minimumAmountOut.source,
6845
+ minimumReceived: minimumReceived.source,
6846
+ deadline: deadline.source,
6847
+ slippageBps: request.slippageBps,
6848
+ quoteId: quoteId.toLowerCase(),
6849
+ providerSignature: signature.toLowerCase(),
6850
+ sourceSwap: {
6851
+ required: true,
6852
+ inputTokenDeploymentId: facts.sourceTokenDeploymentId,
6853
+ intermediateTokenDeploymentId: facts.sourceUsdcDeploymentId,
6854
+ intermediateTokenAddress: facts.sourceUsdcAddress,
6855
+ intermediateTokenStandard: sourceUsdcStandard,
6856
+ intermediateTokenDecimals: 6,
6857
+ providerMinimumAmount: middleNode.rawNumber,
6858
+ routerKind,
6859
+ routerAddress
6860
+ },
6861
+ dependencies,
6862
+ quoteVerification: "provider-signed-not-locally-verified",
6863
+ rawSignedQuoteJson: raw
6864
+ };
6865
+ return {
6866
+ quote: deepFreeze6(quote),
6867
+ rawNode: node,
6868
+ deadlineValue: deadline.value
6869
+ };
6870
+ };
6871
+ var QUOTE_KEYS = [
6872
+ "quoteKind",
6873
+ "providerId",
6874
+ "sourceChainId",
6875
+ "destinationChainId",
6876
+ "sourceTokenDeploymentId",
6877
+ "destinationTokenDeploymentId",
6878
+ "amountIn",
6879
+ "expectedAmountOut",
6880
+ "minimumAmountOut",
6881
+ "minimumReceived",
6882
+ "deadline",
6883
+ "slippageBps",
6884
+ "quoteId",
6885
+ "providerSignature",
6886
+ "sourceSwap",
6887
+ "dependencies",
6888
+ "quoteVerification",
6889
+ "rawSignedQuoteJson"
6890
+ ];
6891
+ var SOURCE_SWAP_KEYS = [
6892
+ "required",
6893
+ "inputTokenDeploymentId",
6894
+ "intermediateTokenDeploymentId",
6895
+ "intermediateTokenAddress",
6896
+ "intermediateTokenStandard",
6897
+ "intermediateTokenDecimals",
6898
+ "providerMinimumAmount",
6899
+ "routerKind",
6900
+ "routerAddress"
6901
+ ];
6902
+ var exactObjectKeys = (value, expected, code) => {
6903
+ const actual = Object.keys(value).sort();
6904
+ const wanted = [...expected].sort();
6905
+ if (actual.length !== wanted.length || actual.some((key, index) => key !== wanted[index])) {
6906
+ fail(code);
6907
+ }
6908
+ };
6909
+ var stableJson = (value) => {
6910
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
6911
+ if (isRecord4(value)) {
6912
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
6913
+ }
6914
+ return JSON.stringify(value);
6915
+ };
6916
+ var cloneQuote = (quote) => {
6917
+ try {
6918
+ return JSON.parse(JSON.stringify(quote));
6919
+ } catch {
6920
+ return fail("BRIDGE_INVALID_ARGUMENT");
6921
+ }
6922
+ };
6923
+ var validateNormalizedQuoteShape = (quote, code) => {
6924
+ const value = requireRecord(quote, code);
6925
+ exactObjectKeys(value, QUOTE_KEYS, code);
6926
+ if (value.quoteKind !== "mayan-swift-v2" || value.providerId !== "mayan-swift-v2") fail(code);
6927
+ const sourceChainId = requireString(value.sourceChainId, code);
6928
+ const destinationChainId = requireString(value.destinationChainId, code);
6929
+ const facts = directionFacts(sourceChainId, destinationChainId);
6930
+ if (value.sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || value.destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) fail(code);
6931
+ const amountIn = normalizePositiveUint64(value.amountIn, code);
6932
+ const expectedAmountOut = normalizePositiveUint64(value.expectedAmountOut, code);
6933
+ const minimumAmountOut = normalizePositiveUint64(value.minimumAmountOut, code);
6934
+ const minimumReceived = normalizePositiveUint64(value.minimumReceived, code);
6935
+ if (minimumAmountOut.value > expectedAmountOut.value || minimumReceived.value > minimumAmountOut.value) fail(code);
6936
+ const deadline = normalizePositiveUint64(value.deadline, code);
6937
+ const slippageBps = normalizeSlippage(value.slippageBps, code);
6938
+ if (value.quoteVerification !== "provider-signed-not-locally-verified") fail(code);
6939
+ const quoteId = requireString(value.quoteId, code);
6940
+ if (!/^0x[0-9a-fA-F]{32}$/u.test(quoteId)) fail(code);
6941
+ const signature = requireString(value.providerSignature, code);
6942
+ if (!EVM_SIGNATURE.test(signature)) fail(code);
6943
+ const sourceSwap = requireRecord(value.sourceSwap, code);
6944
+ exactObjectKeys(sourceSwap, SOURCE_SWAP_KEYS, code);
6945
+ if (sourceSwap.required !== true) fail(code);
6946
+ if (sourceSwap.inputTokenDeploymentId !== facts.sourceTokenDeploymentId || sourceSwap.intermediateTokenDeploymentId !== facts.sourceUsdcDeploymentId) fail(code);
6947
+ if (sourceSwap.intermediateTokenAddress !== facts.sourceUsdcAddress) fail(code);
6948
+ const providerStandard = quoteProviderStandard(facts);
6949
+ if (sourceSwap.intermediateTokenStandard !== providerStandard || sourceSwap.intermediateTokenDecimals !== 6) fail(code);
6950
+ const providerMinimumAmount = sourceSwap.providerMinimumAmount;
6951
+ if (typeof providerMinimumAmount !== "string" || providerMinimumAmount.length === 0) fail(code);
6952
+ let normalizedRouterAddress;
6953
+ let normalizedRouterKind;
6954
+ if (facts.sourceChainId === ETHEREUM_CHAIN_ID) {
6955
+ const routerAddress = sourceSwap.routerAddress;
6956
+ if (sourceSwap.routerKind !== "provider-selected-evm" || typeof routerAddress !== "string" || !EVM_ADDRESS2.test(routerAddress) || /^0x0{40}$/iu.test(routerAddress)) return fail(code);
6957
+ normalizedRouterAddress = routerAddress.toLowerCase();
6958
+ normalizedRouterKind = "provider-selected-evm";
6959
+ } else if (sourceSwap.routerKind !== "jupiter-v6" || sourceSwap.routerAddress !== SOLANA_JUPITER_V6) {
6960
+ return fail(code);
6961
+ } else {
6962
+ normalizedRouterAddress = SOLANA_JUPITER_V6;
6963
+ normalizedRouterKind = "jupiter-v6";
6964
+ }
6965
+ if (!Array.isArray(value.dependencies)) fail(code);
6966
+ const wantedDependencies = facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
6967
+ if (stableJson(value.dependencies) !== stableJson(wantedDependencies)) fail(code);
6968
+ const rawSignedQuoteJson = requireString(value.rawSignedQuoteJson, code);
6969
+ if (byteLength(rawSignedQuoteJson) > MAX_RAW_QUOTE_BYTES) fail(code);
6970
+ return {
6971
+ quoteKind: "mayan-swift-v2",
6972
+ providerId: "mayan-swift-v2",
6973
+ sourceChainId,
6974
+ destinationChainId,
6975
+ sourceTokenDeploymentId: facts.sourceTokenDeploymentId,
6976
+ destinationTokenDeploymentId: facts.destinationTokenDeploymentId,
6977
+ amountIn: amountIn.source,
6978
+ expectedAmountOut: expectedAmountOut.source,
6979
+ minimumAmountOut: minimumAmountOut.source,
6980
+ minimumReceived: minimumReceived.source,
6981
+ deadline: deadline.source,
6982
+ slippageBps,
6983
+ quoteId: quoteId.toLowerCase(),
6984
+ providerSignature: signature.toLowerCase(),
6985
+ sourceSwap: {
6986
+ required: true,
6987
+ inputTokenDeploymentId: facts.sourceTokenDeploymentId,
6988
+ intermediateTokenDeploymentId: facts.sourceUsdcDeploymentId,
6989
+ intermediateTokenAddress: facts.sourceUsdcAddress,
6990
+ intermediateTokenStandard: providerStandard,
6991
+ intermediateTokenDecimals: 6,
6992
+ providerMinimumAmount,
6993
+ routerKind: normalizedRouterKind,
6994
+ routerAddress: normalizedRouterAddress
6995
+ },
6996
+ dependencies: wantedDependencies,
6997
+ quoteVerification: "provider-signed-not-locally-verified",
6998
+ rawSignedQuoteJson
6999
+ };
7000
+ };
7001
+ var quoteRequestBody = (route) => JSON.stringify({
7002
+ fromToken: route.facts.sourceTokenAddress,
7003
+ fromChain: route.facts.sourceName,
7004
+ toToken: route.facts.destinationTokenAddress,
7005
+ toChain: route.facts.destinationName,
7006
+ amountIn64: route.request.amountIn,
7007
+ slippageBps: route.request.slippageBps,
7008
+ swift: true,
7009
+ mctp: false,
7010
+ fastMctp: false,
7011
+ wormhole: false,
7012
+ monoChain: false,
7013
+ gasless: false,
7014
+ fullList: true,
7015
+ guaranteedOutput: true,
7016
+ gasDrop: 0
7017
+ });
7018
+ var quoteFromResponse = (response, request, facts, config) => {
7019
+ if (!isRecord4(response.root.value) || response.root.objectEntries === void 0) {
7020
+ providerInvalid();
7021
+ }
7022
+ if (objectValue5(response.root, "success") !== true) providerInvalid();
7023
+ const quotesNode = requiredNode(response.root, "quotes");
7024
+ const quoteNodes = quotesNode.arrayItems;
7025
+ if (!quoteNodes || quoteNodes.length > MAX_QUOTES) return providerInvalid();
7026
+ const selected = [];
7027
+ for (const quoteNode of quoteNodes) {
7028
+ if (!isRecord4(quoteNode.value)) continue;
7029
+ if (quoteNode.value.type !== "SWIFT" || quoteNode.value.swiftVersion !== "V2" || quoteNode.value.gasless !== false) continue;
7030
+ const validated = validateProviderQuote(
7031
+ quoteNode,
7032
+ response.text,
7033
+ request,
7034
+ facts,
7035
+ config
7036
+ );
7037
+ selected.push(validated.quote);
7038
+ }
7039
+ if (selected.length === 0) fail("BRIDGE_QUOTE_UNAVAILABLE");
7040
+ for (const quote of selected) {
7041
+ ensureQuoteDeadline(
7042
+ normalizePositiveUint64(quote.deadline, "BRIDGE_PROVIDER_INVALID_RESPONSE").value,
7043
+ config.minimumQuoteValiditySeconds
7044
+ );
7045
+ }
7046
+ return deepFreeze6(selected);
7047
+ };
7048
+ var buildRequestSnapshot = (value) => {
7049
+ const request = requireRecord(value, "BRIDGE_INVALID_ARGUMENT");
7050
+ const allowed = /* @__PURE__ */ new Set(["quote", "swapperAddress", "destinationAddress", "refundAddress"]);
7051
+ if (Object.keys(request).some((key) => !allowed.has(key))) fail("BRIDGE_INVALID_ARGUMENT");
7052
+ if (!Object.hasOwn(request, "quote") || !Object.hasOwn(request, "swapperAddress") || !Object.hasOwn(request, "destinationAddress")) {
7053
+ fail("BRIDGE_INVALID_ARGUMENT");
7054
+ }
7055
+ const rawQuote = request.quote;
7056
+ if (!isRecord4(rawQuote)) fail("BRIDGE_INVALID_ARGUMENT");
7057
+ let quote;
7058
+ try {
7059
+ quote = cloneQuote(rawQuote);
7060
+ } catch {
7061
+ return fail("BRIDGE_INVALID_ARGUMENT");
7062
+ }
7063
+ return {
7064
+ quote,
7065
+ swapperAddress: request.swapperAddress,
7066
+ destinationAddress: request.destinationAddress,
7067
+ refundAddress: request.refundAddress
7068
+ };
7069
+ };
7070
+ var normalizeChainAddress = (value, chainId, code) => {
7071
+ if (chainId === ETHEREUM_CHAIN_ID) return normalizeEvmAddress3(value, code);
7072
+ const address = requireString(value, code);
7073
+ decodeBase58(address, 32, code);
7074
+ return address;
7075
+ };
7076
+ var isCanonicalSolanaAddress = (value) => {
7077
+ if (typeof value !== "string") return false;
7078
+ try {
7079
+ decodeBase58(value, 32, "BRIDGE_INVALID_ARGUMENT");
7080
+ return true;
7081
+ } catch {
7082
+ return false;
7083
+ }
7084
+ };
7085
+ var rejectAddressFromOtherChain = (value, expectedChainId) => {
7086
+ const isEvm = typeof value === "string" && EVM_ADDRESS2.test(value) && !/^0x0{40}$/iu.test(value);
7087
+ const isSolana = isCanonicalSolanaAddress(value);
7088
+ if (expectedChainId === ETHEREUM_CHAIN_ID && isSolana || expectedChainId === SOLANA_CHAIN_ID && isEvm) {
7089
+ fail("BRIDGE_QUOTE_MISMATCH");
7090
+ }
7091
+ };
7092
+ var normalizeDestinationAddress = (value, destinationChainId) => {
7093
+ return normalizeChainAddress(value, destinationChainId, "BRIDGE_INVALID_ARGUMENT");
7094
+ };
7095
+ var buildRouteFromQuote = (quote) => {
7096
+ let normalizedQuote;
7097
+ try {
7098
+ normalizedQuote = validateNormalizedQuoteShape(quote, "BRIDGE_QUOTE_MISMATCH");
7099
+ } catch (error) {
7100
+ if (error instanceof BridgeError) throw error;
7101
+ return fail("BRIDGE_QUOTE_MISMATCH");
7102
+ }
7103
+ if (stableJson(quote) !== stableJson(normalizedQuote)) fail("BRIDGE_QUOTE_MISMATCH");
7104
+ const route = validateBridgeRoute({
7105
+ sourceChainId: normalizedQuote.sourceChainId,
7106
+ destinationChainId: normalizedQuote.destinationChainId,
7107
+ sourceTokenDeploymentId: normalizedQuote.sourceTokenDeploymentId,
7108
+ destinationTokenDeploymentId: normalizedQuote.destinationTokenDeploymentId,
7109
+ amountIn: normalizedQuote.amountIn,
7110
+ slippageBps: normalizedQuote.slippageBps
7111
+ });
7112
+ return { route, normalizedQuote };
7113
+ };
7114
+ var validateRawQuoteForBuild = (quote, route, config) => {
7115
+ let response;
7116
+ try {
7117
+ response = parseProviderResponse(quote.rawSignedQuoteJson);
7118
+ } catch (error) {
7119
+ if (error instanceof BridgeError && error.code === "BRIDGE_QUOTE_EXPIRED") throw error;
7120
+ return fail("BRIDGE_QUOTE_MISMATCH");
7121
+ }
7122
+ if (!isRecord4(response.root.value) || response.root.start !== 0 || response.root.end !== response.text.length) {
7123
+ fail("BRIDGE_QUOTE_MISMATCH");
7124
+ }
7125
+ let rebuilt;
7126
+ try {
7127
+ rebuilt = validateProviderQuote(
7128
+ response.root,
7129
+ response.text,
7130
+ route.request,
7131
+ route.facts,
7132
+ config
7133
+ );
7134
+ } catch (error) {
7135
+ if (error instanceof BridgeError && error.code === "BRIDGE_QUOTE_EXPIRED") throw error;
7136
+ return fail("BRIDGE_QUOTE_MISMATCH");
7137
+ }
7138
+ if (stableJson(rebuilt.quote) !== stableJson(quote)) fail("BRIDGE_QUOTE_MISMATCH");
7139
+ return deepFreeze6(quote);
7140
+ };
7141
+ var numericZero = (value) => {
7142
+ if (typeof value === "number") return Number.isFinite(value) && value === 0;
7143
+ if (typeof value !== "string") return false;
7144
+ if (value === "0") return true;
7145
+ return /^0x0+$/iu.test(value);
7146
+ };
7147
+ var validateEvmBuildResult = (wrapper, swapperAddress) => {
7148
+ if (providerString(wrapper, "chainCategory") !== "evm") providerInvalid();
7149
+ if (providerString(wrapper, "quoteType") !== "SWIFT") providerInvalid();
7150
+ if (providerBoolean(wrapper, "gasless")) providerInvalid();
7151
+ const transaction = requiredNode(wrapper, "transaction");
7152
+ if (!isRecord4(transaction.value)) providerInvalid();
7153
+ const to = providerString(transaction, "to");
7154
+ if (!providerAddressEquals(to, ETHEREUM_FORWARDER)) providerInvalid();
7155
+ const chainId = providerInteger(transaction, "chainId");
7156
+ if (chainId !== ETHEREUM_PROVIDER_CHAIN_ID) providerInvalid();
7157
+ if (!numericZero(objectValue5(transaction, "value"))) providerInvalid();
7158
+ const data = providerString(transaction, "data").toLowerCase();
7159
+ if (!HEX_BYTES2.test(data) || data.length % 2 !== 0 || !data.startsWith(ETHEREUM_FORWARDER_SELECTOR) || data.length < 2 + 8 + 13 * 64) {
7160
+ providerInvalid();
7161
+ }
7162
+ return {
7163
+ kind: "evm-unsigned-transaction",
7164
+ chainId: "eip155:1",
7165
+ from: swapperAddress,
7166
+ to: ETHEREUM_FORWARDER,
7167
+ data,
7168
+ value: "0"
7169
+ };
7170
+ };
7171
+ var validateSolanaBuildResult = (wrapper, swapperAddress) => {
7172
+ if (providerString(wrapper, "chainCategory") !== "svm") providerInvalid();
7173
+ if (providerString(wrapper, "quoteType") !== "SWIFT") providerInvalid();
7174
+ const gaslessNode = objectEntry(wrapper, "gasless");
7175
+ if (gaslessNode !== void 0 && gaslessNode.value !== false) providerInvalid();
7176
+ const transaction = requiredNode(wrapper, "transaction");
7177
+ const encoded = validateSolanaTransaction(transaction.value, swapperAddress);
7178
+ return {
7179
+ kind: "solana-v0-unsigned-transaction",
7180
+ chainId: SOLANA_CHAIN_ID,
7181
+ feePayer: swapperAddress,
7182
+ transactionBase64: encoded
7183
+ };
7184
+ };
7185
+ var validateBuildResponse = (response, quote, facts, swapperAddress) => {
7186
+ if (!isRecord4(response.root.value) || objectValue5(response.root, "success") !== true) {
7187
+ fail("BRIDGE_BUILD_INVALID");
7188
+ }
7189
+ const wrapper = requiredNode(response.root, "transaction");
7190
+ if (!isRecord4(wrapper.value)) fail("BRIDGE_BUILD_INVALID");
7191
+ const signers = objectValue5(wrapper, "signers");
7192
+ if (signers !== void 0 && signers !== null && (!Array.isArray(signers) || signers.length !== 0)) {
7193
+ fail("BRIDGE_BUILD_INVALID");
7194
+ }
7195
+ const swapMessageV0Params = objectValue5(wrapper, "swapMessageV0Params");
7196
+ if (swapMessageV0Params !== void 0 && swapMessageV0Params !== null) {
7197
+ fail("BRIDGE_BUILD_INVALID");
7198
+ }
7199
+ let transaction;
7200
+ try {
7201
+ transaction = facts.sourceChainId === ETHEREUM_CHAIN_ID ? validateEvmBuildResult(wrapper, swapperAddress) : validateSolanaBuildResult(wrapper, swapperAddress);
7202
+ } catch (error) {
7203
+ if (error instanceof BridgeError) {
7204
+ if (error.code === "BRIDGE_BUILD_INVALID") throw error;
7205
+ return fail("BRIDGE_BUILD_INVALID");
7206
+ }
7207
+ return fail("BRIDGE_BUILD_INVALID");
7208
+ }
7209
+ return deepFreeze6({
7210
+ buildKind: "mayan-swift-v2-unsigned",
7211
+ providerId: "mayan-swift-v2",
7212
+ quote,
7213
+ sourceChainId: quote.sourceChainId,
7214
+ destinationChainId: quote.destinationChainId,
7215
+ transaction,
7216
+ allowance: facts.sourceChainId === ETHEREUM_CHAIN_ID ? {
7217
+ tokenDeploymentId: "deployment-0011",
7218
+ tokenAddress: ETHEREUM_EURC_ADDRESS,
7219
+ owner: swapperAddress,
7220
+ spender: ETHEREUM_FORWARDER,
7221
+ requiredAmount: quote.amountIn
7222
+ } : null,
7223
+ validation: {
7224
+ level: "structural",
7225
+ quoteSignatureLocallyVerified: false,
7226
+ transactionSemanticsLocallyVerified: false,
7227
+ settlementLocallyVerified: false
7228
+ },
7229
+ rawProviderBuildJson: response.text
7230
+ });
7231
+ };
7232
+ var boundedProviderString = (value, code, maximum = 1024) => {
7233
+ if (typeof value !== "string" || value.length === 0 || value.length > maximum) fail(code);
7234
+ return value;
7235
+ };
7236
+ var statusRequestSnapshot = (value) => {
7237
+ const request = requireRecord(value, "BRIDGE_INVALID_ARGUMENT");
7238
+ exactObjectKeys(request, ["sourceChainId", "sourceTransactionHash"], "BRIDGE_INVALID_ARGUMENT");
7239
+ return {
7240
+ sourceChainId: requireString(request.sourceChainId, "BRIDGE_INVALID_ARGUMENT"),
7241
+ sourceTransactionHash: requireString(request.sourceTransactionHash, "BRIDGE_INVALID_ARGUMENT")
7242
+ };
7243
+ };
7244
+ var normalizeStatusRequest = (value) => {
7245
+ const request = statusRequestSnapshot(value);
7246
+ if (request.sourceChainId === ETHEREUM_CHAIN_ID) {
7247
+ if (!EVM_HASH.test(request.sourceTransactionHash)) fail("BRIDGE_INVALID_ARGUMENT");
7248
+ return {
7249
+ sourceChainId: request.sourceChainId,
7250
+ sourceTransactionHash: request.sourceTransactionHash.toLowerCase()
7251
+ };
7252
+ }
7253
+ if (request.sourceChainId === SOLANA_CHAIN_ID) {
7254
+ decodeBase58(request.sourceTransactionHash, 64, "BRIDGE_INVALID_ARGUMENT");
7255
+ return request;
7256
+ }
7257
+ return fail("BRIDGE_UNSUPPORTED_ROUTE");
7258
+ };
7259
+ var statusFromResponse = (response, request) => {
7260
+ if (!isRecord4(response.root.value)) fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
7261
+ const providerClientStatus = boundedProviderString(
7262
+ objectValue5(response.root, "clientStatus"),
7263
+ "BRIDGE_PROVIDER_INVALID_RESPONSE",
7264
+ 128
7265
+ );
7266
+ const providerStatusValue = objectValue5(response.root, "status");
7267
+ if (providerStatusValue !== null && providerStatusValue !== void 0 && (typeof providerStatusValue !== "string" || providerStatusValue.length > 1024)) {
7268
+ fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
7269
+ }
7270
+ const providerStatus = providerStatusValue === void 0 ? null : providerStatusValue;
7271
+ const state = providerClientStatus === "INPROGRESS" ? "in-progress" : providerClientStatus === "COMPLETED" ? "completed" : providerClientStatus === "REFUNDED" ? "refunded" : "unknown";
7272
+ return deepFreeze6({
7273
+ statusKind: "mayan-explorer-index",
7274
+ providerId: "mayan-swift-v2",
7275
+ sourceChainId: request.sourceChainId,
7276
+ sourceTransactionHash: request.sourceTransactionHash,
7277
+ state,
7278
+ providerClientStatus,
7279
+ providerStatus,
7280
+ statusVerification: "provider-indexed-not-locally-verified",
7281
+ rawProviderStatusJson: response.text
7282
+ });
7283
+ };
7284
+ var buildBody = (quote, sourceChainId, swapperAddress, destinationAddress, refundAddress) => {
7285
+ const params = {
7286
+ swapperAddress,
7287
+ destinationAddress
7288
+ };
7289
+ if (sourceChainId === ETHEREUM_CHAIN_ID) params.signerChainId = 1;
7290
+ if (refundAddress !== void 0) params.swiftRefundAddress = refundAddress;
7291
+ return `{"quote":${quote.rawSignedQuoteJson},"params":${JSON.stringify(params)}}`;
7292
+ };
7293
+ var quoteRequestBodyForRoute = (route) => quoteRequestBody(route);
7294
+ var MayanSwiftV2BridgeClient = class {
7295
+ #config;
7296
+ constructor(config) {
7297
+ this.#config = normalizeBridgeConfig(config);
7298
+ }
7299
+ async quoteExactInput(request, options) {
7300
+ const route = validateBridgeRoute(request);
7301
+ const response = await providerRequest(
7302
+ this.#config,
7303
+ endpointWithPath2(this.#config.builderEndpoint, "/quote"),
7304
+ "POST",
7305
+ quoteRequestBodyForRoute(route),
7306
+ false,
7307
+ options
7308
+ );
7309
+ const parsed = await providerJson(response, "quote");
7310
+ const quotes = quoteFromResponse(parsed, route.request, route.facts, this.#config);
7311
+ return deepFreeze6([...quotes]);
7312
+ }
7313
+ async buildUnsigned(request, options) {
7314
+ const snapshot = buildRequestSnapshot(request);
7315
+ const { route, normalizedQuote } = buildRouteFromQuote(snapshot.quote);
7316
+ rejectAddressFromOtherChain(snapshot.swapperAddress, route.facts.sourceChainId);
7317
+ const sourceAddress = normalizeChainAddress(
7318
+ snapshot.swapperAddress,
7319
+ route.facts.sourceChainId,
7320
+ "BRIDGE_INVALID_ARGUMENT"
7321
+ );
7322
+ const destinationAddress = normalizeDestinationAddress(
7323
+ snapshot.destinationAddress,
7324
+ route.facts.destinationChainId
7325
+ );
7326
+ let refundAddress;
7327
+ if (snapshot.refundAddress !== void 0) {
7328
+ refundAddress = normalizeChainAddress(
7329
+ snapshot.refundAddress,
7330
+ route.facts.sourceChainId,
7331
+ "BRIDGE_INVALID_ARGUMENT"
7332
+ );
7333
+ }
7334
+ if (this.#config.builderApiKey === void 0 && !this.#config.allowUnauthenticatedBuild) {
7335
+ fail("BRIDGE_PROVIDER_AUTH_REQUIRED");
7336
+ }
7337
+ const quote = validateRawQuoteForBuild(normalizedQuote, route, this.#config);
7338
+ const response = await providerRequest(
7339
+ this.#config,
7340
+ endpointWithPath2(this.#config.builderEndpoint, "/build"),
7341
+ "POST",
7342
+ buildBody(quote, route.facts.sourceChainId, sourceAddress, destinationAddress, refundAddress),
7343
+ true,
7344
+ options
7345
+ );
7346
+ const parsed = await providerJson(response, "build");
7347
+ ensureQuoteDeadline(
7348
+ normalizePositiveUint64(quote.deadline, "BRIDGE_QUOTE_EXPIRED").value,
7349
+ this.#config.minimumQuoteValiditySeconds
7350
+ );
7351
+ return validateBuildResponse(parsed, quote, route.facts, sourceAddress);
7352
+ }
7353
+ async getStatus(request, options) {
7354
+ const normalized = normalizeStatusRequest(request);
7355
+ const response = await providerRequest(
7356
+ this.#config,
7357
+ endpointWithPath2(
7358
+ this.#config.explorerEndpoint,
7359
+ `/swap/trx/${encodeURIComponent(normalized.sourceTransactionHash)}`
7360
+ ),
7361
+ "GET",
7362
+ void 0,
7363
+ false,
7364
+ options
7365
+ );
7366
+ const parsed = await providerJson(response, "status");
7367
+ return statusFromResponse(parsed, normalized);
7368
+ }
7369
+ close() {
7370
+ }
7371
+ };
7372
+ var createMayanSwiftV2BridgeClient = (config) => new MayanSwiftV2BridgeClient(config);
7373
+
5003
7374
  exports.AVALANCHE_AVAX_METHODS = AVALANCHE_AVAX_METHODS;
5004
7375
  exports.AVALANCHE_INDEX_METHODS = AVALANCHE_INDEX_METHODS;
5005
7376
  exports.AVALANCHE_INFO_METHODS = AVALANCHE_INFO_METHODS;
@@ -5007,6 +7378,11 @@ exports.AVALANCHE_PROPOSER_VM_METHODS = AVALANCHE_PROPOSER_VM_METHODS;
5007
7378
  exports.AVALANCHE_P_CHAIN_METHODS = AVALANCHE_P_CHAIN_METHODS;
5008
7379
  exports.AVALANCHE_X_CHAIN_METHODS = AVALANCHE_X_CHAIN_METHODS;
5009
7380
  exports.AccountClient = AccountClient;
7381
+ exports.BRIDGE_CAPABILITIES_AS_OF_DATE = BRIDGE_CAPABILITIES_AS_OF_DATE;
7382
+ exports.BRIDGE_CAPABILITIES_CONTENT_DIGEST = BRIDGE_CAPABILITIES_CONTENT_DIGEST;
7383
+ exports.BRIDGE_CAPABILITIES_JSON = BRIDGE_CAPABILITIES_JSON;
7384
+ exports.BRIDGE_ERROR_MESSAGES = BRIDGE_ERROR_MESSAGES;
7385
+ exports.BridgeError = BridgeError;
5010
7386
  exports.CloudCatalogClient = CloudCatalogClient;
5011
7387
  exports.CloudCreditClient = CloudCreditClient;
5012
7388
  exports.CloudResourcesClient = CloudResourcesClient;
@@ -5030,9 +7406,11 @@ exports.ErpcError = ErpcError;
5030
7406
  exports.ErpcHttpError = ErpcHttpError;
5031
7407
  exports.ErpcInvalidResponseError = ErpcInvalidResponseError;
5032
7408
  exports.ErpcJsonRpcError = ErpcJsonRpcError;
7409
+ exports.ErpcNotConfiguredError = ErpcNotConfiguredError;
5033
7410
  exports.ErpcTimeoutError = ErpcTimeoutError;
5034
7411
  exports.ErpcTransportError = ErpcTransportError;
5035
7412
  exports.EthereumSubscriptions = EthereumSubscriptions;
7413
+ exports.MayanSwiftV2BridgeClient = MayanSwiftV2BridgeClient;
5036
7414
  exports.NATIVE_WRAP_DEFINITIONS = NATIVE_WRAP_DEFINITIONS;
5037
7415
  exports.POOL_DEFINITIONS = POOL_DEFINITIONS;
5038
7416
  exports.PendingRpcBatchRequest = PendingRpcBatchRequest;
@@ -5045,8 +7423,15 @@ exports.SOLANA_ENHANCED_SUBSCRIPTION_METHODS = SOLANA_ENHANCED_SUBSCRIPTION_METH
5045
7423
  exports.SOLANA_HISTORY_METHODS = SOLANA_HISTORY_METHODS;
5046
7424
  exports.SOLANA_LEADER_METHODS = SOLANA_LEADER_METHODS;
5047
7425
  exports.SOLANA_RPC_METHODS = SOLANA_RPC_METHODS;
7426
+ exports.SWAP_EXECUTION_CAPABILITIES_AS_OF_DATE = SWAP_EXECUTION_CAPABILITIES_AS_OF_DATE;
7427
+ exports.SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST = SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST;
7428
+ exports.SWAP_EXECUTION_CAPABILITIES_JSON = SWAP_EXECUTION_CAPABILITIES_JSON;
7429
+ exports.SWAP_EXECUTION_ERROR_MESSAGES = SWAP_EXECUTION_ERROR_MESSAGES;
7430
+ exports.SWAP_EXECUTION_FUNCTION_SELECTOR = SWAP_EXECUTION_FUNCTION_SELECTOR;
7431
+ exports.SWAP_EXECUTION_FUNCTION_SIGNATURE = SWAP_EXECUTION_FUNCTION_SIGNATURE;
5048
7432
  exports.SWAP_QUOTE_ERROR_MESSAGES = SWAP_QUOTE_ERROR_MESSAGES;
5049
7433
  exports.SolanaSubscriptions = SolanaSubscriptions;
7434
+ exports.SwapExecutionError = SwapExecutionError;
5050
7435
  exports.SwapQuoteError = SwapQuoteError;
5051
7436
  exports.TOKEN_ALIASES = TOKEN_ALIASES;
5052
7437
  exports.TOKEN_ASSETS = TOKEN_ASSETS;
@@ -5062,6 +7447,7 @@ exports.TOKEN_RANKINGS_METADATA = TOKEN_RANKINGS_METADATA;
5062
7447
  exports.UsageClient = UsageClient;
5063
7448
  exports.createErpcClient = createErpcClient;
5064
7449
  exports.createErpcCloudClient = createErpcCloudClient;
7450
+ exports.createMayanSwiftV2BridgeClient = createMayanSwiftV2BridgeClient;
5065
7451
  exports.dexes = dexes;
5066
7452
  exports.findPoolDefinitionByAddress = findPoolDefinitionByAddress;
5067
7453
  exports.findPoolDefinitionsByPair = findPoolDefinitionsByPair;