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