@elsoul/erpc-sdk 0.8.0 → 0.9.0

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
@@ -1,3 +1,7 @@
1
+ import { ed25519 } from '@noble/curves/ed25519.js';
2
+ import { sha256 } from '@noble/hashes/sha2.js';
3
+ import { keccak_256 } from '@noble/hashes/sha3.js';
4
+
1
5
  // src/errors.ts
2
6
  var REDACTED = "[REDACTED]";
3
7
  var credentialVariants = (credential) => {
@@ -20,6 +24,16 @@ var directEndpointVariants = (endpoint) => {
20
24
  const add = (value) => {
21
25
  if (value) values.push(value);
22
26
  };
27
+ const addPathValue = (value) => {
28
+ add(value);
29
+ try {
30
+ add(decodeURIComponent(value));
31
+ } catch {
32
+ }
33
+ };
34
+ for (const component of endpoint.pathname.split("/")) {
35
+ if (component) addPathValue(component);
36
+ }
23
37
  for (const value of endpoint.searchParams.values()) add(value);
24
38
  const rawQuery = endpoint.search.startsWith("?") ? endpoint.search.slice(1) : endpoint.search;
25
39
  for (const part of rawQuery.split("&")) {
@@ -347,13 +361,14 @@ var deepFreeze = (value) => {
347
361
  }
348
362
  return value;
349
363
  };
350
- var TOKEN_CATALOG_VERSION = "1.0.0";
351
- var TOKEN_CATALOG_AS_OF_DATE = "2026-09-15";
352
- var TOKEN_CATALOG_CONTENT_DIGEST = "28318f4f6a6bc2cdeef51368eeb17c86685c6f12d1723b0b4dd27f7e54d7235d";
364
+ var TOKEN_CATALOG_VERSION = "1.1.0";
365
+ var TOKEN_CATALOG_AS_OF_DATE = "2026-09-26";
366
+ var TOKEN_CATALOG_CONTENT_DIGEST = "cca180df1846def0ec98f4e55b84cc46614c60d7a8c4a91c66dc9715c710ba73";
353
367
  var TOKEN_CHAIN_IDS = deepFreeze({
354
368
  "ethereumMainnet": "eip155:1",
355
369
  "solanaMainnet": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
356
- "avalancheCMainnet": "eip155:43114"
370
+ "avalancheCMainnet": "eip155:43114",
371
+ "baseMainnet": "eip155:8453"
357
372
  });
358
373
  var tokens = deepFreeze({
359
374
  "avalancheC": {
@@ -375,6 +390,11 @@ var tokens = deepFreeze({
375
390
  "USDT": "deployment-0015",
376
391
  "WAVAX": "deployment-0004"
377
392
  },
393
+ "base": {
394
+ "ETH": "deployment-0061",
395
+ "EURC": "deployment-0063",
396
+ "USDC": "deployment-0062"
397
+ },
378
398
  "ethereum": {
379
399
  "AAVE": "deployment-0056",
380
400
  "AUSD": "deployment-0034",
@@ -1788,6 +1808,54 @@ var TOKEN_DEPLOYMENTS = deepFreeze([
1788
1808
  "status": "active",
1789
1809
  "replacedByDeploymentId": null
1790
1810
  },
1811
+ {
1812
+ "deploymentId": "deployment-0061",
1813
+ "assetId": "asset-0001",
1814
+ "name": "Ether",
1815
+ "representationKind": "native",
1816
+ "stableCurrency": null,
1817
+ "underlyingAssetId": null,
1818
+ "economicReferenceAssetId": null,
1819
+ "chainId": "eip155:8453",
1820
+ "symbol": "ETH",
1821
+ "decimals": 18,
1822
+ "standard": "native",
1823
+ "address": null,
1824
+ "status": "active",
1825
+ "replacedByDeploymentId": null
1826
+ },
1827
+ {
1828
+ "deploymentId": "deployment-0062",
1829
+ "assetId": "asset-0007",
1830
+ "name": "USD Coin",
1831
+ "representationKind": "issued",
1832
+ "stableCurrency": "USD",
1833
+ "underlyingAssetId": null,
1834
+ "economicReferenceAssetId": null,
1835
+ "chainId": "eip155:8453",
1836
+ "symbol": "USDC",
1837
+ "decimals": 6,
1838
+ "standard": "erc20",
1839
+ "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
1840
+ "status": "active",
1841
+ "replacedByDeploymentId": null
1842
+ },
1843
+ {
1844
+ "deploymentId": "deployment-0063",
1845
+ "assetId": "asset-0008",
1846
+ "name": "Euro Coin",
1847
+ "representationKind": "issued",
1848
+ "stableCurrency": "EUR",
1849
+ "underlyingAssetId": null,
1850
+ "economicReferenceAssetId": null,
1851
+ "chainId": "eip155:8453",
1852
+ "symbol": "EURC",
1853
+ "decimals": 6,
1854
+ "standard": "erc20",
1855
+ "address": "0x60a3e35cc302bfa44cb288bc5a4f316fdb1adb42",
1856
+ "status": "active",
1857
+ "replacedByDeploymentId": null
1858
+ },
1791
1859
  {
1792
1860
  "deploymentId": "discovered-token-054d80a64e1f36a756129763ca2f1e7a140b50b04c83876ff01dd5fd497a74c5",
1793
1861
  "assetId": "discovered-token-054d80a64e1f36a756129763ca2f1e7a140b50b04c83876ff01dd5fd497a74c5",
@@ -1967,6 +2035,9 @@ var TOKEN_ALIASES = deepFreeze([
1967
2035
  { namespace: "avalancheC", name: "USDC_E", deploymentId: tokens.avalancheC.USDC_E },
1968
2036
  { namespace: "avalancheC", name: "USDT", deploymentId: tokens.avalancheC.USDT },
1969
2037
  { namespace: "avalancheC", name: "WAVAX", deploymentId: tokens.avalancheC.WAVAX },
2038
+ { namespace: "base", name: "ETH", deploymentId: tokens.base.ETH },
2039
+ { namespace: "base", name: "EURC", deploymentId: tokens.base.EURC },
2040
+ { namespace: "base", name: "USDC", deploymentId: tokens.base.USDC },
1970
2041
  { namespace: "ethereum", name: "AAVE", deploymentId: tokens.ethereum.AAVE },
1971
2042
  { namespace: "ethereum", name: "AUSD", deploymentId: tokens.ethereum.AUSD },
1972
2043
  { namespace: "ethereum", name: "DAI", deploymentId: tokens.ethereum.DAI },
@@ -2111,13 +2182,13 @@ function isRecord(value) {
2111
2182
  return typeof value === "object" && value !== null && !Array.isArray(value);
2112
2183
  }
2113
2184
  function isKnownChainId(value) {
2114
- return value === TOKEN_CHAIN_IDS.ethereumMainnet || value === TOKEN_CHAIN_IDS.solanaMainnet || value === TOKEN_CHAIN_IDS.avalancheCMainnet;
2185
+ return value === TOKEN_CHAIN_IDS.ethereumMainnet || value === TOKEN_CHAIN_IDS.solanaMainnet || value === TOKEN_CHAIN_IDS.avalancheCMainnet || value === TOKEN_CHAIN_IDS.baseMainnet;
2115
2186
  }
2116
2187
  function isStableCurrency(value) {
2117
2188
  return value === "USD" || value === "EUR" || value === "JPY";
2118
2189
  }
2119
2190
  function isEvmChain(chainId) {
2120
- return chainId === TOKEN_CHAIN_IDS.ethereumMainnet || chainId === TOKEN_CHAIN_IDS.avalancheCMainnet;
2191
+ return chainId === TOKEN_CHAIN_IDS.ethereumMainnet || chainId === TOKEN_CHAIN_IDS.avalancheCMainnet || chainId === TOKEN_CHAIN_IDS.baseMainnet;
2121
2192
  }
2122
2193
  function normalizeEvmAddress(address) {
2123
2194
  if (!/^0x[0-9a-fA-F]{40}$/.test(address)) return void 0;
@@ -2477,8 +2548,8 @@ var parseOffering = (value) => {
2477
2548
  const offering = objectValue(value);
2478
2549
  if (offering === null || typeof offering.id !== "string" || typeof offering.kind !== "string" || !resourceKinds.includes(offering.kind) || typeof offering.name !== "string" || typeof offering.description !== "string" || offering.mode !== void 0 && (typeof offering.mode !== "string" || !resourceModes.includes(offering.mode))) return null;
2479
2550
  const regions = stringArray(offering.regions);
2480
- const capabilities = stringArray(offering.capabilities);
2481
- if (regions === null || capabilities === null) return null;
2551
+ const capabilities2 = stringArray(offering.capabilities);
2552
+ if (regions === null || capabilities2 === null) return null;
2482
2553
  const compute = offering.compute === void 0 ? void 0 : objectValue(offering.compute);
2483
2554
  if (compute !== void 0 && (compute === null || compute.tenancy !== "virtual-machine" && compute.tenancy !== "bare-metal")) return null;
2484
2555
  const solana = offering.solana === void 0 ? void 0 : objectValue(offering.solana);
@@ -2491,7 +2562,7 @@ var parseOffering = (value) => {
2491
2562
  name: offering.name,
2492
2563
  description: offering.description,
2493
2564
  regions,
2494
- capabilities,
2565
+ capabilities: capabilities2,
2495
2566
  ...typeof offering.mode === "string" ? { mode: offering.mode } : {},
2496
2567
  ...compute && (compute.tenancy === "virtual-machine" || compute.tenancy === "bare-metal") ? { compute: { tenancy: compute.tenancy } } : {},
2497
2568
  ...solana && (solana.transport === "grpc" || solana.transport === "shredstream") ? { solana: { transport: solana.transport } } : {},
@@ -2531,9 +2602,13 @@ var CloudCatalogClient = class {
2531
2602
  }
2532
2603
  };
2533
2604
 
2605
+ // src/transport/fetch.ts
2606
+ var wrapFetch = (implementation) => (input, init) => implementation(input, init);
2607
+
2534
2608
  // src/config.ts
2535
2609
  var DEFAULT_ENDPOINT = "https://edge.erpc.global";
2536
2610
  var DEFAULT_AVALANCHE_ENDPOINT = "https://ava-rpc.erpc.global";
2611
+ var DEFAULT_BASE_ENDPOINT = "https://base.erpc.global";
2537
2612
  var DEFAULT_ACCOUNT_ENDPOINT = "https://solana-rpc.erpc.global";
2538
2613
  var DEFAULT_USER_ENDPOINT = "https://user-api.erpc.global";
2539
2614
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -2544,7 +2619,7 @@ var requireFetch = (provided) => {
2544
2619
  "A Fetch API implementation is required in this runtime"
2545
2620
  );
2546
2621
  }
2547
- return implementation;
2622
+ return wrapFetch(implementation);
2548
2623
  };
2549
2624
  var normalizeLegacyEndpoint = (endpoint) => {
2550
2625
  endpoint.search = "";
@@ -2612,6 +2687,15 @@ var resolveRpcEndpoint = (value, namespace) => {
2612
2687
  ...webSocketUrl === void 0 ? {} : { webSocketUrl }
2613
2688
  };
2614
2689
  };
2690
+ var resolveBaseRpcEndpoint = (value) => {
2691
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2692
+ throw new ErpcConfigError("baseRpc must define an HTTP(S) URL");
2693
+ }
2694
+ const config = value;
2695
+ const httpUrl = parseDirectUrl(config.httpUrl, "baseRpc.httpUrl", "HTTP(S)");
2696
+ const headers = directHeaders(config.headers, "baseRpc");
2697
+ return { headers, httpUrl };
2698
+ };
2615
2699
  var resolveConfig = (config) => {
2616
2700
  const configuredApiKey = config.apiKey === void 0 ? void 0 : typeof config.apiKey === "string" ? config.apiKey.trim() : (() => {
2617
2701
  throw new ErpcConfigError("apiKey must be a string");
@@ -2619,13 +2703,15 @@ var resolveConfig = (config) => {
2619
2703
  const solanaRpc = config.solanaRpc === void 0 ? void 0 : resolveRpcEndpoint(config.solanaRpc, "solanaRpc");
2620
2704
  const ethereumRpc = config.ethereumRpc === void 0 ? void 0 : resolveRpcEndpoint(config.ethereumRpc, "ethereumRpc");
2621
2705
  const avalancheCRpc = config.avalancheCRpc === void 0 ? void 0 : resolveRpcEndpoint(config.avalancheCRpc, "avalancheCRpc");
2622
- const hasDirectRpc = solanaRpc !== void 0 || ethereumRpc !== void 0 || avalancheCRpc !== void 0;
2706
+ const baseRpc = config.baseRpc === void 0 ? void 0 : resolveBaseRpcEndpoint(config.baseRpc);
2707
+ const hasDirectRpc = solanaRpc !== void 0 || ethereumRpc !== void 0 || avalancheCRpc !== void 0 || baseRpc !== void 0;
2623
2708
  if (!configuredApiKey && !hasDirectRpc) {
2624
2709
  throw new ErpcConfigError("apiKey must not be empty");
2625
2710
  }
2626
2711
  const apiKey = configuredApiKey || void 0;
2627
2712
  let endpoint;
2628
2713
  let avalancheEndpoint;
2714
+ let baseEndpoint;
2629
2715
  let accountEndpoint;
2630
2716
  let userEndpoint;
2631
2717
  try {
@@ -2633,6 +2719,9 @@ var resolveConfig = (config) => {
2633
2719
  avalancheEndpoint = normalizeLegacyEndpoint(new URL(
2634
2720
  config.avalancheEndpoint ?? DEFAULT_AVALANCHE_ENDPOINT
2635
2721
  ));
2722
+ baseEndpoint = normalizeLegacyEndpoint(new URL(
2723
+ config.baseEndpoint ?? DEFAULT_BASE_ENDPOINT
2724
+ ));
2636
2725
  accountEndpoint = normalizeLegacyEndpoint(new URL(
2637
2726
  config.accountEndpoint ?? DEFAULT_ACCOUNT_ENDPOINT
2638
2727
  ));
@@ -2646,6 +2735,9 @@ var resolveConfig = (config) => {
2646
2735
  if (avalancheEndpoint.protocol !== "https:" && avalancheEndpoint.protocol !== "http:") {
2647
2736
  throw new ErpcConfigError("avalancheEndpoint must use HTTP or HTTPS");
2648
2737
  }
2738
+ if (baseEndpoint.protocol !== "https:" && baseEndpoint.protocol !== "http:") {
2739
+ throw new ErpcConfigError("baseEndpoint must use HTTP or HTTPS");
2740
+ }
2649
2741
  if (accountEndpoint.protocol !== "https:" && accountEndpoint.protocol !== "http:") {
2650
2742
  throw new ErpcConfigError("accountEndpoint must use HTTP or HTTPS");
2651
2743
  }
@@ -2659,6 +2751,7 @@ var resolveConfig = (config) => {
2659
2751
  return {
2660
2752
  accountEndpoint,
2661
2753
  avalancheEndpoint,
2754
+ baseEndpoint,
2662
2755
  endpoint,
2663
2756
  fetch: requireFetch(config.fetch),
2664
2757
  headers: config.headers ?? {},
@@ -2666,6 +2759,7 @@ var resolveConfig = (config) => {
2666
2759
  userEndpoint,
2667
2760
  ...apiKey === void 0 ? {} : { apiKey },
2668
2761
  ...avalancheCRpc === void 0 ? {} : { avalancheCRpc },
2762
+ ...baseRpc === void 0 ? {} : { baseRpc },
2669
2763
  ...ethereumRpc === void 0 ? {} : { ethereumRpc },
2670
2764
  ...solanaRpc === void 0 ? {} : { solanaRpc },
2671
2765
  ...config.webSocket === void 0 ? {} : { webSocket: config.webSocket }
@@ -3039,6 +3133,19 @@ var createAvalancheClient = (transport, indexTransports, nativeTransport = trans
3039
3133
  }
3040
3134
  });
3041
3135
 
3136
+ // src/rpc/base.ts
3137
+ var createBaseClient = (transport) => {
3138
+ const ethereumRpc = createEthereumClient(transport).rpc;
3139
+ return {
3140
+ rpc: {
3141
+ endpoint: ethereumRpc.endpoint,
3142
+ eth_chainId: ethereumRpc.eth_chainId,
3143
+ eth_getBalance: ethereumRpc.eth_getBalance,
3144
+ eth_call: ethereumRpc.eth_call
3145
+ }
3146
+ };
3147
+ };
3148
+
3042
3149
  // src/rpc/solana.ts
3043
3150
  var SOLANA_RPC_METHODS = [
3044
3151
  "getAccountInfo",
@@ -5199,8 +5306,14 @@ var HttpJsonRpcTransport = class {
5199
5306
  this.#unavailableNamespace = config.unavailableNamespace;
5200
5307
  this.maxBatchSize = config.maxBatchSize ?? 256;
5201
5308
  const endpoint = new URL(config.endpoint);
5202
- endpoint.search = "";
5203
- endpoint.hash = "";
5309
+ if (this.#direct) {
5310
+ endpoint.pathname = "/";
5311
+ endpoint.search = "";
5312
+ endpoint.hash = "";
5313
+ } else {
5314
+ endpoint.search = "";
5315
+ endpoint.hash = "";
5316
+ }
5204
5317
  this.endpoint = endpoint.toString();
5205
5318
  }
5206
5319
  async request(method, params, options = {}) {
@@ -5471,6 +5584,7 @@ var createErpcClient = (config) => {
5471
5584
  const solanaTransport = resolved.solanaRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("solana.rpc") : createLegacyHttp(resolved.endpoint) : createDirectHttp(resolved.solanaRpc);
5472
5585
  const ethereumTransport = resolved.ethereumRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("ethereum.rpc") : createLegacyHttp(endpointWithPath(resolved.endpoint, "/eth")) : createDirectHttp(resolved.ethereumRpc);
5473
5586
  const avalancheTransport = resolved.avalancheCRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("avalanche.rpc") : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, "/ava")) : createDirectHttp(resolved.avalancheCRpc);
5587
+ const baseTransport = resolved.baseRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("base") : createLegacyHttp(resolved.baseEndpoint) : createDirectHttp(resolved.baseRpc);
5474
5588
  const avalancheNativeTransport = resolved.apiKey === void 0 ? createUnavailableHttp("avalanche.native") : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, "/ava"));
5475
5589
  const avalancheIndexTransport = (path, namespace) => resolved.apiKey === void 0 ? createUnavailableHttp(namespace) : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, path));
5476
5590
  const solanaWebSocket = resolved.solanaRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("solana.subscriptions") : createLegacyWebSocket(websocketUrl(resolved.endpoint, resolved.apiKey)) : createDirectWebSocket(resolved.solanaRpc, "solana.subscriptions");
@@ -5533,6 +5647,7 @@ var createErpcClient = (config) => {
5533
5647
  solana,
5534
5648
  ethereum,
5535
5649
  avalanche,
5650
+ base: createBaseClient(baseTransport),
5536
5651
  price: new PriceClient(priceTransport),
5537
5652
  account: new AccountClient(accountTransport),
5538
5653
  swap,
@@ -5719,7 +5834,7 @@ var requireFetch2 = (provided) => {
5719
5834
  "A Fetch API implementation is required in this runtime"
5720
5835
  );
5721
5836
  }
5722
- return implementation;
5837
+ return wrapFetch(implementation);
5723
5838
  };
5724
5839
  var cloudEndpoint = (value) => {
5725
5840
  let endpoint;
@@ -5762,9 +5877,1514 @@ var createErpcCloudClient = (config) => {
5762
5877
  };
5763
5878
 
5764
5879
  // src/generated/bridge_capabilities.ts
5765
- 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"}]';
5766
- var BRIDGE_CAPABILITIES_CONTENT_DIGEST = "fe698f99218057f8cb40b3e24421d1d78e4e2cd7508cf6e3eb2457b329e5141b";
5767
- var BRIDGE_CAPABILITIES_AS_OF_DATE = "2026-09-16";
5880
+ 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"},{"bridgeCapabilityId":"bridge-mayan-swift-v2-usdc-eth-sol","providerId":"mayan-swift-v2","capabilityKind":"external-provider-dynamic","sourceChainId":"eip155:1","destinationChainId":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","sourceTokenDeploymentId":"deployment-0008","destinationTokenDeploymentId":"deployment-0010","sourceTokenAddress":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","destinationTokenAddress":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","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":"0xe4269fc4","jupiterProgramAddress":null,"builderEndpoint":"https://tx-builder.mayan.finance","explorerEndpoint":"https://explorer-api.mayan.finance/v3","dependencies":["mayan-hosted-quote-api","mayan-hosted-transaction-builder","swift-auction-solvers","relayers","wormhole-guardian-messaging","mayan-explorer-indexer"],"status":"active"},{"bridgeCapabilityId":"bridge-mayan-swift-v2-usdc-sol-eth","providerId":"mayan-swift-v2","capabilityKind":"external-provider-dynamic","sourceChainId":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","destinationChainId":"eip155:1","sourceTokenDeploymentId":"deployment-0010","destinationTokenDeploymentId":"deployment-0008","sourceTokenAddress":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","destinationTokenAddress":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","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":null,"builderEndpoint":"https://tx-builder.mayan.finance","explorerEndpoint":"https://explorer-api.mayan.finance/v3","dependencies":["mayan-hosted-quote-api","mayan-hosted-transaction-builder","swift-auction-solvers","relayers","wormhole-guardian-messaging","mayan-explorer-indexer"],"status":"active"}]';
5881
+ var BRIDGE_CAPABILITIES_CONTENT_DIGEST = "691a77498c5ff876dadc437a8265d8288ec51cbc1d44f8beacb746626bf5b98d";
5882
+ var BRIDGE_CAPABILITIES_AS_OF_DATE = "2026-09-17";
5883
+ var ETHEREUM_CHAIN_ID = TOKEN_CHAIN_IDS.ethereumMainnet;
5884
+ var SOLANA_CHAIN_ID = TOKEN_CHAIN_IDS.solanaMainnet;
5885
+ var ETHEREUM_FORWARDER = "0x337685fdab40d39bd02028545a4ffa7d287cc3e2";
5886
+ var ETHEREUM_FORWARDER_PROVIDER = "0x337685fdaB40D39bd02028545a4FfA7D287cC3E2";
5887
+ var SOLANA_SWIFT_PROGRAM = "mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny";
5888
+ var SOLANA_JUPITER_V6 = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
5889
+ var SOLANA_TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
5890
+ var SOLANA_ASSOCIATED_TOKEN_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
5891
+ var SOLANA_SYSTEM_PROGRAM = "11111111111111111111111111111111";
5892
+ var SOLANA_SYSVAR_RENT = "SysvarRent111111111111111111111111111111111";
5893
+ var SOLANA_COMPUTE_BUDGET_PROGRAM = "ComputeBudget111111111111111111111111111111";
5894
+ var SOLANA_CPI_PROXY_PROGRAM = "D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa";
5895
+ var SOLANA_ANCHOR_EVENT_AUTHORITY = "D8cy77BBepLMngZx6ZukaTff5hCt1HrWyKk3Hnd9oitf";
5896
+ var SOLANA_FEE_MANAGER_PROGRAM = "5VtQHnhs2pfVEr68qQsbTRwKh4JV5GTu9mBHgHFxpHeQ";
5897
+ var SOLANA_MAINNET_GENESIS_HASH = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
5898
+ var SOLANA_MAYAN_LOOKUP_TABLE = "Ff3yi1meWQQ19VPZMzGg6H8JQQeRudiV7QtVtyzJyoht";
5899
+ var SOLANA_ADDRESS_LOOKUP_TABLE_OWNER = "AddressLookupTab1e1111111111111111111111111";
5900
+ var SOLANA_ROUTE_V2_DISCRIMINATOR = "bb64facc31c4af14";
5901
+ var SOLANA_ROUTE_V2_WHIRLPOOL_TAIL = "000001000000110010270001";
5902
+ var SOLANA_ROUTE_V2_RAYDIUM_TAIL = "0000010000001a10270001";
5903
+ var SOLANA_WHIRLPOOL_PROGRAM = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
5904
+ var SOLANA_WHIRLPOOL_POOL = "ArisQNcbjXPJD7RgPRvysatX3xcfHPTbcTkfD8kDoZ9i";
5905
+ var SOLANA_RAYDIUM_CLMM_PROGRAM = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK";
5906
+ var SOLANA_RAYDIUM_CLMM_POOL = "2zVV22uNWdJNmkXpj5vCrMzwHGBoJdsyV7qACh29sK1w";
5907
+ var SOLANA_INIT_ORDER_DISCRIMINATOR = "204c290c27a284db";
5908
+ var EVM_SOURCE_SWAP_SELECTOR = "0x3f0bde25";
5909
+ var SOLANA_MAYAN_SOURCE_SWAP_ENDPOINT = "https://price-api.mayan.finance/v3";
5910
+ var MAYAN_REFERENCE_COMMIT = "c4c98031aaad9264d17630d7b4de0cb18688cf78";
5911
+ var MAYAN_ORACLE_SDK_VERSION = "15_2_2";
5912
+ var MAX_RESPONSE_BYTES = 1024 * 1024;
5913
+ var MAX_JSON_DEPTH = 32;
5914
+ var MAX_ROUTER_CALLDATA_BYTES = 16384;
5915
+ var MAX_SOLANA_SWAP_ACCOUNTS = 64;
5916
+ var MAX_SOLANA_SWAP_DATA_BYTES = 4096;
5917
+ var MAX_LOOKUP_TABLES = 8;
5918
+ var MAX_LOOKUP_TABLE_ADDRESSES = 256;
5919
+ var MAX_SOLANA_TRANSACTION_BYTES = 1232;
5920
+ var UINT64_MAX = (1n << 64n) - 1n;
5921
+ var EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/u;
5922
+ var HEX_BYTES2 = /^0x(?:[0-9a-fA-F]{2})*$/u;
5923
+ var UINT64 = /^(0|[1-9][0-9]*)$/u;
5924
+ var NONCE = /^0x[0-9a-f]{32}$/u;
5925
+ var PLAIN_DECIMAL = /^(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/u;
5926
+ var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
5927
+ var capabilities = JSON.parse(BRIDGE_CAPABILITIES_JSON);
5928
+ var concatBytes = (...parts) => {
5929
+ const length = parts.reduce((sum, part) => sum + part.length, 0);
5930
+ const result = new Uint8Array(length);
5931
+ let offset = 0;
5932
+ for (const part of parts) {
5933
+ result.set(part, offset);
5934
+ offset += part.length;
5935
+ }
5936
+ return result;
5937
+ };
5938
+ var bytesToHex = (bytes) => [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
5939
+ var hexToBytes = (value) => {
5940
+ const normalized = value.startsWith("0x") ? value.slice(2) : value;
5941
+ if (!/^(?:[0-9a-fA-F]{2})*$/u.test(normalized)) throw new Error("invalid hex");
5942
+ const bytes = new Uint8Array(normalized.length / 2);
5943
+ for (let index = 0; index < bytes.length; index += 1) {
5944
+ bytes[index] = Number.parseInt(normalized.slice(index * 2, index * 2 + 2), 16);
5945
+ }
5946
+ return bytes;
5947
+ };
5948
+ var sha256Hex = (value) => bytesToHex(sha256(typeof value === "string" ? new TextEncoder().encode(value) : value));
5949
+ var keccakHex = (value) => bytesToHex(keccak_256(value));
5950
+ var stableJson = (value) => {
5951
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
5952
+ if (value !== null && typeof value === "object") {
5953
+ const object = value;
5954
+ return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${stableJson(object[key])}`).join(",")}}`;
5955
+ }
5956
+ return JSON.stringify(value);
5957
+ };
5958
+ var cloneJson = (value) => JSON.parse(JSON.stringify(value));
5959
+ var assertJsonDepth = (value, depth = 0) => {
5960
+ if (depth > MAX_JSON_DEPTH) throw new Error("json depth");
5961
+ if (Array.isArray(value)) {
5962
+ for (const child of value) assertJsonDepth(child, depth + 1);
5963
+ } else if (value !== null && typeof value === "object") {
5964
+ for (const child of Object.values(value)) assertJsonDepth(child, depth + 1);
5965
+ }
5966
+ };
5967
+ var parseJsonObject = (text) => {
5968
+ if (new TextEncoder().encode(text).length > MAX_RESPONSE_BYTES) throw new Error("response too large");
5969
+ const value = JSON.parse(text);
5970
+ assertJsonDepth(value);
5971
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("object expected");
5972
+ return value;
5973
+ };
5974
+ var normalizeEvmAddress3 = (value) => {
5975
+ if (typeof value !== "string" || !EVM_ADDRESS2.test(value) || /^0x0{40}$/iu.test(value)) throw new Error("EVM address");
5976
+ return value.toLowerCase();
5977
+ };
5978
+ var base58Decode = (value) => {
5979
+ if (typeof value !== "string" || value.length === 0) throw new Error("base58");
5980
+ let result = 0n;
5981
+ for (const character of value) {
5982
+ const digit = BASE58_ALPHABET.indexOf(character);
5983
+ if (digit < 0) throw new Error("base58");
5984
+ result = result * 58n + BigInt(digit);
5985
+ }
5986
+ const bytes = [];
5987
+ while (result > 0n) {
5988
+ bytes.push(Number(result & 0xffn));
5989
+ result >>= 8n;
5990
+ }
5991
+ bytes.reverse();
5992
+ let leading = 0;
5993
+ while (leading < value.length && value[leading] === "1") leading += 1;
5994
+ return Uint8Array.from([...new Uint8Array(leading), ...bytes]);
5995
+ };
5996
+ var base58Encode = (value) => {
5997
+ let number = 0n;
5998
+ for (const byte of value) number = number * 256n + BigInt(byte);
5999
+ let result = "";
6000
+ while (number > 0n) {
6001
+ const digit = Number(number % 58n);
6002
+ result = BASE58_ALPHABET[digit] + result;
6003
+ number /= 58n;
6004
+ }
6005
+ let leading = 0;
6006
+ while (leading < value.length && value[leading] === 0) leading += 1;
6007
+ return `${"1".repeat(leading)}${result}`;
6008
+ };
6009
+ var canonicalSolanaAddress = (value) => {
6010
+ const bytes = base58Decode(value);
6011
+ if (bytes.length !== 32 || base58Encode(bytes) !== value) throw new Error("Solana address");
6012
+ return value;
6013
+ };
6014
+ var uint64 = (value, positive = false) => {
6015
+ if (typeof value !== "string" || !UINT64.test(value) || value.length > 20) throw new Error("uint64");
6016
+ const parsed = BigInt(value);
6017
+ if (parsed > UINT64_MAX || positive && parsed === 0n) throw new Error("uint64");
6018
+ return parsed;
6019
+ };
6020
+ var wordUint = (value) => {
6021
+ if (value < 0n || value >= 1n << 256n) throw new Error("ABI uint");
6022
+ const result = new Uint8Array(32);
6023
+ let remaining = value;
6024
+ for (let index = 31; index >= 0; index -= 1) {
6025
+ result[index] = Number(remaining & 0xffn);
6026
+ remaining >>= 8n;
6027
+ }
6028
+ return result;
6029
+ };
6030
+ var wordAddress = (value) => {
6031
+ const bytes = hexToBytes(normalizeEvmAddress3(value));
6032
+ return concatBytes(new Uint8Array(12), bytes);
6033
+ };
6034
+ var wordBytes32 = (value) => {
6035
+ if (value.length !== 32) throw new Error("bytes32");
6036
+ return value;
6037
+ };
6038
+ var pad32 = (value) => {
6039
+ const padded = new Uint8Array(Math.ceil(value.length / 32) * 32);
6040
+ padded.set(value);
6041
+ return padded;
6042
+ };
6043
+ var encodeAbiBytes = (value) => concatBytes(wordUint(BigInt(value.length)), pad32(value));
6044
+ var encodeAbiWithDynamics = (head, dynamics) => {
6045
+ const headSize = (head.length + dynamics.length) * 32;
6046
+ let offset = headSize;
6047
+ const offsets = dynamics.map((value) => {
6048
+ const current = offset;
6049
+ offset += 32 + Math.ceil(value.length / 32) * 32;
6050
+ return current;
6051
+ });
6052
+ return concatBytes(
6053
+ ...head.map((word) => word),
6054
+ ...offsets.map((entry) => wordUint(BigInt(entry))),
6055
+ ...dynamics.map(encodeAbiBytes)
6056
+ );
6057
+ };
6058
+ var nativeAddressBytes = (value, chainId) => {
6059
+ if (chainId === ETHEREUM_CHAIN_ID) return wordAddress(value);
6060
+ canonicalSolanaAddress(value);
6061
+ return base58Decode(value);
6062
+ };
6063
+ var routeForQuote = (quote) => {
6064
+ const route = capabilities.find((entry) => entry.sourceChainId === quote.sourceChainId && entry.destinationChainId === quote.destinationChainId && entry.sourceTokenDeploymentId === quote.sourceTokenDeploymentId && entry.destinationTokenDeploymentId === quote.destinationTokenDeploymentId);
6065
+ if (!route) throw new Error("route");
6066
+ return route;
6067
+ };
6068
+ var sourceIsUsdc = (route) => route.bridgeCapabilityId.includes("-usdc-");
6069
+ var providerStandard = (chainId) => chainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl";
6070
+ var assertCatalogToken = (deploymentId, chainId, address, standard) => {
6071
+ const token = getTokenDeployment(deploymentId);
6072
+ if (!token || token.chainId !== chainId || token.address === null || token.standard !== standard || token.decimals !== 6 || token.status !== "active" || (chainId === ETHEREUM_CHAIN_ID ? token.address.toLowerCase() !== address.toLowerCase() : token.address !== address)) throw new Error("token");
6073
+ return token;
6074
+ };
6075
+ var validateLocalRoute = (quote) => {
6076
+ const route = routeForQuote(quote);
6077
+ if (route.providerId !== "mayan-swift-v2" || route.status !== "active") throw new Error("route");
6078
+ assertCatalogToken(route.sourceTokenDeploymentId, route.sourceChainId, route.sourceTokenAddress, route.sourceTokenStandard);
6079
+ assertCatalogToken(route.destinationTokenDeploymentId, route.destinationChainId, route.destinationTokenAddress, route.destinationTokenStandard);
6080
+ assertCatalogToken(route.sourceUsdcDeploymentId, route.sourceChainId, route.sourceUsdcAddress, route.sourceUsdcStandard);
6081
+ if (quote.sourceSwap.required !== !sourceIsUsdc(route)) throw new Error("quote");
6082
+ if (quote.sourceSwap.inputTokenDeploymentId !== route.sourceTokenDeploymentId || quote.sourceSwap.intermediateTokenDeploymentId !== route.sourceUsdcDeploymentId || quote.sourceSwap.intermediateTokenAddress !== route.sourceUsdcAddress || quote.sourceSwap.intermediateTokenStandard !== providerStandard(route.sourceChainId) || quote.sourceSwap.intermediateTokenDecimals !== 6) throw new Error("quote");
6083
+ if (sourceIsUsdc(route)) {
6084
+ if (quote.sourceSwap.routerKind !== null || quote.sourceSwap.routerAddress !== null) throw new Error("quote");
6085
+ if (JSON.stringify(quote.dependencies) !== JSON.stringify(route.dependencies)) throw new Error("quote");
6086
+ } else if (route.sourceChainId === ETHEREUM_CHAIN_ID && (quote.sourceSwap.routerKind !== "provider-selected-evm" || quote.sourceSwap.routerAddress === null) || route.sourceChainId === SOLANA_CHAIN_ID && (quote.sourceSwap.routerKind !== "jupiter-v6" || quote.sourceSwap.routerAddress !== SOLANA_JUPITER_V6) || JSON.stringify(quote.dependencies) !== JSON.stringify(route.dependencies)) throw new Error("quote");
6087
+ const raw = parseJsonObject(quote.rawSignedQuoteJson);
6088
+ if (raw.swiftWrapAndLock !== void 0 && raw.swiftWrapAndLock !== false) throw new Error("quote");
6089
+ if (!sourceIsUsdc(route) && route.sourceChainId === ETHEREUM_CHAIN_ID) {
6090
+ if (raw.evmSwapRouterAddress !== void 0 && !rawAddressEquals(raw.evmSwapRouterAddress, quote.sourceSwap.routerAddress ?? "")) throw new Error("quote");
6091
+ if (raw.evmSwapRouterCalldata !== void 0 && (typeof raw.evmSwapRouterCalldata !== "string" || !HEX_BYTES2.test(raw.evmSwapRouterCalldata) || raw.evmSwapRouterCalldata === "0x" || hexToBytes(raw.evmSwapRouterCalldata).length > MAX_ROUTER_CALLDATA_BYTES)) throw new Error("quote");
6092
+ }
6093
+ const mode = raw.swiftAuctionMode;
6094
+ if (mode !== 2 && mode !== 3) throw new Error("quote");
6095
+ if (mode !== (sourceIsUsdc(route) ? 3 : 2)) throw new Error("quote");
6096
+ if (mode === 3 && (raw.expectedAmountOutBaseUnits !== raw.minAmountOutBaseUnits || raw.minAmountOutBaseUnits !== raw.minReceivedBaseUnits)) throw new Error("quote");
6097
+ const forbidden = ["customPayload", "memoHex", "referrer", "referrerAddress", "swiftRefundAddress", "permit", "approval", "approvalBatch", "separateSwapTx", "jito", "extraInstructions"];
6098
+ for (const key of forbidden) if (Object.hasOwn(raw, key) && raw[key] !== null && raw[key] !== false && raw[key] !== "") throw new Error("quote");
6099
+ return route;
6100
+ };
6101
+ var extractRawNumberLexeme = (raw, key) => {
6102
+ const expression = new RegExp(`"${key}"\\s*:\\s*([^,}\\s]+)`, "gu");
6103
+ const matches = [...raw.matchAll(expression)];
6104
+ const match = matches[0];
6105
+ if (matches.length !== 1 || match === void 0 || match[1] === void 0) throw new Error("number");
6106
+ return match[1];
6107
+ };
6108
+ var parsePlainDecimal = (value) => {
6109
+ if (!PLAIN_DECIMAL.test(value)) throw new Error("decimal");
6110
+ const separator = value.indexOf(".");
6111
+ const integerPart = separator === -1 ? value : value.slice(0, separator);
6112
+ const fractionalPart = separator === -1 ? "" : value.slice(separator + 1);
6113
+ const integer = BigInt(integerPart);
6114
+ const keptFraction = fractionalPart.slice(0, 6).padEnd(6, "0");
6115
+ const result = integer * 1000000n + BigInt(keptFraction || "0");
6116
+ if (result <= 0n || result > UINT64_MAX) throw new Error("decimal");
6117
+ return { source: value, integer: result, scale: fractionalPart.length };
6118
+ };
6119
+ var binary64RoundedDecimalUnits = (value) => {
6120
+ const number = Number(value);
6121
+ if (!Number.isFinite(number) || number <= 0 || number === 0) throw new Error("decimal");
6122
+ const bits = new DataView(new ArrayBuffer(8));
6123
+ bits.setFloat64(0, number, false);
6124
+ const high = BigInt(bits.getUint32(0, false));
6125
+ const low = BigInt(bits.getUint32(4, false));
6126
+ const encoded = high << 32n | low;
6127
+ const exponent = Number(encoded >> 52n & 0x7ffn);
6128
+ const fraction = encoded & (1n << 52n) - 1n;
6129
+ const mantissa = exponent === 0 ? fraction : 1n << 52n | fraction;
6130
+ const binaryExponent = exponent === 0 ? -1074 : exponent - 1023 - 52;
6131
+ let numerator = mantissa * 10000000n;
6132
+ let denominator = 1n;
6133
+ if (binaryExponent >= 0) numerator <<= BigInt(binaryExponent);
6134
+ else denominator <<= BigInt(-binaryExponent);
6135
+ let rounded = numerator / denominator;
6136
+ const remainder = numerator % denominator;
6137
+ if (remainder * 2n >= denominator) rounded += 1n;
6138
+ const result = rounded / 10n;
6139
+ if (result <= 0n || result > UINT64_MAX) throw new Error("decimal");
6140
+ return result;
6141
+ };
6142
+ var exactIntermediateAmount = (raw, direct, amountIn) => {
6143
+ const decimal = parsePlainDecimal(raw);
6144
+ const exact = decimal.integer;
6145
+ if (direct) {
6146
+ if (exact !== uint64(amountIn, true)) throw new Error("decimal");
6147
+ return exact.toString();
6148
+ }
6149
+ if (binary64RoundedDecimalUnits(raw) !== exact) throw new Error("decimal");
6150
+ return exact.toString();
6151
+ };
6152
+ var validateDestinationMinimumCompatibility = (raw, canonical) => {
6153
+ const units = uint64(canonical, true);
6154
+ const lexeme = extractRawNumberLexeme(raw, "minAmountOut");
6155
+ if (parsePlainDecimal(lexeme).integer !== units || binary64RoundedDecimalUnits(lexeme) !== units) {
6156
+ throw new Error("destination minimum");
6157
+ }
6158
+ };
6159
+ var rawUint64 = (raw, key, required = true) => {
6160
+ const value = raw[key];
6161
+ if (value === void 0 && !required) return 0n;
6162
+ return uint64(value, false);
6163
+ };
6164
+ var rawAddressEquals = (value, expected) => typeof value === "string" && (EVM_ADDRESS2.test(expected) ? value.toLowerCase() === expected.toLowerCase() : value === expected);
6165
+ var isOnCurveZip215 = (bytes) => {
6166
+ try {
6167
+ ed25519.Point.fromBytes(bytes, true);
6168
+ return true;
6169
+ } catch {
6170
+ return false;
6171
+ }
6172
+ };
6173
+ var findProgramAddress = (seeds, programId) => {
6174
+ if (seeds.length > 16 || seeds.some((seed) => seed.length > 32)) throw new Error("PDA seeds");
6175
+ const program = base58Decode(programId);
6176
+ if (program.length !== 32) throw new Error("PDA program");
6177
+ const suffix = new TextEncoder().encode("ProgramDerivedAddress");
6178
+ for (let bump = 255; bump >= 0; bump -= 1) {
6179
+ const candidate = sha256(concatBytes(...seeds, Uint8Array.from([bump]), program, suffix));
6180
+ if (!isOnCurveZip215(candidate)) return { address: base58Encode(candidate), bump };
6181
+ }
6182
+ throw new Error("PDA unavailable");
6183
+ };
6184
+ var associatedTokenAddress = (owner, mint, allowOwnerOffCurve) => {
6185
+ const ownerBytes = base58Decode(owner);
6186
+ const mintBytes = base58Decode(mint);
6187
+ if (ownerBytes.length !== 32 || mintBytes.length !== 32) throw new Error("ATA address");
6188
+ if (!allowOwnerOffCurve && isOnCurveZip215(ownerBytes) === false) throw new Error("ATA owner");
6189
+ return findProgramAddress(
6190
+ [ownerBytes, base58Decode(SOLANA_TOKEN_PROGRAM), mintBytes],
6191
+ SOLANA_ASSOCIATED_TOKEN_PROGRAM
6192
+ ).address;
6193
+ };
6194
+ var parseSourceQuote = (quote, route) => {
6195
+ const raw = parseJsonObject(quote.rawSignedQuoteJson);
6196
+ const minimumLexeme = extractRawNumberLexeme(quote.rawSignedQuoteJson, "minMiddleAmount");
6197
+ const modeValue = raw.swiftAuctionMode;
6198
+ if (modeValue !== 2 && modeValue !== 3) throw new Error("mode");
6199
+ const mode = modeValue === 2 || modeValue === 3 ? modeValue : sourceIsUsdc(route) ? 3 : 2;
6200
+ if (mode !== (sourceIsUsdc(route) ? 3 : 2)) throw new Error("mode");
6201
+ if (mode === 3 && (raw.expectedAmountOutBaseUnits !== raw.minAmountOutBaseUnits || raw.minAmountOutBaseUnits !== raw.minReceivedBaseUnits)) throw new Error("guaranteed output");
6202
+ const minimumIntermediateAmount = exactIntermediateAmount(minimumLexeme, sourceIsUsdc(route), quote.amountIn);
6203
+ if (quote.sourceSwap.providerMinimumAmount !== minimumLexeme) throw new Error("provider minimum");
6204
+ if (!sourceIsUsdc(route)) {
6205
+ const numeric = Number(minimumLexeme);
6206
+ if (!Number.isFinite(numeric) || numeric <= 0) throw new Error("number");
6207
+ }
6208
+ return {
6209
+ raw,
6210
+ minimumIntermediateAmount,
6211
+ mode,
6212
+ cancelFee: rawUint64(raw, "cancelRelayerFee64"),
6213
+ refundFee: rawUint64(raw, "refundRelayerFee64"),
6214
+ submitFee: rawUint64(raw, "submitRelayerFee64")
6215
+ };
6216
+ };
6217
+ var swiftRandom = (quoteId, orderNonce) => concatBytes(hexToBytes(quoteId), hexToBytes(orderNonce));
6218
+ var writeUint16Be = (value) => {
6219
+ if (!Number.isSafeInteger(value) || value < 0 || value > 65535) throw new Error("uint16");
6220
+ return Uint8Array.from([value >>> 8 & 255, value & 255]);
6221
+ };
6222
+ var writeUint64Be = (value) => {
6223
+ if (value < 0n || value > UINT64_MAX) throw new Error("uint64");
6224
+ const result = new Uint8Array(8);
6225
+ let current = value;
6226
+ for (let index = 7; index >= 0; index -= 1) {
6227
+ result[index] = Number(current & 0xffn);
6228
+ current >>= 8n;
6229
+ }
6230
+ return result;
6231
+ };
6232
+ var writeUint64Le = (value) => {
6233
+ const result = writeUint64Be(value);
6234
+ return Uint8Array.from([...result].reverse());
6235
+ };
6236
+ var writeUint16Le = (value) => {
6237
+ const result = writeUint16Be(value);
6238
+ return Uint8Array.from([result[1], result[0]]);
6239
+ };
6240
+ var zero32 = () => new Uint8Array(32);
6241
+ var orderPreimage = (quote, route, swapperAddress, destinationAddress, orderNonce, minimumIntermediateAmount, cancelFee, refundFee, mode) => {
6242
+ const destinationMinimum = uint64(quote.minimumAmountOut, true);
6243
+ const parts = [
6244
+ Uint8Array.from([1]),
6245
+ nativeAddressBytes(swapperAddress, route.sourceChainId),
6246
+ writeUint16Be(route.sourceWormholeChainId),
6247
+ nativeAddressBytes(route.sourceUsdcAddress, route.sourceChainId),
6248
+ nativeAddressBytes(destinationAddress, route.destinationChainId),
6249
+ writeUint16Be(route.destinationWormholeChainId),
6250
+ nativeAddressBytes(route.destinationTokenAddress, route.destinationChainId),
6251
+ writeUint64Be(destinationMinimum),
6252
+ writeUint64Be(0n),
6253
+ writeUint64Be(cancelFee),
6254
+ writeUint64Be(refundFee),
6255
+ writeUint64Be(uint64(quote.deadline, true)),
6256
+ zero32(),
6257
+ Uint8Array.from([0, 0, mode]),
6258
+ swiftRandom(quote.quoteId, orderNonce),
6259
+ zero32()
6260
+ ];
6261
+ const result = concatBytes(...parts);
6262
+ if (result.length !== 272) throw new Error("order preimage");
6263
+ return result;
6264
+ };
6265
+ var hashOrder = (quote, route, swapperAddress, destinationAddress, orderNonce, minimumIntermediateAmount, cancelFee, refundFee, mode) => `0x${keccakHex(orderPreimage(quote, route, swapperAddress, destinationAddress, orderNonce, minimumIntermediateAmount, cancelFee, refundFee, mode))}`;
6266
+ var quoteBindingHash = (route, quote, rawQuoteSha256, orderNonce, swapperAddress, destinationAddress) => sha256Hex(stableJson({
6267
+ capabilityId: route.bridgeCapabilityId,
6268
+ destinationAddress,
6269
+ destinationChainId: route.destinationChainId,
6270
+ destinationTokenDeploymentId: route.destinationTokenDeploymentId,
6271
+ orderNonce,
6272
+ quoteId: quote.quoteId,
6273
+ rawQuoteSha256,
6274
+ sourceChainId: route.sourceChainId,
6275
+ sourceTokenDeploymentId: route.sourceTokenDeploymentId,
6276
+ swapperAddress
6277
+ }));
6278
+ var sourceSwapHashProjection = (sourceSwap) => {
6279
+ if (sourceSwap.kind === "none") return sourceSwap;
6280
+ if (sourceSwap.kind === "evm-router") {
6281
+ const { rawProviderSourceSwapJson: _raw2, ...value2 } = sourceSwap;
6282
+ return value2;
6283
+ }
6284
+ const { rawProviderSourceSwapJson: _raw, ...value } = sourceSwap;
6285
+ return value;
6286
+ };
6287
+ var planHash = (binding, sourceSwap) => sha256Hex(stableJson({ quoteBindingHash: binding, sourceSwap: sourceSwapHashProjection(sourceSwap) }));
6288
+ var endpointUrl = (value) => {
6289
+ const source = value === void 0 ? SOLANA_MAYAN_SOURCE_SWAP_ENDPOINT : value;
6290
+ if (typeof source !== "string" || source.length === 0 || source.trim() !== source) throw new Error("endpoint");
6291
+ let endpoint;
6292
+ try {
6293
+ endpoint = new URL(source);
6294
+ } catch {
6295
+ throw new Error("endpoint");
6296
+ }
6297
+ if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash || endpoint.protocol !== "https:" && !(endpoint.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]", "::1"].includes(endpoint.hostname))) throw new Error("endpoint");
6298
+ endpoint.pathname = endpoint.pathname.replace(/\/+$/u, "") || "/";
6299
+ return endpoint;
6300
+ };
6301
+ var sourceSwapUrl = (endpoint, chain, params) => {
6302
+ const result = new URL(endpoint);
6303
+ const basePath = result.pathname.replace(/\/+$/u, "");
6304
+ result.pathname = `${basePath}/get-swap/${chain}`.replace(/\/{2,}/gu, "/");
6305
+ for (const [key, value] of params) result.searchParams.append(key, String(value));
6306
+ return result;
6307
+ };
6308
+ var SourceResponseInvalidError = class extends Error {
6309
+ constructor() {
6310
+ super("invalid source response");
6311
+ this.name = "SourceResponseInvalidError";
6312
+ }
6313
+ };
6314
+ var disposeResponseBody = (response) => {
6315
+ if (response.body === null) return;
6316
+ try {
6317
+ const reader = response.body.getReader();
6318
+ void reader.cancel().catch(() => void 0);
6319
+ reader.releaseLock();
6320
+ } catch {
6321
+ }
6322
+ };
6323
+ var readSourceResponseText = async (response, signal) => {
6324
+ const declaredLength = response.headers.get("content-length");
6325
+ if (declaredLength !== null && /^\d+$/u.test(declaredLength) && Number(declaredLength) > MAX_RESPONSE_BYTES) {
6326
+ disposeResponseBody(response);
6327
+ throw new SourceResponseInvalidError();
6328
+ }
6329
+ if (response.body === null) return "";
6330
+ const reader = response.body.getReader();
6331
+ const chunks = [];
6332
+ let total = 0;
6333
+ let complete = false;
6334
+ let abortListener;
6335
+ try {
6336
+ while (true) {
6337
+ if (signal.aborted) throw new DOMException("aborted", "AbortError");
6338
+ const abortPromise = new Promise((_resolve, reject) => {
6339
+ abortListener = () => reject(new DOMException("aborted", "AbortError"));
6340
+ signal.addEventListener("abort", abortListener, { once: true });
6341
+ });
6342
+ let result;
6343
+ try {
6344
+ result = await Promise.race([reader.read(), abortPromise]);
6345
+ } finally {
6346
+ if (abortListener !== void 0) signal.removeEventListener("abort", abortListener);
6347
+ abortListener = void 0;
6348
+ }
6349
+ if (result.done) {
6350
+ complete = true;
6351
+ break;
6352
+ }
6353
+ if (!(result.value instanceof Uint8Array)) throw new SourceResponseInvalidError();
6354
+ total += result.value.byteLength;
6355
+ if (total > MAX_RESPONSE_BYTES) throw new SourceResponseInvalidError();
6356
+ chunks.push(result.value);
6357
+ }
6358
+ } finally {
6359
+ if (!complete) {
6360
+ try {
6361
+ await reader.cancel();
6362
+ } catch {
6363
+ }
6364
+ }
6365
+ reader.releaseLock();
6366
+ }
6367
+ const bytes = new Uint8Array(total);
6368
+ let offset = 0;
6369
+ for (const chunk of chunks) {
6370
+ bytes.set(chunk, offset);
6371
+ offset += chunk.byteLength;
6372
+ }
6373
+ try {
6374
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
6375
+ } catch {
6376
+ throw new SourceResponseInvalidError();
6377
+ }
6378
+ };
6379
+ var fetchSourceSwap = async (runtime, url, options) => {
6380
+ const controller = new AbortController();
6381
+ let timedOut = false;
6382
+ const timeout = setTimeout(() => {
6383
+ timedOut = true;
6384
+ controller.abort();
6385
+ }, runtime.timeoutMs);
6386
+ const abort = () => controller.abort();
6387
+ if (options?.signal?.aborted) controller.abort();
6388
+ else options?.signal?.addEventListener("abort", abort, { once: true });
6389
+ try {
6390
+ const response = await runtime.fetch(url, {
6391
+ method: "GET",
6392
+ headers: { accept: "application/json" },
6393
+ credentials: "omit",
6394
+ redirect: "manual",
6395
+ signal: controller.signal
6396
+ });
6397
+ if (!response.ok) {
6398
+ disposeResponseBody(response);
6399
+ runtime.fail("BRIDGE_PROVIDER_HTTP");
6400
+ }
6401
+ const text = await readSourceResponseText(response, controller.signal);
6402
+ let root;
6403
+ try {
6404
+ root = parseJsonObject(text);
6405
+ } catch {
6406
+ runtime.fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6407
+ }
6408
+ return { text, root };
6409
+ } catch (error) {
6410
+ if (error instanceof Error && error.name === "BridgeError") throw error;
6411
+ if (error instanceof SourceResponseInvalidError) runtime.fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6412
+ if (runtime.fail && timedOut) runtime.fail("BRIDGE_TIMEOUT");
6413
+ if (options?.signal?.aborted) runtime.fail("BRIDGE_ABORTED");
6414
+ if (error instanceof ErpcHttpError) runtime.fail("BRIDGE_PROVIDER_HTTP");
6415
+ runtime.fail("BRIDGE_PROVIDER_TRANSPORT");
6416
+ } finally {
6417
+ clearTimeout(timeout);
6418
+ options?.signal?.removeEventListener("abort", abort);
6419
+ }
6420
+ };
6421
+ var base64Decode = (value, maximumBytes = MAX_SOLANA_SWAP_DATA_BYTES) => {
6422
+ if (typeof value !== "string" || value.length > Math.ceil(maximumBytes * 4 / 3) + 4 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u.test(value)) throw new Error("base64");
6423
+ const bytes = Uint8Array.from(Buffer.from(value, "base64"));
6424
+ if (bytes.length > maximumBytes || Buffer.from(bytes).toString("base64") !== value) throw new Error("base64");
6425
+ return bytes;
6426
+ };
6427
+ var instructionFromRaw = (value) => {
6428
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("instruction");
6429
+ const source = value;
6430
+ if (Object.keys(source).sort().join(",") !== "accounts,data,programId") throw new Error("instruction");
6431
+ const programId = canonicalSolanaAddress(source.programId);
6432
+ if (!Array.isArray(source.accounts) || source.accounts.length > MAX_SOLANA_SWAP_ACCOUNTS) throw new Error("instruction");
6433
+ const accounts = source.accounts.map((entry) => {
6434
+ if (entry === null || typeof entry !== "object" || Array.isArray(entry)) throw new Error("account");
6435
+ const account = entry;
6436
+ if (Object.keys(account).sort().join(",") !== "isSigner,isWritable,pubkey" || typeof account.isSigner !== "boolean" || typeof account.isWritable !== "boolean") throw new Error("account");
6437
+ return {
6438
+ pubkey: canonicalSolanaAddress(account.pubkey),
6439
+ isSigner: account.isSigner,
6440
+ isWritable: account.isWritable
6441
+ };
6442
+ });
6443
+ const dataBase64 = source.data;
6444
+ base64Decode(dataBase64);
6445
+ return { programId, accounts, dataBase64 };
6446
+ };
6447
+ var encodeInstructionData = (value) => base64Decode(value);
6448
+ var accountAt = (instruction, index) => {
6449
+ const value = instruction.accounts[index];
6450
+ if (!value) throw new Error("account");
6451
+ return value;
6452
+ };
6453
+ var assertAccount = (account, pubkey, isSigner, isWritable) => {
6454
+ if (account.pubkey !== pubkey || account.isSigner !== isSigner || account.isWritable !== isWritable) {
6455
+ throw new Error("account");
6456
+ }
6457
+ };
6458
+ var validateComputeInstructions = (instructions) => {
6459
+ if (instructions.length > 2) throw new Error("compute");
6460
+ const tags = /* @__PURE__ */ new Set();
6461
+ for (const instruction of instructions) {
6462
+ if (instruction.programId !== SOLANA_COMPUTE_BUDGET_PROGRAM || instruction.accounts.length !== 0) throw new Error("compute");
6463
+ const data = encodeInstructionData(instruction.dataBase64);
6464
+ const tag = data[0];
6465
+ if (tag !== 2 && tag !== 3 || tags.has(tag)) throw new Error("compute");
6466
+ tags.add(tag);
6467
+ if (tag === 2) {
6468
+ if (data.length !== 5 || new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(1, true) > 14e5) throw new Error("compute");
6469
+ } else if (data.length !== 9 || new DataView(data.buffer, data.byteOffset, data.byteLength).getBigUint64(1, true) > 100000n) {
6470
+ throw new Error("compute");
6471
+ }
6472
+ }
6473
+ };
6474
+ var validateAtaSetup = (instructions, swapperAddress, stateAddress, sourceUsdcAddress) => {
6475
+ if (instructions.length === 0 || instructions.length > 2) throw new Error("setup");
6476
+ const tokenProgram = SOLANA_TOKEN_PROGRAM;
6477
+ const owners = /* @__PURE__ */ new Set();
6478
+ for (const instruction of instructions) {
6479
+ if (instruction.programId !== SOLANA_ASSOCIATED_TOKEN_PROGRAM || instruction.accounts.length !== 6) throw new Error("setup");
6480
+ const payer = accountAt(instruction, 0);
6481
+ assertAccount(payer, swapperAddress, true, true);
6482
+ const owner = accountAt(instruction, 2).pubkey;
6483
+ if (owner !== swapperAddress && owner !== stateAddress) throw new Error("setup");
6484
+ if (owners.has(owner)) throw new Error("setup");
6485
+ owners.add(owner);
6486
+ const expectedAta = associatedTokenAddress(owner, sourceUsdcAddress, owner === stateAddress);
6487
+ assertAccount(accountAt(instruction, 2), owner, false, false);
6488
+ assertAccount(accountAt(instruction, 1), expectedAta, false, true);
6489
+ assertAccount(accountAt(instruction, 3), sourceUsdcAddress, false, false);
6490
+ assertAccount(accountAt(instruction, 4), SOLANA_SYSTEM_PROGRAM, false, false);
6491
+ assertAccount(accountAt(instruction, 5), tokenProgram, false, false);
6492
+ const data = encodeInstructionData(instruction.dataBase64);
6493
+ if (data.length !== 0 && (data.length !== 1 || data[0] !== 1)) throw new Error("setup");
6494
+ }
6495
+ if (!owners.has(stateAddress)) throw new Error("setup");
6496
+ };
6497
+ var validateJupiterInstruction = (instruction, route, quote, stateTokenAccount, swapperAddress, minimumIntermediateAmount, sourceSwapRaw) => {
6498
+ if (instruction.programId !== SOLANA_JUPITER_V6 || instruction.accounts.length < 8 || instruction.accounts.length > MAX_SOLANA_SWAP_ACCOUNTS) throw new Error("jupiter");
6499
+ const data = encodeInstructionData(instruction.dataBase64);
6500
+ if (bytesToHex(data.slice(0, 8)) !== SOLANA_ROUTE_V2_DISCRIMINATOR) throw new Error("jupiter");
6501
+ const quoteResponse = sourceSwapRaw.quoteResponse;
6502
+ if (quoteResponse === null || typeof quoteResponse !== "object" || Array.isArray(quoteResponse)) throw new Error("jupiter");
6503
+ const quoteResponseRaw = quoteResponse.raw;
6504
+ if (quoteResponseRaw === null || typeof quoteResponseRaw !== "object" || Array.isArray(quoteResponseRaw)) throw new Error("jupiter");
6505
+ const routePlan = quoteResponseRaw.routePlan;
6506
+ if (!Array.isArray(routePlan) || routePlan.length !== 1) throw new Error("jupiter");
6507
+ const swapInfo = routePlan[0]?.swapInfo;
6508
+ if (swapInfo === null || typeof swapInfo !== "object" || Array.isArray(swapInfo)) throw new Error("jupiter");
6509
+ const swapInfoRecord = swapInfo;
6510
+ const quoteResponseRecord = quoteResponse;
6511
+ const quoteResponseRawRecord = quoteResponseRaw;
6512
+ if (!rawAddressEquals(quoteResponseRecord.inputMint, route.sourceTokenAddress) || !rawAddressEquals(quoteResponseRecord.outputMint, route.sourceUsdcAddress) || !rawAddressEquals(quoteResponseRawRecord.inputMint, route.sourceTokenAddress) || !rawAddressEquals(quoteResponseRawRecord.outputMint, route.sourceUsdcAddress) || !rawAddressEquals(swapInfoRecord.inputMint, route.sourceTokenAddress) || !rawAddressEquals(swapInfoRecord.outputMint, route.sourceUsdcAddress) || typeof swapInfoRecord.inAmount !== "string" || typeof swapInfoRecord.outAmount !== "string" || uint64(swapInfoRecord.inAmount, true) !== uint64(quote.amountIn, true) || uint64(swapInfoRecord.outAmount, true) < uint64(minimumIntermediateAmount, true)) throw new Error("jupiter");
6513
+ const label = swapInfo.label;
6514
+ const expectedTail = label === "Whirlpool" ? SOLANA_ROUTE_V2_WHIRLPOOL_TAIL : label === "Raydium CLMM" ? SOLANA_ROUTE_V2_RAYDIUM_TAIL : null;
6515
+ if (expectedTail === null || data.length !== 28 + expectedTail.length / 2 || bytesToHex(data.slice(28)) !== expectedTail) throw new Error("jupiter");
6516
+ const expectedAccountCount = label === "Whirlpool" ? 22 : 25;
6517
+ const expectedAccounts = label === "Whirlpool" ? [
6518
+ [swapperAddress, true, false],
6519
+ [associatedTokenAddress(swapperAddress, route.sourceTokenAddress, false), false, true],
6520
+ [associatedTokenAddress(swapperAddress, route.sourceUsdcAddress, false), false, true],
6521
+ [route.sourceTokenAddress, false, false],
6522
+ [route.sourceUsdcAddress, false, false],
6523
+ [SOLANA_TOKEN_PROGRAM, false, false],
6524
+ [SOLANA_TOKEN_PROGRAM, false, false],
6525
+ [stateTokenAccount, false, true],
6526
+ [SOLANA_ANCHOR_EVENT_AUTHORITY, false, false],
6527
+ [SOLANA_JUPITER_V6, false, false],
6528
+ [SOLANA_WHIRLPOOL_PROGRAM, false, false],
6529
+ [SOLANA_TOKEN_PROGRAM, false, false],
6530
+ [swapperAddress, false, false],
6531
+ [SOLANA_WHIRLPOOL_POOL, false, true],
6532
+ [associatedTokenAddress(swapperAddress, route.sourceUsdcAddress, false), false, true],
6533
+ ["6i68TM44UYSawGAS4Bx1vX31Af7QNZaRNBLUbc4r8exB", false, true],
6534
+ [associatedTokenAddress(swapperAddress, route.sourceTokenAddress, false), false, true],
6535
+ ["8aq9zUXe37KLtXSaEYt7oq65oNAJiu1my2kRNMRPhTD5", false, true],
6536
+ ["7qscKXFXCd1WQinZJvSDLsGLTTEwjmd88a871pz2V3Ja", false, true],
6537
+ ["CaohZGaBaLmXyFQ4cLc83wGZTET7Mt9xMtUqR9EGaMHF", false, true],
6538
+ ["7Mr4WYMiGPAXkyt9ePsHHmV6ust3U6dHwBmyfMRiHPA7", false, true],
6539
+ ["9BjNZYSCZ3ac3XUYVKte4YYtmBGd7ATKfRshTGN99NxQ", false, false]
6540
+ ] : [
6541
+ [swapperAddress, true, false],
6542
+ [associatedTokenAddress(swapperAddress, route.sourceTokenAddress, false), false, true],
6543
+ [associatedTokenAddress(swapperAddress, route.sourceUsdcAddress, false), false, true],
6544
+ [route.sourceTokenAddress, false, false],
6545
+ [route.sourceUsdcAddress, false, false],
6546
+ [SOLANA_TOKEN_PROGRAM, false, false],
6547
+ [SOLANA_TOKEN_PROGRAM, false, false],
6548
+ [stateTokenAccount, false, true],
6549
+ [SOLANA_ANCHOR_EVENT_AUTHORITY, false, false],
6550
+ [SOLANA_JUPITER_V6, false, false],
6551
+ [SOLANA_RAYDIUM_CLMM_PROGRAM, false, false],
6552
+ [swapperAddress, false, false],
6553
+ ["9iFER3bpjf1PTTCQCfTRu17EJgvsxo9pVyA9QWwEuX4x", false, false],
6554
+ [SOLANA_RAYDIUM_CLMM_POOL, false, true],
6555
+ [associatedTokenAddress(swapperAddress, route.sourceTokenAddress, false), false, true],
6556
+ [associatedTokenAddress(swapperAddress, route.sourceUsdcAddress, false), false, true],
6557
+ ["GFwsANMCPK8W3WhqTnwVP8JiwHaAr3cNDe5TJqgHHSPe", false, true],
6558
+ ["ECw2X1TYbsrqFgdiYApNpn2ggznbj8pL5tREpY9Fb8jY", false, true],
6559
+ ["2UQncszfVU7igwDiGN3jq2sUKzziLxDZqNsJEXzEob5x", false, true],
6560
+ [SOLANA_TOKEN_PROGRAM, false, false],
6561
+ ["BVvv13QAQjPYKTWrpX7wQbhBAu3pbWwTb8P9SAqgRNKQ", false, true],
6562
+ ["4HSR9WBSHgw7n5V8WGYYhLW8g92RPSrgnf2CHzbeQrrr", false, true],
6563
+ ["HssFpWsQcNbJXBro1NVWCFAYEh8jp6NJV2nyFhE1zMGj", false, true],
6564
+ ["DKcmVcrXuiF5FZre6h8GqurR2sKChUGBakxdTX7dSDw9", false, true],
6565
+ [SOLANA_JUPITER_V6, false, false]
6566
+ ];
6567
+ const expectedPool = label === "Whirlpool" ? SOLANA_WHIRLPOOL_POOL : SOLANA_RAYDIUM_CLMM_POOL;
6568
+ if (instruction.accounts.length !== expectedAccountCount || expectedAccounts.length !== instruction.accounts.length) throw new Error("jupiter");
6569
+ for (const [index, [pubkey, isSigner, isWritable]] of expectedAccounts.entries()) {
6570
+ assertAccount(accountAt(instruction, index), pubkey, isSigner, isWritable);
6571
+ }
6572
+ if (typeof swapInfoRecord.ammKey !== "string" || swapInfoRecord.ammKey !== expectedPool) throw new Error("jupiter");
6573
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
6574
+ const inputAmount = view.getBigUint64(8, true);
6575
+ const quotedOutput = view.getBigUint64(16, true);
6576
+ const slippageBps = view.getUint16(24, true);
6577
+ const platformBps = view.getUint16(26, true);
6578
+ if (inputAmount !== uint64(quote.amountIn, true) || quotedOutput < uint64(minimumIntermediateAmount, true) || platformBps !== 0 || slippageBps > 1e4) throw new Error("jupiter");
6579
+ };
6580
+ var wrapInCpiProxy = (instruction) => ({
6581
+ programId: SOLANA_CPI_PROXY_PROGRAM,
6582
+ accounts: [
6583
+ { pubkey: instruction.programId, isSigner: false, isWritable: false },
6584
+ ...instruction.accounts
6585
+ ],
6586
+ dataBase64: instruction.dataBase64
6587
+ });
6588
+ var makeAtaInstruction = (swapperAddress, owner, mint, allowOwnerOffCurve) => ({
6589
+ programId: SOLANA_ASSOCIATED_TOKEN_PROGRAM,
6590
+ accounts: [
6591
+ { pubkey: swapperAddress, isSigner: true, isWritable: true },
6592
+ { pubkey: associatedTokenAddress(owner, mint, allowOwnerOffCurve), isSigner: false, isWritable: true },
6593
+ { pubkey: owner, isSigner: false, isWritable: false },
6594
+ { pubkey: mint, isSigner: false, isWritable: false },
6595
+ { pubkey: SOLANA_SYSTEM_PROGRAM, isSigner: false, isWritable: false },
6596
+ { pubkey: SOLANA_TOKEN_PROGRAM, isSigner: false, isWritable: false },
6597
+ { pubkey: SOLANA_SYSVAR_RENT, isSigner: false, isWritable: false }
6598
+ ],
6599
+ dataBase64: "AQ=="
6600
+ });
6601
+ var makeSplTransferInstruction = (source, destination, owner, amount) => ({
6602
+ programId: SOLANA_TOKEN_PROGRAM,
6603
+ accounts: [
6604
+ { pubkey: source, isSigner: false, isWritable: true },
6605
+ { pubkey: destination, isSigner: false, isWritable: true },
6606
+ { pubkey: owner, isSigner: true, isWritable: false }
6607
+ ],
6608
+ dataBase64: Buffer.from(Uint8Array.from([3, ...writeUint64Le(amount)])).toString("base64")
6609
+ });
6610
+ var makeComputeUnitPriceInstruction = (microLamports) => ({
6611
+ programId: SOLANA_COMPUTE_BUDGET_PROGRAM,
6612
+ accounts: [],
6613
+ dataBase64: Buffer.from(Uint8Array.from([3, ...writeUint64Le(microLamports)])).toString("base64")
6614
+ });
6615
+ var makeSwiftInitInstruction = (quote, route, swapperAddress, destinationAddress, stateAddress, stateTokenAccount, minimumIntermediateAmount, cancelFee, refundFee, submitFee, mode, orderNonce) => {
6616
+ const relayerAccount = associatedTokenAddress(swapperAddress, route.sourceUsdcAddress, false);
6617
+ const data = new Uint8Array(198);
6618
+ data.set(hexToBytes(`0x${SOLANA_INIT_ORDER_DISCRIMINATOR}`), 0);
6619
+ data.set(writeUint64Le(uint64(minimumIntermediateAmount, true)), 8);
6620
+ data[16] = 0;
6621
+ data.set(writeUint64Le(submitFee), 17);
6622
+ data.set(nativeAddressBytes(destinationAddress, route.destinationChainId), 25);
6623
+ data.set(writeUint16Le(route.destinationWormholeChainId), 57);
6624
+ data.set(nativeAddressBytes(route.destinationTokenAddress, route.destinationChainId), 59);
6625
+ data.set(writeUint64Le(uint64(quote.minimumAmountOut, true)), 91);
6626
+ data.set(writeUint64Le(0n), 99);
6627
+ data.set(writeUint64Le(cancelFee), 107);
6628
+ data.set(writeUint64Le(refundFee), 115);
6629
+ data.set(writeUint64Le(uint64(quote.deadline, true)), 123);
6630
+ data.set(zero32(), 131);
6631
+ data[163] = 0;
6632
+ data[164] = 0;
6633
+ data[165] = mode;
6634
+ data.set(swiftRandom(quote.quoteId, orderNonce), 166);
6635
+ const accounts = [
6636
+ { pubkey: swapperAddress, isSigner: false, isWritable: false },
6637
+ { pubkey: swapperAddress, isSigner: true, isWritable: true },
6638
+ { pubkey: stateAddress, isSigner: false, isWritable: true },
6639
+ { pubkey: stateTokenAccount, isSigner: false, isWritable: true },
6640
+ { pubkey: relayerAccount, isSigner: false, isWritable: true },
6641
+ { pubkey: SOLANA_SWIFT_PROGRAM, isSigner: false, isWritable: false },
6642
+ { pubkey: route.sourceUsdcAddress, isSigner: false, isWritable: false },
6643
+ { pubkey: SOLANA_FEE_MANAGER_PROGRAM, isSigner: false, isWritable: false },
6644
+ { pubkey: SOLANA_TOKEN_PROGRAM, isSigner: false, isWritable: false },
6645
+ { pubkey: SOLANA_SYSTEM_PROGRAM, isSigner: false, isWritable: false }
6646
+ ];
6647
+ return {
6648
+ programId: SOLANA_SWIFT_PROGRAM,
6649
+ accounts,
6650
+ dataBase64: Buffer.from(data).toString("base64")
6651
+ };
6652
+ };
6653
+ var encodeShortVec = (value) => {
6654
+ if (!Number.isSafeInteger(value) || value < 0 || value > 65535) throw new Error("shortvec");
6655
+ const bytes = [];
6656
+ let current = value;
6657
+ do {
6658
+ let element = current & 127;
6659
+ current >>>= 7;
6660
+ if (current !== 0) element |= 128;
6661
+ bytes.push(element);
6662
+ } while (current !== 0);
6663
+ return Uint8Array.from(bytes);
6664
+ };
6665
+ var compileSolanaV0 = (payer, recentBlockhash, instructions, lookupTables) => {
6666
+ const keyMeta = /* @__PURE__ */ new Map();
6667
+ const getOrInsert = (address) => {
6668
+ const existing = keyMeta.get(address);
6669
+ if (existing) return existing;
6670
+ const value = { signer: false, writable: false, invoked: false };
6671
+ keyMeta.set(address, value);
6672
+ return value;
6673
+ };
6674
+ const payerMeta = getOrInsert(payer);
6675
+ payerMeta.signer = true;
6676
+ payerMeta.writable = true;
6677
+ for (const instruction of instructions) {
6678
+ getOrInsert(instruction.programId).invoked = true;
6679
+ for (const account of instruction.accounts) {
6680
+ const meta = getOrInsert(account.pubkey);
6681
+ meta.signer ||= account.isSigner;
6682
+ meta.writable ||= account.isWritable;
6683
+ }
6684
+ }
6685
+ const lookupTableLookups = [];
6686
+ const writableLookupKeys = [];
6687
+ const readonlyLookupKeys = [];
6688
+ for (const table of lookupTables) {
6689
+ const writableIndexes = [];
6690
+ const readonlyIndexes = [];
6691
+ for (const [address, meta] of [...keyMeta.entries()]) {
6692
+ if (meta.signer || meta.invoked || !meta.writable) continue;
6693
+ const index = table.addresses.indexOf(address);
6694
+ if (index >= 0) {
6695
+ if (index > 255) throw new Error("ALT index");
6696
+ writableIndexes.push(index);
6697
+ writableLookupKeys.push(address);
6698
+ keyMeta.delete(address);
6699
+ }
6700
+ }
6701
+ for (const [address, meta] of [...keyMeta.entries()]) {
6702
+ if (meta.signer || meta.invoked || meta.writable) continue;
6703
+ const index = table.addresses.indexOf(address);
6704
+ if (index >= 0) {
6705
+ if (index > 255) throw new Error("ALT index");
6706
+ readonlyIndexes.push(index);
6707
+ readonlyLookupKeys.push(address);
6708
+ keyMeta.delete(address);
6709
+ }
6710
+ }
6711
+ if (writableIndexes.length > 0 || readonlyIndexes.length > 0) {
6712
+ lookupTableLookups.push({ accountKey: table.address, writableIndexes, readonlyIndexes });
6713
+ }
6714
+ }
6715
+ if (keyMeta.size > 256 || lookupTableLookups.length > MAX_LOOKUP_TABLES) throw new Error("account keys");
6716
+ const entries = [...keyMeta.entries()];
6717
+ const writableSigners = entries.filter(([, meta]) => meta.signer && meta.writable);
6718
+ const readonlySigners = entries.filter(([, meta]) => meta.signer && !meta.writable);
6719
+ const writableNonSigners = entries.filter(([, meta]) => !meta.signer && meta.writable);
6720
+ const readonlyNonSigners = entries.filter(([, meta]) => !meta.signer && !meta.writable);
6721
+ if (writableSigners.length !== 1 || readonlySigners.length !== 0 || writableSigners[0]?.[0] !== payer) throw new Error("payer");
6722
+ const staticKeys = [
6723
+ ...writableSigners.map(([address]) => address),
6724
+ ...readonlySigners.map(([address]) => address),
6725
+ ...writableNonSigners.map(([address]) => address),
6726
+ ...readonlyNonSigners.map(([address]) => address)
6727
+ ];
6728
+ const allKeys = [...staticKeys, ...writableLookupKeys, ...readonlyLookupKeys];
6729
+ if (allKeys.length > 256) throw new Error("account index");
6730
+ const keyIndexes = new Map(allKeys.map((address, index) => [address, index]));
6731
+ const compiled = instructions.map((instruction) => {
6732
+ const programIdIndex = keyIndexes.get(instruction.programId);
6733
+ if (programIdIndex === void 0) throw new Error("program index");
6734
+ const accountKeyIndexes = instruction.accounts.map((account) => {
6735
+ const index = keyIndexes.get(account.pubkey);
6736
+ if (index === void 0) throw new Error("account index");
6737
+ return index;
6738
+ });
6739
+ return { programIdIndex, accountKeyIndexes, data: encodeInstructionData(instruction.dataBase64) };
6740
+ });
6741
+ const header = Uint8Array.from([
6742
+ writableSigners.length + readonlySigners.length,
6743
+ readonlySigners.length,
6744
+ readonlyNonSigners.length
6745
+ ]);
6746
+ const compiledInstructionBytes = concatBytes(
6747
+ encodeShortVec(compiled.length),
6748
+ ...compiled.map((instruction) => concatBytes(
6749
+ Uint8Array.from([instruction.programIdIndex]),
6750
+ encodeShortVec(instruction.accountKeyIndexes.length),
6751
+ Uint8Array.from(instruction.accountKeyIndexes),
6752
+ encodeShortVec(instruction.data.length),
6753
+ instruction.data
6754
+ ))
6755
+ );
6756
+ const lookupBytes = concatBytes(
6757
+ encodeShortVec(lookupTableLookups.length),
6758
+ ...lookupTableLookups.map((lookup) => concatBytes(
6759
+ base58Decode(lookup.accountKey),
6760
+ encodeShortVec(lookup.writableIndexes.length),
6761
+ Uint8Array.from(lookup.writableIndexes),
6762
+ encodeShortVec(lookup.readonlyIndexes.length),
6763
+ Uint8Array.from(lookup.readonlyIndexes)
6764
+ ))
6765
+ );
6766
+ const message = concatBytes(
6767
+ Uint8Array.from([128]),
6768
+ header,
6769
+ encodeShortVec(staticKeys.length),
6770
+ ...staticKeys.map((address) => base58Decode(address)),
6771
+ base58Decode(canonicalSolanaAddress(recentBlockhash)),
6772
+ compiledInstructionBytes,
6773
+ lookupBytes
6774
+ );
6775
+ const requiredSignatures = writableSigners.length + readonlySigners.length;
6776
+ const transaction = concatBytes(
6777
+ encodeShortVec(requiredSignatures),
6778
+ new Uint8Array(requiredSignatures * 64),
6779
+ message
6780
+ );
6781
+ if (transaction.length > MAX_SOLANA_TRANSACTION_BYTES) throw new Error("transaction size");
6782
+ return {
6783
+ transactionBase64: Buffer.from(transaction).toString("base64"),
6784
+ lookupTableLookups
6785
+ };
6786
+ };
6787
+ var validateSourceSwapEnvelope = (quote, route, raw, stateAddress, stateTokenAccount, swapperAddress, minimumIntermediateAmount) => {
6788
+ const direct = sourceIsUsdc(route);
6789
+ if (direct) throw new Error("direct source swap");
6790
+ if (route.sourceChainId === ETHEREUM_CHAIN_ID) {
6791
+ if (Object.keys(raw).sort().join(",") !== "swapRouterAddress,swapRouterCalldata") throw new Error("source swap");
6792
+ const routerAddress = normalizeEvmAddress3(raw.swapRouterAddress);
6793
+ if (quote.sourceSwap.routerAddress !== routerAddress || quote.sourceSwap.routerKind !== "provider-selected-evm") throw new Error("source swap");
6794
+ if (typeof raw.swapRouterCalldata !== "string" || !HEX_BYTES2.test(raw.swapRouterCalldata) || raw.swapRouterCalldata === "0x" || !raw.swapRouterCalldata.toLowerCase().startsWith(EVM_SOURCE_SWAP_SELECTOR) || hexToBytes(raw.swapRouterCalldata).length > MAX_ROUTER_CALLDATA_BYTES) throw new Error("source swap");
6795
+ return {
6796
+ kind: "evm-router",
6797
+ routerAddress,
6798
+ calldata: raw.swapRouterCalldata.toLowerCase(),
6799
+ rawResponseSha256: "",
6800
+ rawProviderSourceSwapJson: ""
6801
+ };
6802
+ }
6803
+ if (Object.hasOwn(raw, "tokenLedgerInstruction") && raw.tokenLedgerInstruction !== null) throw new Error("source swap");
6804
+ if (!Array.isArray(raw.computeBudgetInstructions) || !Array.isArray(raw.setupInstructions) || raw.swapInstruction === void 0 || raw.swapInstruction === null) throw new Error("source swap");
6805
+ if (raw.cleanupInstruction !== null && raw.cleanupInstruction !== void 0) throw new Error("source swap");
6806
+ if (!Array.isArray(raw.otherInstructions) || raw.otherInstructions.length !== 0) throw new Error("source swap");
6807
+ if (raw.simulationError !== null && raw.simulationError !== void 0) throw new Error("source swap");
6808
+ if (raw.separateSwapTx !== void 0 && raw.separateSwapTx !== false) throw new Error("source swap");
6809
+ if (raw.jito !== void 0 && raw.jito !== false && raw.jito !== null) throw new Error("source swap");
6810
+ const compute = raw.computeBudgetInstructions.map(instructionFromRaw);
6811
+ const setup = raw.setupInstructions.map(instructionFromRaw);
6812
+ const swap = instructionFromRaw(raw.swapInstruction);
6813
+ validateComputeInstructions(compute);
6814
+ validateAtaSetup(setup, swapperAddress, stateAddress, route.sourceUsdcAddress);
6815
+ validateJupiterInstruction(swap, route, quote, stateTokenAccount, swapperAddress, minimumIntermediateAmount, raw);
6816
+ const providerAlts = raw.addressLookupTableAddresses;
6817
+ if (!Array.isArray(providerAlts) || providerAlts.length > MAX_LOOKUP_TABLES || providerAlts.some((address) => {
6818
+ try {
6819
+ canonicalSolanaAddress(address);
6820
+ return false;
6821
+ } catch {
6822
+ return true;
6823
+ }
6824
+ })) throw new Error("source swap");
6825
+ const addressLookupTableAddresses = providerAlts;
6826
+ if (raw.prioritizationFeeLamports !== void 0 && (typeof raw.prioritizationFeeLamports !== "number" || !Number.isSafeInteger(raw.prioritizationFeeLamports) || raw.prioritizationFeeLamports < 0)) throw new Error("source swap");
6827
+ if (raw.computeUnitLimit !== void 0 && (typeof raw.computeUnitLimit !== "number" || !Number.isSafeInteger(raw.computeUnitLimit) || raw.computeUnitLimit > 14e5)) throw new Error("source swap");
6828
+ return {
6829
+ kind: "solana-jupiter-v6",
6830
+ instructions: [...compute, ...setup, swap],
6831
+ addressLookupTableAddresses,
6832
+ rawResponseSha256: "",
6833
+ rawProviderSourceSwapJson: ""
6834
+ };
6835
+ };
6836
+ var preparePlan = (context, runtime, options) => {
6837
+ const snapshot = cloneJson(context);
6838
+ return (async () => {
6839
+ const context2 = {
6840
+ ...snapshot,
6841
+ quote: runtime.validateQuote(snapshot.quote, "BRIDGE_LOCAL_PLAN_INVALID")
6842
+ };
6843
+ let route;
6844
+ let rawQuote;
6845
+ let swapperAddress;
6846
+ let destinationAddress;
6847
+ let orderNonce;
6848
+ try {
6849
+ if (context2 === null || typeof context2 !== "object" || Array.isArray(context2)) throw new Error("context");
6850
+ const keys = Object.keys(context2).sort().join(",");
6851
+ if (keys !== "destinationAddress,orderNonce,quote,swapperAddress") throw new Error("context");
6852
+ route = validateLocalRoute(context2.quote);
6853
+ rawQuote = parseSourceQuote(context2.quote, route);
6854
+ swapperAddress = route.sourceChainId === ETHEREUM_CHAIN_ID ? normalizeEvmAddress3(context2.swapperAddress) : canonicalSolanaAddress(context2.swapperAddress);
6855
+ destinationAddress = route.destinationChainId === ETHEREUM_CHAIN_ID ? normalizeEvmAddress3(context2.destinationAddress) : canonicalSolanaAddress(context2.destinationAddress);
6856
+ orderNonce = context2.orderNonce;
6857
+ if (typeof orderNonce !== "string" || !NONCE.test(orderNonce)) throw new Error("nonce");
6858
+ validateDestinationMinimumCompatibility(context2.quote.rawSignedQuoteJson, context2.quote.minimumAmountOut);
6859
+ if (Math.floor(Date.now() / 1e3) + runtime.minimumQuoteValiditySeconds > Number(uint64(context2.quote.deadline, true))) runtime.fail("BRIDGE_QUOTE_EXPIRED");
6860
+ } catch (error) {
6861
+ if (error instanceof Error && error.name === "BridgeError") throw error;
6862
+ runtime.fail("BRIDGE_LOCAL_PLAN_INVALID");
6863
+ }
6864
+ const rawQuoteSha256 = sha256Hex(context2.quote.rawSignedQuoteJson);
6865
+ const orderHash = hashOrder(context2.quote, route, swapperAddress, destinationAddress, orderNonce, rawQuote.minimumIntermediateAmount, rawQuote.cancelFee, rawQuote.refundFee, rawQuote.mode);
6866
+ const binding = quoteBindingHash(route, context2.quote, rawQuoteSha256, orderNonce, swapperAddress, destinationAddress);
6867
+ let sourceSwap;
6868
+ if (sourceIsUsdc(route)) {
6869
+ sourceSwap = { kind: "none" };
6870
+ } else {
6871
+ const endpoint = endpointUrl(runtime.localBuild?.sourceSwapEndpoint);
6872
+ const sourceChain = route.sourceChainId === ETHEREUM_CHAIN_ID ? "evm" : "solana";
6873
+ let url;
6874
+ if (sourceChain === "evm") {
6875
+ url = sourceSwapUrl(endpoint, sourceChain, [
6876
+ ["forwarderAddress", ETHEREUM_FORWARDER_PROVIDER],
6877
+ ["slippageBps", context2.quote.slippageBps],
6878
+ ["fromToken", String(rawQuote.raw.fromToken.contract)],
6879
+ ["middleToken", route.sourceUsdcAddress],
6880
+ ["chainName", route.sourceProviderChainName],
6881
+ ["amountIn64", context2.quote.amountIn],
6882
+ ["sdkVersion", MAYAN_ORACLE_SDK_VERSION]
6883
+ ]);
6884
+ } else {
6885
+ const state = findProgramAddress([
6886
+ new TextEncoder().encode("STATE_SOURCE"),
6887
+ hexToBytes(orderHash),
6888
+ writeUint16Le(2)
6889
+ ], SOLANA_SWIFT_PROGRAM);
6890
+ const sourceMinimum = extractRawNumberLexeme(context2.quote.rawSignedQuoteJson, "minMiddleAmount");
6891
+ url = sourceSwapUrl(endpoint, sourceChain, [
6892
+ ["minMiddleAmount", Number(sourceMinimum)],
6893
+ ["middleToken", route.sourceUsdcAddress],
6894
+ ["userWallet", swapperAddress],
6895
+ ["slippageBps", context2.quote.slippageBps],
6896
+ ["fromToken", route.sourceTokenAddress],
6897
+ ["amountIn64", context2.quote.amountIn],
6898
+ ["depositMode", "SWIFT"],
6899
+ ["fillMaxAccounts", false],
6900
+ ["chainName", route.sourceProviderChainName],
6901
+ ["userLedger", state.address],
6902
+ ["sdkVersion", MAYAN_ORACLE_SDK_VERSION]
6903
+ ]);
6904
+ }
6905
+ try {
6906
+ const response = await fetchSourceSwap(runtime, url, options);
6907
+ const state = route.sourceChainId === SOLANA_CHAIN_ID ? findProgramAddress([new TextEncoder().encode("STATE_SOURCE"), hexToBytes(orderHash), writeUint16Le(2)], SOLANA_SWIFT_PROGRAM).address : "";
6908
+ const stateTokenAccount = route.sourceChainId === SOLANA_CHAIN_ID ? associatedTokenAddress(state, route.sourceUsdcAddress, true) : "";
6909
+ sourceSwap = validateSourceSwapEnvelope(context2.quote, route, response.root, state, stateTokenAccount, swapperAddress, rawQuote.minimumIntermediateAmount);
6910
+ if (sourceSwap.kind === "none") throw new Error("source swap");
6911
+ sourceSwap = {
6912
+ ...sourceSwap,
6913
+ rawResponseSha256: sha256Hex(response.text),
6914
+ rawProviderSourceSwapJson: response.text
6915
+ };
6916
+ } catch (error) {
6917
+ if (error instanceof Error && error.name === "BridgeError") throw error;
6918
+ runtime.fail("BRIDGE_LOCAL_PLAN_INVALID");
6919
+ }
6920
+ }
6921
+ const plan = {
6922
+ planKind: "mayan-swift-v2-local-source-swap",
6923
+ providerId: "mayan-swift-v2",
6924
+ capabilityId: route.bridgeCapabilityId,
6925
+ sourceChainId: route.sourceChainId,
6926
+ destinationChainId: route.destinationChainId,
6927
+ sourceTokenDeploymentId: route.sourceTokenDeploymentId,
6928
+ destinationTokenDeploymentId: route.destinationTokenDeploymentId,
6929
+ quoteId: context2.quote.quoteId,
6930
+ rawQuoteSha256,
6931
+ orderNonce,
6932
+ swapperAddress,
6933
+ destinationAddress,
6934
+ orderHash,
6935
+ quoteBindingHash: binding,
6936
+ minimumIntermediateAmount: rawQuote.minimumIntermediateAmount,
6937
+ sourceSwap,
6938
+ planHash: planHash(binding, sourceSwap)
6939
+ };
6940
+ return plan;
6941
+ })();
6942
+ };
6943
+ var sourceRpcError = (runtime, error) => {
6944
+ if (error instanceof Error && error.name === "BridgeError") throw error;
6945
+ if (error instanceof ErpcInvalidResponseError || error instanceof ErpcJsonRpcError) {
6946
+ return runtime.fail("BRIDGE_SOURCE_RPC_INVALID_RESPONSE");
6947
+ }
6948
+ if (error instanceof ErpcAbortedError) return runtime.fail("BRIDGE_ABORTED");
6949
+ if (error instanceof ErpcTimeoutError) return runtime.fail("BRIDGE_TIMEOUT");
6950
+ if (error instanceof ErpcHttpError || error instanceof ErpcTransportError) {
6951
+ return runtime.fail("BRIDGE_SOURCE_RPC_TRANSPORT");
6952
+ }
6953
+ if (error instanceof ErpcConfigError) return runtime.fail("BRIDGE_LOCAL_BUILD_INVALID");
6954
+ return runtime.fail("BRIDGE_SOURCE_RPC_INVALID_RESPONSE");
6955
+ };
6956
+ var directRpc = (endpoint, runtime, code, chain) => {
6957
+ if (endpoint === void 0 || endpoint === null) runtime.fail(code);
6958
+ if (endpoint === null || typeof endpoint !== "object" || Array.isArray(endpoint)) runtime.fail("BRIDGE_LOCAL_BUILD_INVALID");
6959
+ const rpcFetch = async (input, init) => {
6960
+ const requestBody = init?.body;
6961
+ if (typeof requestBody !== "string") return runtime.fetch(input, init);
6962
+ let request;
6963
+ try {
6964
+ const parsed2 = JSON.parse(requestBody);
6965
+ if (parsed2 === null || typeof parsed2 !== "object" || Array.isArray(parsed2)) return runtime.fetch(input, init);
6966
+ request = parsed2;
6967
+ } catch {
6968
+ return runtime.fetch(input, init);
6969
+ }
6970
+ const requestId = request.id;
6971
+ request.id = 1;
6972
+ const response = await runtime.fetch(input, { ...init, body: JSON.stringify(request) });
6973
+ let responseBody;
6974
+ try {
6975
+ const signal = init?.signal ?? new AbortController().signal;
6976
+ responseBody = await readSourceResponseText(response, signal);
6977
+ } catch (error) {
6978
+ if (error instanceof SourceResponseInvalidError) {
6979
+ return new Response("null", {
6980
+ status: response.status,
6981
+ statusText: response.statusText,
6982
+ headers: response.headers
6983
+ });
6984
+ }
6985
+ throw error;
6986
+ }
6987
+ if (!response.ok) {
6988
+ return new Response(responseBody, {
6989
+ status: response.status,
6990
+ statusText: response.statusText,
6991
+ headers: response.headers
6992
+ });
6993
+ }
6994
+ let parsed;
6995
+ try {
6996
+ parsed = parseJsonObject(responseBody);
6997
+ } catch {
6998
+ return new Response("null", {
6999
+ status: response.status,
7000
+ statusText: response.statusText,
7001
+ headers: response.headers
7002
+ });
7003
+ }
7004
+ if (parsed.jsonrpc !== "2.0" || typeof parsed.id !== "number" || !Number.isSafeInteger(parsed.id) || parsed.id !== 1) {
7005
+ return new Response("null", {
7006
+ status: response.status,
7007
+ statusText: response.statusText,
7008
+ headers: response.headers
7009
+ });
7010
+ }
7011
+ parsed.id = requestId;
7012
+ responseBody = JSON.stringify(parsed);
7013
+ return new Response(responseBody, {
7014
+ status: response.status,
7015
+ statusText: response.statusText,
7016
+ headers: response.headers
7017
+ });
7018
+ };
7019
+ return createErpcClient({
7020
+ ...chain === "ethereum" ? { ethereumRpc: endpoint } : { solanaRpc: endpoint },
7021
+ fetch: rpcFetch,
7022
+ timeoutMs: runtime.timeoutMs
7023
+ });
7024
+ };
7025
+ var parseRpcAccount = (value) => {
7026
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("account");
7027
+ const account = value;
7028
+ if (!Array.isArray(account.data) || account.data.length !== 2 || typeof account.data[0] !== "string" || account.data[1] !== "base64" || typeof account.owner !== "string" || account.executable !== false) throw new Error("account");
7029
+ const data = base64Decode(account.data[0], 16384);
7030
+ return { data, owner: canonicalSolanaAddress(account.owner) };
7031
+ };
7032
+ var decodeLookupTable = (address, account, accountContextSlot) => {
7033
+ if (account.owner !== SOLANA_ADDRESS_LOOKUP_TABLE_OWNER || account.data.length < 56 || (account.data.length - 56) % 32 !== 0) throw new Error("ALT");
7034
+ const view = new DataView(account.data.buffer, account.data.byteOffset, account.data.byteLength);
7035
+ if (view.getUint32(0, true) !== 1) throw new Error("ALT");
7036
+ const deactivationSlot = view.getBigUint64(4, true);
7037
+ if (deactivationSlot !== UINT64_MAX) throw new Error("ALT");
7038
+ const lastExtendedSlot = view.getBigUint64(12, true);
7039
+ if (lastExtendedSlot > BigInt(accountContextSlot)) throw new Error("ALT");
7040
+ const lastExtendedStartIndex = account.data[20];
7041
+ const authorityOption = account.data[21];
7042
+ if (lastExtendedStartIndex === void 0 || authorityOption === void 0 || authorityOption !== 0 && authorityOption !== 1) throw new Error("ALT");
7043
+ for (let index = 54; index < 56; index += 1) {
7044
+ if (account.data[index] !== 0) throw new Error("ALT");
7045
+ }
7046
+ if (authorityOption === 0) {
7047
+ for (let index = 22; index < 54; index += 1) {
7048
+ if (account.data[index] !== 0) throw new Error("ALT");
7049
+ }
7050
+ }
7051
+ const addresses = [];
7052
+ for (let offset = 56; offset < account.data.length; offset += 32) addresses.push(base58Encode(account.data.slice(offset, offset + 32)));
7053
+ if (addresses.length > MAX_LOOKUP_TABLE_ADDRESSES || lastExtendedStartIndex > addresses.length) throw new Error("ALT");
7054
+ const activeCount = lastExtendedSlot === BigInt(accountContextSlot) ? lastExtendedStartIndex : addresses.length;
7055
+ return { address, addresses: addresses.slice(0, activeCount) };
7056
+ };
7057
+ var fetchSourceRpc = async (route, plan, runtime, options) => {
7058
+ const endpoint = route.sourceChainId === ETHEREUM_CHAIN_ID ? runtime.localBuild?.ethereumRpc : runtime.localBuild?.solanaRpc;
7059
+ let erpc;
7060
+ try {
7061
+ erpc = directRpc(endpoint, runtime, "BRIDGE_LOCAL_RPC_REQUIRED", route.sourceChainId === ETHEREUM_CHAIN_ID ? "ethereum" : "solana");
7062
+ } catch (error) {
7063
+ return sourceRpcError(runtime, error);
7064
+ }
7065
+ const rpcOptions = options?.signal === void 0 ? void 0 : { signal: options.signal };
7066
+ try {
7067
+ if (route.sourceChainId === ETHEREUM_CHAIN_ID) {
7068
+ const rpcChainId = await erpc.ethereum.rpc.eth_chainId().send(rpcOptions);
7069
+ if (rpcChainId.toLowerCase() !== "0x1") throw new Error("chain");
7070
+ const codeAddresses = [ETHEREUM_FORWARDER, route.swiftContract];
7071
+ if (plan.sourceSwap.kind === "evm-router") codeAddresses.push(plan.sourceSwap.routerAddress);
7072
+ const code = [];
7073
+ for (const address of codeAddresses) {
7074
+ const bytecode = await erpc.ethereum.rpc.eth_getCode(address, "latest").send(rpcOptions);
7075
+ if (typeof bytecode !== "string" || !HEX_BYTES2.test(bytecode) || bytecode === "0x") throw new Error("code");
7076
+ code.push({ address: normalizeEvmAddress3(address), keccak256: `0x${keccakHex(hexToBytes(bytecode))}` });
7077
+ }
7078
+ return {
7079
+ erpc,
7080
+ evidence: { kind: "evm", rpcChainId: "0x1", code },
7081
+ lookupTables: [],
7082
+ recentBlockhash: null
7083
+ };
7084
+ }
7085
+ const genesisHash = await erpc.solana.rpc.getGenesisHash().send(rpcOptions);
7086
+ if (genesisHash !== SOLANA_MAINNET_GENESIS_HASH) throw new Error("genesis");
7087
+ const blockhashResult = await erpc.solana.rpc.getLatestBlockhash({ commitment: "confirmed" }).send(rpcOptions);
7088
+ if (blockhashResult === null || typeof blockhashResult !== "object" || Array.isArray(blockhashResult)) throw new Error("blockhash");
7089
+ const blockhashWrapper = blockhashResult;
7090
+ const blockhashContext = blockhashWrapper.context;
7091
+ const blockhashValue = blockhashWrapper.value;
7092
+ if (blockhashContext === null || typeof blockhashContext !== "object" || Array.isArray(blockhashContext) || blockhashValue === null || typeof blockhashValue !== "object" || Array.isArray(blockhashValue)) throw new Error("blockhash");
7093
+ const blockhashSlot = blockhashContext.slot;
7094
+ const recentBlockhash = blockhashValue.blockhash;
7095
+ const lastValidBlockHeight = blockhashValue.lastValidBlockHeight;
7096
+ if (typeof blockhashSlot !== "number" || !Number.isSafeInteger(blockhashSlot) || blockhashSlot < 0 || typeof recentBlockhash !== "string" || typeof lastValidBlockHeight !== "number" || !Number.isSafeInteger(lastValidBlockHeight) || lastValidBlockHeight < 0 || !canonicalSolanaAddress(recentBlockhash)) throw new Error("blockhash");
7097
+ const providerAlts = plan.sourceSwap.kind === "solana-jupiter-v6" ? plan.sourceSwap.addressLookupTableAddresses : [];
7098
+ const altAddresses = [.../* @__PURE__ */ new Set([SOLANA_MAYAN_LOOKUP_TABLE, ...providerAlts])];
7099
+ if (altAddresses.length > MAX_LOOKUP_TABLES) throw new Error("ALT");
7100
+ const accountsResult = await erpc.solana.rpc.getMultipleAccounts(
7101
+ altAddresses,
7102
+ { encoding: "base64", commitment: "confirmed", minContextSlot: blockhashSlot }
7103
+ ).send(rpcOptions);
7104
+ if (accountsResult === null || typeof accountsResult !== "object" || Array.isArray(accountsResult)) throw new Error("accounts");
7105
+ const accountsWrapper = accountsResult;
7106
+ const accountContext = accountsWrapper.context;
7107
+ const accountValues = accountsWrapper.value;
7108
+ if (accountContext === null || typeof accountContext !== "object" || Array.isArray(accountContext) || !Array.isArray(accountValues)) throw new Error("accounts");
7109
+ const accountSlot = accountContext.slot;
7110
+ if (typeof accountSlot !== "number" || !Number.isSafeInteger(accountSlot) || accountSlot < 0 || typeof blockhashSlot !== "number" || accountSlot < blockhashSlot || accountValues.length !== altAddresses.length) throw new Error("accounts");
7111
+ const lookupTables = altAddresses.map((address, index) => decodeLookupTable(address, parseRpcAccount(accountValues[index]), accountSlot));
7112
+ return {
7113
+ erpc,
7114
+ evidence: {
7115
+ kind: "solana",
7116
+ genesisHash,
7117
+ blockhashContextSlot: String(blockhashSlot),
7118
+ accountContextSlot: String(accountSlot),
7119
+ recentBlockhash,
7120
+ lastValidBlockHeight: String(lastValidBlockHeight),
7121
+ lookupTables: lookupTables.map((table) => ({ address: table.address, dataSha256: sha256Hex(parseRpcAccount(accountValues[altAddresses.indexOf(table.address)]).data) }))
7122
+ },
7123
+ lookupTables,
7124
+ recentBlockhash
7125
+ };
7126
+ } catch (error) {
7127
+ erpc.close();
7128
+ return sourceRpcError(runtime, error);
7129
+ }
7130
+ };
7131
+ var exactKeys = (value, expected) => {
7132
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
7133
+ const actual = Object.keys(value).sort();
7134
+ const wanted = [...expected].sort();
7135
+ return actual.length === wanted.length && actual.every((key, index) => key === wanted[index]);
7136
+ };
7137
+ var validatePlan = (request, route, rawQuote, plan, rawQuoteSha256, orderHash, binding, swapperAddress, destinationAddress) => {
7138
+ if (!exactKeys(plan, [
7139
+ "planKind",
7140
+ "providerId",
7141
+ "capabilityId",
7142
+ "sourceChainId",
7143
+ "destinationChainId",
7144
+ "sourceTokenDeploymentId",
7145
+ "destinationTokenDeploymentId",
7146
+ "quoteId",
7147
+ "rawQuoteSha256",
7148
+ "orderNonce",
7149
+ "swapperAddress",
7150
+ "destinationAddress",
7151
+ "orderHash",
7152
+ "quoteBindingHash",
7153
+ "minimumIntermediateAmount",
7154
+ "sourceSwap",
7155
+ "planHash"
7156
+ ])) throw new Error("plan");
7157
+ if (plan.planKind !== "mayan-swift-v2-local-source-swap" || plan.providerId !== "mayan-swift-v2" || plan.capabilityId !== route.bridgeCapabilityId || plan.sourceChainId !== route.sourceChainId || plan.destinationChainId !== route.destinationChainId || plan.sourceTokenDeploymentId !== route.sourceTokenDeploymentId || plan.destinationTokenDeploymentId !== route.destinationTokenDeploymentId || plan.quoteId !== request.quote.quoteId || plan.rawQuoteSha256 !== rawQuoteSha256 || plan.orderNonce !== request.orderNonce || plan.swapperAddress !== swapperAddress || plan.destinationAddress !== destinationAddress || plan.orderHash !== orderHash || plan.quoteBindingHash !== binding || plan.minimumIntermediateAmount !== rawQuote.minimumIntermediateAmount) throw new Error("plan");
7158
+ let normalizedSwap;
7159
+ if (sourceIsUsdc(route)) {
7160
+ if (!exactKeys(plan.sourceSwap, ["kind"]) || plan.sourceSwap.kind !== "none") throw new Error("plan");
7161
+ normalizedSwap = { kind: "none" };
7162
+ } else {
7163
+ const state = route.sourceChainId === SOLANA_CHAIN_ID ? findProgramAddress([new TextEncoder().encode("STATE_SOURCE"), hexToBytes(orderHash), writeUint16Le(2)], SOLANA_SWIFT_PROGRAM).address : "";
7164
+ const stateTokenAccount = route.sourceChainId === SOLANA_CHAIN_ID ? associatedTokenAddress(state, route.sourceUsdcAddress, true) : "";
7165
+ if (plan.sourceSwap.kind === "none") throw new Error("plan");
7166
+ const sourceRaw = parseJsonObject(plan.sourceSwap.rawProviderSourceSwapJson);
7167
+ if (plan.sourceSwap.rawResponseSha256 !== sha256Hex(plan.sourceSwap.rawProviderSourceSwapJson)) throw new Error("plan");
7168
+ const expected = validateSourceSwapEnvelope(request.quote, route, sourceRaw, state, stateTokenAccount, swapperAddress, rawQuote.minimumIntermediateAmount);
7169
+ if (stableJson(expected) !== stableJson({ ...plan.sourceSwap, rawResponseSha256: "", rawProviderSourceSwapJson: "" })) throw new Error("plan");
7170
+ normalizedSwap = plan.sourceSwap;
7171
+ }
7172
+ if (plan.planHash !== planHash(binding, normalizedSwap)) throw new Error("plan");
7173
+ return plan;
7174
+ };
7175
+ var localBuildDependencies = (route) => [
7176
+ ...route.dependencies.filter((dependency) => dependency !== "mayan-hosted-transaction-builder"),
7177
+ route.sourceChainId === ETHEREUM_CHAIN_ID ? "configured-ethereum-rpc" : "configured-solana-rpc"
7178
+ ];
7179
+ var buildEvmOrderCall = (quote, route, plan, swapperAddress, destinationAddress, minimumIntermediateAmount, cancelFee, refundFee, mode, orderNonce) => {
7180
+ const orderWords = [
7181
+ wordUint(1n),
7182
+ wordBytes32(nativeAddressBytes(swapperAddress, route.sourceChainId)),
7183
+ wordBytes32(nativeAddressBytes(destinationAddress, route.destinationChainId)),
7184
+ wordUint(BigInt(route.destinationWormholeChainId)),
7185
+ wordBytes32(zero32()),
7186
+ wordBytes32(nativeAddressBytes(route.destinationTokenAddress, route.destinationChainId)),
7187
+ wordUint(uint64(quote.minimumAmountOut, true)),
7188
+ wordUint(0n),
7189
+ wordUint(cancelFee),
7190
+ wordUint(refundFee),
7191
+ wordUint(uint64(quote.deadline, true)),
7192
+ wordUint(0n),
7193
+ wordUint(BigInt(mode)),
7194
+ wordBytes32(swiftRandom(quote.quoteId, orderNonce))
7195
+ ];
7196
+ const swiftCallData = `0xa3a30834${bytesToHex(encodeAbiWithDynamics([
7197
+ wordAddress(route.sourceUsdcAddress),
7198
+ wordUint(uint64(quote.amountIn, true)),
7199
+ ...orderWords
7200
+ ], [new Uint8Array()]))}`;
7201
+ if (plan.sourceSwap.kind === "none") {
7202
+ return `0xe4269fc4${bytesToHex(encodeAbiWithDynamics([
7203
+ wordAddress(route.sourceUsdcAddress),
7204
+ wordUint(uint64(quote.amountIn, true)),
7205
+ ...[wordUint(0n), wordUint(0n), wordUint(0n), wordBytes32(zero32()), wordBytes32(zero32())],
7206
+ wordAddress(route.swiftContract)
7207
+ ], [hexToBytes(swiftCallData)]))}`;
7208
+ }
7209
+ if (plan.sourceSwap.kind !== "evm-router") throw new Error("plan");
7210
+ const routerData = hexToBytes(plan.sourceSwap.calldata);
7211
+ const routerOffset = 13 * 32;
7212
+ const swiftOffset = routerOffset + 32 + Math.ceil(routerData.length / 32) * 32;
7213
+ const head = [
7214
+ wordAddress(route.sourceTokenAddress),
7215
+ wordUint(uint64(quote.amountIn, true)),
7216
+ wordUint(0n),
7217
+ wordUint(0n),
7218
+ wordUint(0n),
7219
+ wordBytes32(zero32()),
7220
+ wordBytes32(zero32()),
7221
+ wordAddress(plan.sourceSwap.routerAddress),
7222
+ wordUint(BigInt(routerOffset)),
7223
+ wordAddress(route.sourceUsdcAddress),
7224
+ wordUint(uint64(minimumIntermediateAmount, true)),
7225
+ wordAddress(route.swiftContract),
7226
+ wordUint(BigInt(swiftOffset))
7227
+ ];
7228
+ return `0x30dedc57${bytesToHex(concatBytes(
7229
+ ...head,
7230
+ encodeAbiBytes(routerData),
7231
+ encodeAbiBytes(hexToBytes(swiftCallData))
7232
+ ))}`;
7233
+ };
7234
+ var buildSolanaInstructions = (quote, route, plan, swapperAddress, destinationAddress, minimumIntermediateAmount, cancelFee, refundFee, submitFee, mode, orderNonce, raw) => {
7235
+ const state = findProgramAddress([
7236
+ new TextEncoder().encode("STATE_SOURCE"),
7237
+ hexToBytes(hashOrder(quote, route, swapperAddress, destinationAddress, orderNonce, minimumIntermediateAmount, cancelFee, refundFee, mode)),
7238
+ writeUint16Le(2)
7239
+ ], SOLANA_SWIFT_PROGRAM).address;
7240
+ const stateTokenAccount = associatedTokenAddress(state, route.sourceUsdcAddress, true);
7241
+ const init = makeSwiftInitInstruction(
7242
+ quote,
7243
+ route,
7244
+ swapperAddress,
7245
+ destinationAddress,
7246
+ state,
7247
+ stateTokenAccount,
7248
+ minimumIntermediateAmount,
7249
+ cancelFee,
7250
+ refundFee,
7251
+ submitFee,
7252
+ mode,
7253
+ orderNonce
7254
+ );
7255
+ if (sourceIsUsdc(route)) {
7256
+ const instructions = [];
7257
+ const suggestedPriorityFee = raw.suggestedPriorityFee;
7258
+ if (typeof suggestedPriorityFee === "number" && Number.isSafeInteger(suggestedPriorityFee) && suggestedPriorityFee > 0) {
7259
+ if (suggestedPriorityFee > 1e5) throw new Error("compute");
7260
+ instructions.push(makeComputeUnitPriceInstruction(BigInt(suggestedPriorityFee)));
7261
+ }
7262
+ instructions.push(wrapInCpiProxy(makeAtaInstruction(swapperAddress, state, route.sourceUsdcAddress, true)));
7263
+ instructions.push(wrapInCpiProxy(makeSplTransferInstruction(
7264
+ associatedTokenAddress(swapperAddress, route.sourceUsdcAddress, false),
7265
+ stateTokenAccount,
7266
+ swapperAddress,
7267
+ uint64(quote.amountIn, true)
7268
+ )));
7269
+ instructions.push(wrapInCpiProxy(init));
7270
+ return instructions;
7271
+ }
7272
+ if (plan.sourceSwap.kind !== "solana-jupiter-v6") throw new Error("plan");
7273
+ const computeCount = plan.sourceSwap.instructions.filter((instruction) => instruction.programId === SOLANA_COMPUTE_BUDGET_PROGRAM).length;
7274
+ const compute = plan.sourceSwap.instructions.slice(0, computeCount);
7275
+ const remainder = plan.sourceSwap.instructions.slice(computeCount);
7276
+ const swapIndex = remainder.findIndex((instruction) => instruction.programId === SOLANA_JUPITER_V6);
7277
+ if (swapIndex < 1) throw new Error("source swap");
7278
+ const setup = remainder.slice(0, swapIndex);
7279
+ const swap = remainder[swapIndex];
7280
+ if (!swap || remainder.slice(swapIndex + 1).length !== 0) throw new Error("source swap");
7281
+ return [
7282
+ ...compute,
7283
+ ...setup.map(wrapInCpiProxy),
7284
+ swap,
7285
+ wrapInCpiProxy(init)
7286
+ ];
7287
+ };
7288
+ var buildLocalPlan = (context, runtime, options) => {
7289
+ const snapshot = cloneJson(context);
7290
+ return (async () => {
7291
+ const context2 = {
7292
+ ...snapshot,
7293
+ quote: runtime.validateQuote(snapshot.quote, "BRIDGE_LOCAL_BUILD_INVALID")
7294
+ };
7295
+ let route;
7296
+ let rawQuote;
7297
+ let swapperAddress;
7298
+ let destinationAddress;
7299
+ try {
7300
+ if (context2 === null || typeof context2 !== "object" || Array.isArray(context2)) throw new Error("context");
7301
+ const keys = Object.keys(context2).sort().join(",");
7302
+ if (keys !== "destinationAddress,orderNonce,quote,sourceSwapPlan,swapperAddress") throw new Error("context");
7303
+ route = validateLocalRoute(context2.quote);
7304
+ rawQuote = parseSourceQuote(context2.quote, route);
7305
+ swapperAddress = route.sourceChainId === ETHEREUM_CHAIN_ID ? normalizeEvmAddress3(context2.swapperAddress) : canonicalSolanaAddress(context2.swapperAddress);
7306
+ destinationAddress = route.destinationChainId === ETHEREUM_CHAIN_ID ? normalizeEvmAddress3(context2.destinationAddress) : canonicalSolanaAddress(context2.destinationAddress);
7307
+ if (typeof context2.orderNonce !== "string" || !NONCE.test(context2.orderNonce)) throw new Error("nonce");
7308
+ validateDestinationMinimumCompatibility(context2.quote.rawSignedQuoteJson, context2.quote.minimumAmountOut);
7309
+ if (Math.floor(Date.now() / 1e3) + runtime.minimumQuoteValiditySeconds > Number(uint64(context2.quote.deadline, true))) runtime.fail("BRIDGE_QUOTE_EXPIRED");
7310
+ } catch (error) {
7311
+ if (error instanceof Error && error.name === "BridgeError") throw error;
7312
+ runtime.fail("BRIDGE_LOCAL_BUILD_INVALID");
7313
+ }
7314
+ const rawQuoteSha256 = sha256Hex(context2.quote.rawSignedQuoteJson);
7315
+ const orderHash = hashOrder(context2.quote, route, swapperAddress, destinationAddress, context2.orderNonce, rawQuote.minimumIntermediateAmount, rawQuote.cancelFee, rawQuote.refundFee, rawQuote.mode);
7316
+ const binding = quoteBindingHash(route, context2.quote, rawQuoteSha256, context2.orderNonce, swapperAddress, destinationAddress);
7317
+ try {
7318
+ const plan = validatePlan(context2, route, rawQuote, context2.sourceSwapPlan, rawQuoteSha256, orderHash, binding, swapperAddress, destinationAddress);
7319
+ const rpc = await fetchSourceRpc(route, plan, runtime, options);
7320
+ try {
7321
+ let transaction;
7322
+ if (route.sourceChainId === ETHEREUM_CHAIN_ID) {
7323
+ const data = buildEvmOrderCall(context2.quote, route, plan, swapperAddress, destinationAddress, rawQuote.minimumIntermediateAmount, rawQuote.cancelFee, rawQuote.refundFee, rawQuote.mode, context2.orderNonce);
7324
+ transaction = {
7325
+ kind: "evm-unsigned-transaction",
7326
+ chainId: ETHEREUM_CHAIN_ID,
7327
+ from: swapperAddress,
7328
+ to: ETHEREUM_FORWARDER,
7329
+ data,
7330
+ value: "0"
7331
+ };
7332
+ } else {
7333
+ const instructions = buildSolanaInstructions(context2.quote, route, plan, swapperAddress, destinationAddress, rawQuote.minimumIntermediateAmount, rawQuote.cancelFee, rawQuote.refundFee, rawQuote.submitFee, rawQuote.mode, context2.orderNonce, rawQuote.raw);
7334
+ if (rpc.recentBlockhash === null) throw new Error("blockhash");
7335
+ const compiled = compileSolanaV0(swapperAddress, rpc.recentBlockhash, instructions, rpc.lookupTables);
7336
+ transaction = {
7337
+ kind: "solana-v0-unsigned-transaction",
7338
+ chainId: SOLANA_CHAIN_ID,
7339
+ feePayer: swapperAddress,
7340
+ transactionBase64: compiled.transactionBase64
7341
+ };
7342
+ }
7343
+ const allowance = route.sourceChainId === ETHEREUM_CHAIN_ID ? {
7344
+ tokenDeploymentId: route.sourceTokenDeploymentId,
7345
+ tokenAddress: route.sourceTokenAddress,
7346
+ owner: swapperAddress,
7347
+ spender: ETHEREUM_FORWARDER,
7348
+ requiredAmount: context2.quote.amountIn
7349
+ } : null;
7350
+ return {
7351
+ buildKind: "mayan-swift-v2-local-unsigned",
7352
+ providerId: "mayan-swift-v2",
7353
+ capabilityId: route.bridgeCapabilityId,
7354
+ quote: cloneJson(context2.quote),
7355
+ sourceChainId: route.sourceChainId,
7356
+ destinationChainId: route.destinationChainId,
7357
+ sourceSwapPlan: cloneJson(plan),
7358
+ transaction,
7359
+ allowance,
7360
+ construction: {
7361
+ mode: "local",
7362
+ referenceCommit: MAYAN_REFERENCE_COMMIT,
7363
+ orderNonce: context2.orderNonce,
7364
+ orderHash,
7365
+ minimumIntermediateAmount: rawQuote.minimumIntermediateAmount,
7366
+ effectiveDependencies: localBuildDependencies(route),
7367
+ sourceRpcEvidence: rpc.evidence
7368
+ },
7369
+ validation: {
7370
+ level: "local-structural",
7371
+ quoteSignatureLocallyVerified: false,
7372
+ planBindingLocallyVerified: true,
7373
+ transactionBytesLocallyConstructed: true,
7374
+ settlementLocallyVerified: false
7375
+ }
7376
+ };
7377
+ } finally {
7378
+ rpc.erpc.close();
7379
+ }
7380
+ } catch (error) {
7381
+ if (error instanceof Error && error.name === "BridgeError") throw error;
7382
+ runtime.fail("BRIDGE_LOCAL_BUILD_INVALID");
7383
+ }
7384
+ })();
7385
+ };
7386
+ var prepareSourceSwap = (context, runtime, options) => preparePlan(context, runtime, options);
7387
+ var buildLocalUnsigned = (request, runtime, options) => buildLocalPlan(request, runtime, options);
5768
7388
 
5769
7389
  // src/bridge.ts
5770
7390
  var BRIDGE_ERROR_MESSAGES = Object.freeze({
@@ -5778,6 +7398,11 @@ var BRIDGE_ERROR_MESSAGES = Object.freeze({
5778
7398
  BRIDGE_QUOTE_EXPIRED: "Bridge quote is expired",
5779
7399
  BRIDGE_QUOTE_MISMATCH: "Bridge quote does not match the request",
5780
7400
  BRIDGE_BUILD_INVALID: "Bridge provider build is invalid",
7401
+ BRIDGE_LOCAL_RPC_REQUIRED: "Bridge local source RPC is required",
7402
+ BRIDGE_SOURCE_RPC_TRANSPORT: "Bridge source RPC transport failed",
7403
+ BRIDGE_SOURCE_RPC_INVALID_RESPONSE: "Bridge source RPC response is invalid",
7404
+ BRIDGE_LOCAL_PLAN_INVALID: "Bridge local source-swap plan is invalid",
7405
+ BRIDGE_LOCAL_BUILD_INVALID: "Bridge local unsigned build is invalid",
5781
7406
  BRIDGE_STATUS_NOT_FOUND: "Bridge status was not found",
5782
7407
  BRIDGE_TIMEOUT: "Bridge provider request timed out",
5783
7408
  BRIDGE_ABORTED: "Bridge provider request was aborted"
@@ -5792,8 +7417,8 @@ var BridgeError = class extends Error {
5792
7417
  if (status !== void 0) this.status = status;
5793
7418
  }
5794
7419
  };
5795
- var ETHEREUM_CHAIN_ID = TOKEN_CHAIN_IDS.ethereumMainnet;
5796
- var SOLANA_CHAIN_ID = TOKEN_CHAIN_IDS.solanaMainnet;
7420
+ var ETHEREUM_CHAIN_ID2 = TOKEN_CHAIN_IDS.ethereumMainnet;
7421
+ var SOLANA_CHAIN_ID2 = TOKEN_CHAIN_IDS.solanaMainnet;
5797
7422
  var ETHEREUM_NAME = "ethereum";
5798
7423
  var SOLANA_NAME = "solana";
5799
7424
  var ETHEREUM_PROVIDER_CHAIN_ID = 1;
@@ -5809,26 +7434,28 @@ var SOLANA_EURC_ADDRESS = "HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr";
5809
7434
  var ETHEREUM_USDC_ADDRESS = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
5810
7435
  var SOLANA_USDC_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
5811
7436
  var ETHEREUM_SWIFT_CONTRACT = "0x40ffe85a28dc9993541449464d7529a922142960";
5812
- var SOLANA_SWIFT_PROGRAM = "mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny";
5813
- var ETHEREUM_FORWARDER = "0x337685fdab40d39bd02028545a4ffa7d287cc3e2";
5814
- var SOLANA_JUPITER_V6 = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
5815
- var ETHEREUM_FORWARDER_SELECTOR = "0x30dedc57";
7437
+ var SOLANA_SWIFT_PROGRAM2 = "mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny";
7438
+ var ETHEREUM_FORWARDER2 = "0x337685fdab40d39bd02028545a4ffa7d287cc3e2";
7439
+ var SOLANA_JUPITER_V62 = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
7440
+ var ETHEREUM_EURC_FORWARDER_SELECTOR = "0x30dedc57";
7441
+ var ETHEREUM_USDC_FORWARDER_SELECTOR = "0xe4269fc4";
7442
+ var MAYAN_USDC_MINT = "A9mUU4qviSctJVPJdBJWkb28deg915LYJKrzQ19ji3FM";
5816
7443
  var DEFAULT_BUILDER_ENDPOINT = "https://tx-builder.mayan.finance";
5817
7444
  var DEFAULT_EXPLORER_ENDPOINT = "https://explorer-api.mayan.finance/v3";
5818
7445
  var DEFAULT_TIMEOUT_MS2 = 3e4;
5819
- var MAX_RESPONSE_BYTES = 1024 * 1024;
7446
+ var MAX_RESPONSE_BYTES2 = 1024 * 1024;
5820
7447
  var MAX_RAW_QUOTE_BYTES = 256 * 1024;
5821
- var MAX_JSON_DEPTH = 32;
7448
+ var MAX_JSON_DEPTH2 = 32;
5822
7449
  var MAX_QUOTES = 16;
5823
- var UINT64_MAX = (1n << 64n) - 1n;
7450
+ var UINT64_MAX2 = (1n << 64n) - 1n;
5824
7451
  var CANONICAL_UINT64 = /^(0|[1-9][0-9]*)$/u;
5825
7452
  var POSITIVE_UINT64 = /^[1-9][0-9]*$/u;
5826
- var EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/u;
7453
+ var EVM_ADDRESS3 = /^0x[0-9a-fA-F]{40}$/u;
5827
7454
  var EVM_HASH = /^0x[0-9a-fA-F]{64}$/u;
5828
7455
  var EVM_SIGNATURE = /^0x[0-9a-fA-F]{130}$/u;
5829
- var HEX_BYTES2 = /^0x[0-9a-fA-F]*$/u;
7456
+ var HEX_BYTES3 = /^0x[0-9a-fA-F]*$/u;
5830
7457
  var BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
5831
- var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
7458
+ var BASE58_ALPHABET2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
5832
7459
  var DEPENDENCIES = Object.freeze([
5833
7460
  "mayan-hosted-quote-api",
5834
7461
  "mayan-hosted-transaction-builder",
@@ -5838,6 +7465,14 @@ var DEPENDENCIES = Object.freeze([
5838
7465
  "wormhole-guardian-messaging",
5839
7466
  "mayan-explorer-indexer"
5840
7467
  ]);
7468
+ var DIRECT_USDC_DEPENDENCIES = Object.freeze([
7469
+ "mayan-hosted-quote-api",
7470
+ "mayan-hosted-transaction-builder",
7471
+ "swift-auction-solvers",
7472
+ "relayers",
7473
+ "wormhole-guardian-messaging",
7474
+ "mayan-explorer-indexer"
7475
+ ]);
5841
7476
  var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5842
7477
  var deepFreeze6 = (value) => {
5843
7478
  if (value && typeof value === "object" && !Object.isFrozen(value)) {
@@ -5861,9 +7496,9 @@ var requireString = (value, code, nonempty = true) => {
5861
7496
  if (typeof value !== "string" || nonempty && value.length === 0) fail(code);
5862
7497
  return value;
5863
7498
  };
5864
- var normalizeEvmAddress3 = (value, code) => {
7499
+ var normalizeEvmAddress4 = (value, code) => {
5865
7500
  const address = requireString(value, code);
5866
- if (!EVM_ADDRESS2.test(address) || /^0x0{40}$/iu.test(address)) fail(code);
7501
+ if (!EVM_ADDRESS3.test(address) || /^0x0{40}$/iu.test(address)) fail(code);
5867
7502
  return address.toLowerCase();
5868
7503
  };
5869
7504
  var normalizePositiveUint64 = (value, code) => {
@@ -5876,7 +7511,7 @@ var normalizePositiveUint64 = (value, code) => {
5876
7511
  return fail(code);
5877
7512
  }
5878
7513
  const valueParsed = parsed;
5879
- if (valueParsed <= 0n || valueParsed > UINT64_MAX) fail(code);
7514
+ if (valueParsed <= 0n || valueParsed > UINT64_MAX2) fail(code);
5880
7515
  return { source, value: valueParsed };
5881
7516
  };
5882
7517
  var normalizeCanonicalUint64 = (value, code) => {
@@ -5889,7 +7524,7 @@ var normalizeCanonicalUint64 = (value, code) => {
5889
7524
  return fail(code);
5890
7525
  }
5891
7526
  const valueParsed = parsed;
5892
- if (valueParsed > UINT64_MAX) fail(code);
7527
+ if (valueParsed > UINT64_MAX2) fail(code);
5893
7528
  return { source, value: valueParsed };
5894
7529
  };
5895
7530
  var normalizeSlippage = (value, code) => {
@@ -5898,18 +7533,22 @@ var normalizeSlippage = (value, code) => {
5898
7533
  }
5899
7534
  return value;
5900
7535
  };
5901
- var providerAddressEquals = (value, expected) => typeof value === "string" && (EVM_ADDRESS2.test(value) ? value.toLowerCase() === expected.toLowerCase() : value === expected);
5902
- 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";
5903
- var directionFacts = (sourceChainId, destinationChainId) => {
5904
- if (sourceChainId === ETHEREUM_CHAIN_ID && destinationChainId === SOLANA_CHAIN_ID) {
7536
+ var providerAddressEquals = (value, expected) => typeof value === "string" && (EVM_ADDRESS3.test(value) ? value.toLowerCase() === expected.toLowerCase() : value === expected);
7537
+ var catalogTokenMatches = (token, expected) => token?.deploymentId === expected.deploymentId && token.chainId === expected.chainId && token.address !== null && (expected.chainId === ETHEREUM_CHAIN_ID2 ? token.address.toLowerCase() === expected.address.toLowerCase() : token.address === expected.address) && token.standard === expected.standard && token.decimals === expected.decimals && token.status === "active";
7538
+ var directionFacts = (sourceChainId, destinationChainId, sourceTokenDeploymentId, destinationTokenDeploymentId) => {
7539
+ if (sourceChainId === ETHEREUM_CHAIN_ID2 && destinationChainId === SOLANA_CHAIN_ID2) {
7540
+ const isEurc = sourceTokenDeploymentId === ETHEREUM_EURC_DEPLOYMENT_ID && destinationTokenDeploymentId === SOLANA_EURC_DEPLOYMENT_ID;
7541
+ const isUsdc = sourceTokenDeploymentId === ETHEREUM_USDC_DEPLOYMENT_ID && destinationTokenDeploymentId === SOLANA_USDC_DEPLOYMENT_ID;
7542
+ if (!isEurc && !isUsdc) return fail("BRIDGE_UNSUPPORTED_ROUTE");
5905
7543
  return {
5906
7544
  sourceChainId,
5907
7545
  destinationChainId,
5908
- bridgeCapabilityId: "bridge-mayan-swift-v2-eurc-eth-sol",
5909
- sourceTokenDeploymentId: ETHEREUM_EURC_DEPLOYMENT_ID,
5910
- destinationTokenDeploymentId: SOLANA_EURC_DEPLOYMENT_ID,
5911
- sourceTokenAddress: ETHEREUM_EURC_ADDRESS,
5912
- destinationTokenAddress: SOLANA_EURC_ADDRESS,
7546
+ asset: isEurc ? "eurc" : "usdc",
7547
+ bridgeCapabilityId: isEurc ? "bridge-mayan-swift-v2-eurc-eth-sol" : "bridge-mayan-swift-v2-usdc-eth-sol",
7548
+ sourceTokenDeploymentId,
7549
+ destinationTokenDeploymentId,
7550
+ sourceTokenAddress: isEurc ? ETHEREUM_EURC_ADDRESS : ETHEREUM_USDC_ADDRESS,
7551
+ destinationTokenAddress: isEurc ? SOLANA_EURC_ADDRESS : SOLANA_USDC_ADDRESS,
5913
7552
  sourceTokenStandard: "erc20",
5914
7553
  destinationTokenStandard: "spl-token",
5915
7554
  sourceProviderChainId: ETHEREUM_PROVIDER_CHAIN_ID,
@@ -5918,23 +7557,31 @@ var directionFacts = (sourceChainId, destinationChainId) => {
5918
7557
  destinationWormholeChainId: SOLANA_WORMHOLE_CHAIN_ID,
5919
7558
  sourceName: ETHEREUM_NAME,
5920
7559
  destinationName: SOLANA_NAME,
5921
- sourceEurcMint: "",
5922
- destinationEurcMint: SOLANA_EURC_ADDRESS,
7560
+ sourceTokenName: isEurc ? "EuroC" : "USD Coin",
7561
+ destinationTokenName: isEurc ? "EuroC" : "USD Coin",
7562
+ sourceTokenMint: isEurc ? "" : MAYAN_USDC_MINT,
7563
+ destinationTokenMint: isEurc ? SOLANA_EURC_ADDRESS : SOLANA_USDC_ADDRESS,
5923
7564
  sourceUsdcDeploymentId: ETHEREUM_USDC_DEPLOYMENT_ID,
5924
7565
  sourceUsdcAddress: ETHEREUM_USDC_ADDRESS,
5925
7566
  sourceUsdcStandard: "erc20",
5926
- swiftContract: ETHEREUM_SWIFT_CONTRACT
7567
+ swiftContract: ETHEREUM_SWIFT_CONTRACT,
7568
+ forwarderAddress: ETHEREUM_FORWARDER2,
7569
+ forwarderFunctionSelector: isUsdc ? ETHEREUM_USDC_FORWARDER_SELECTOR : ETHEREUM_EURC_FORWARDER_SELECTOR
5927
7570
  };
5928
7571
  }
5929
- if (sourceChainId === SOLANA_CHAIN_ID && destinationChainId === ETHEREUM_CHAIN_ID) {
7572
+ if (sourceChainId === SOLANA_CHAIN_ID2 && destinationChainId === ETHEREUM_CHAIN_ID2) {
7573
+ const isEurc = sourceTokenDeploymentId === SOLANA_EURC_DEPLOYMENT_ID && destinationTokenDeploymentId === ETHEREUM_EURC_DEPLOYMENT_ID;
7574
+ const isUsdc = sourceTokenDeploymentId === SOLANA_USDC_DEPLOYMENT_ID && destinationTokenDeploymentId === ETHEREUM_USDC_DEPLOYMENT_ID;
7575
+ if (!isEurc && !isUsdc) return fail("BRIDGE_UNSUPPORTED_ROUTE");
5930
7576
  return {
5931
7577
  sourceChainId,
5932
7578
  destinationChainId,
5933
- bridgeCapabilityId: "bridge-mayan-swift-v2-eurc-sol-eth",
5934
- sourceTokenDeploymentId: SOLANA_EURC_DEPLOYMENT_ID,
5935
- destinationTokenDeploymentId: ETHEREUM_EURC_DEPLOYMENT_ID,
5936
- sourceTokenAddress: SOLANA_EURC_ADDRESS,
5937
- destinationTokenAddress: ETHEREUM_EURC_ADDRESS,
7579
+ asset: isEurc ? "eurc" : "usdc",
7580
+ bridgeCapabilityId: isEurc ? "bridge-mayan-swift-v2-eurc-sol-eth" : "bridge-mayan-swift-v2-usdc-sol-eth",
7581
+ sourceTokenDeploymentId,
7582
+ destinationTokenDeploymentId,
7583
+ sourceTokenAddress: isEurc ? SOLANA_EURC_ADDRESS : SOLANA_USDC_ADDRESS,
7584
+ destinationTokenAddress: isEurc ? ETHEREUM_EURC_ADDRESS : ETHEREUM_USDC_ADDRESS,
5938
7585
  sourceTokenStandard: "spl-token",
5939
7586
  destinationTokenStandard: "erc20",
5940
7587
  sourceProviderChainId: SOLANA_PROVIDER_CHAIN_ID,
@@ -5943,12 +7590,16 @@ var directionFacts = (sourceChainId, destinationChainId) => {
5943
7590
  destinationWormholeChainId: ETHEREUM_WORMHOLE_CHAIN_ID,
5944
7591
  sourceName: SOLANA_NAME,
5945
7592
  destinationName: ETHEREUM_NAME,
5946
- sourceEurcMint: SOLANA_EURC_ADDRESS,
5947
- destinationEurcMint: "",
7593
+ sourceTokenName: isEurc ? "EuroC" : "USD Coin",
7594
+ destinationTokenName: isEurc ? "EuroC" : "USD Coin",
7595
+ sourceTokenMint: isEurc ? SOLANA_EURC_ADDRESS : SOLANA_USDC_ADDRESS,
7596
+ destinationTokenMint: isEurc ? "" : MAYAN_USDC_MINT,
5948
7597
  sourceUsdcDeploymentId: SOLANA_USDC_DEPLOYMENT_ID,
5949
7598
  sourceUsdcAddress: SOLANA_USDC_ADDRESS,
5950
7599
  sourceUsdcStandard: "spl-token",
5951
- swiftContract: SOLANA_SWIFT_PROGRAM
7600
+ swiftContract: SOLANA_SWIFT_PROGRAM2,
7601
+ forwarderAddress: null,
7602
+ forwarderFunctionSelector: null
5952
7603
  };
5953
7604
  }
5954
7605
  return fail("BRIDGE_UNSUPPORTED_ROUTE");
@@ -6012,12 +7663,12 @@ var validateCapability = (capability, facts) => {
6012
7663
  sourceUsdcStandard: facts.sourceUsdcStandard,
6013
7664
  sourceUsdcDecimals: 6,
6014
7665
  swiftContract: facts.swiftContract,
6015
- forwarderAddress: facts.sourceChainId === ETHEREUM_CHAIN_ID ? ETHEREUM_FORWARDER : null,
6016
- forwarderFunctionSelector: facts.sourceChainId === ETHEREUM_CHAIN_ID ? "0x30dedc57" : null,
6017
- jupiterProgramAddress: facts.sourceChainId === SOLANA_CHAIN_ID ? SOLANA_JUPITER_V6 : null,
7666
+ forwarderAddress: facts.sourceChainId === ETHEREUM_CHAIN_ID2 ? ETHEREUM_FORWARDER2 : null,
7667
+ forwarderFunctionSelector: facts.sourceChainId === ETHEREUM_CHAIN_ID2 ? facts.asset === "usdc" ? ETHEREUM_USDC_FORWARDER_SELECTOR : ETHEREUM_EURC_FORWARDER_SELECTOR : null,
7668
+ jupiterProgramAddress: facts.sourceChainId === SOLANA_CHAIN_ID2 && facts.asset === "eurc" ? SOLANA_JUPITER_V62 : null,
6018
7669
  builderEndpoint: DEFAULT_BUILDER_ENDPOINT,
6019
7670
  explorerEndpoint: DEFAULT_EXPLORER_ENDPOINT,
6020
- dependencies: facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES],
7671
+ dependencies: facts.asset === "usdc" ? [...DIRECT_USDC_DEPENDENCIES] : facts.sourceChainId === SOLANA_CHAIN_ID2 ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES],
6021
7672
  status: "active"
6022
7673
  };
6023
7674
  const actualKeys = Object.keys(capability).sort();
@@ -6058,10 +7709,12 @@ var validateBridgeRoute = (request) => {
6058
7709
  );
6059
7710
  const amountIn = normalizePositiveUint64(value.amountIn, "BRIDGE_INVALID_ARGUMENT");
6060
7711
  const slippageBps = normalizeSlippage(value.slippageBps, "BRIDGE_INVALID_ARGUMENT");
6061
- const facts = directionFacts(sourceChainId, destinationChainId);
6062
- if (sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) {
6063
- fail("BRIDGE_UNSUPPORTED_ROUTE");
6064
- }
7712
+ const facts = directionFacts(
7713
+ sourceChainId,
7714
+ destinationChainId,
7715
+ sourceTokenDeploymentId,
7716
+ destinationTokenDeploymentId
7717
+ );
6065
7718
  validateCatalogDirection(facts);
6066
7719
  const capability = findCapability(facts);
6067
7720
  validateCapability(capability, facts);
@@ -6093,7 +7746,7 @@ var StrictJsonParser = class {
6093
7746
  return value;
6094
7747
  }
6095
7748
  #value(depth) {
6096
- if (depth > MAX_JSON_DEPTH) this.#invalid();
7749
+ if (depth > MAX_JSON_DEPTH2) this.#invalid();
6097
7750
  const start = this.#index;
6098
7751
  const character = this.#source[this.#index];
6099
7752
  if (character === "{") return this.#object(start, depth);
@@ -6305,7 +7958,7 @@ var decodeResponseBody = async (response, controlled, external) => {
6305
7958
  const contentLength = response.headers.get("content-length");
6306
7959
  if (contentLength !== null && /^\d+$/u.test(contentLength)) {
6307
7960
  try {
6308
- if (BigInt(contentLength) > BigInt(MAX_RESPONSE_BYTES)) {
7961
+ if (BigInt(contentLength) > BigInt(MAX_RESPONSE_BYTES2)) {
6309
7962
  fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6310
7963
  }
6311
7964
  } catch {
@@ -6346,7 +7999,7 @@ var decodeResponseBody = async (response, controlled, external) => {
6346
7999
  const chunk = result.value;
6347
8000
  if (!(chunk instanceof Uint8Array)) return fail("BRIDGE_PROVIDER_TRANSPORT");
6348
8001
  totalBytes += chunk.byteLength;
6349
- if (totalBytes > MAX_RESPONSE_BYTES) {
8002
+ if (totalBytes > MAX_RESPONSE_BYTES2) {
6350
8003
  fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
6351
8004
  }
6352
8005
  chunks.push(chunk);
@@ -6381,7 +8034,8 @@ var CONFIG_KEYS = /* @__PURE__ */ new Set([
6381
8034
  "allowUnauthenticatedBuild",
6382
8035
  "minimumQuoteValiditySeconds",
6383
8036
  "timeoutMs",
6384
- "fetch"
8037
+ "fetch",
8038
+ "localBuild"
6385
8039
  ]);
6386
8040
  var endpointWithPath2 = (base, path) => new URL(path.replace(/^\/+/, ""), `${base.toString().replace(/\/+$/u, "")}/`);
6387
8041
  var normalizeProviderEndpoint = (value, fallback, label) => {
@@ -6453,6 +8107,15 @@ var normalizeBridgeConfig = (config) => {
6453
8107
  const timeoutMs = timeoutMsValue;
6454
8108
  const implementation = value.fetch ?? globalThis.fetch;
6455
8109
  if (typeof implementation !== "function") fail("BRIDGE_INVALID_ARGUMENT");
8110
+ let localBuild;
8111
+ if (value.localBuild !== void 0) {
8112
+ const localBuildValue = requireRecord(value.localBuild, "BRIDGE_INVALID_ARGUMENT");
8113
+ const localBuildKeys = /* @__PURE__ */ new Set(["sourceSwapEndpoint", "ethereumRpc", "solanaRpc"]);
8114
+ if (Object.keys(localBuildValue).some((key) => !localBuildKeys.has(key))) {
8115
+ fail("BRIDGE_INVALID_ARGUMENT");
8116
+ }
8117
+ localBuild = localBuildValue;
8118
+ }
6456
8119
  return Object.freeze({
6457
8120
  builderEndpoint,
6458
8121
  explorerEndpoint,
@@ -6460,7 +8123,8 @@ var normalizeBridgeConfig = (config) => {
6460
8123
  allowUnauthenticatedBuild,
6461
8124
  minimumQuoteValiditySeconds,
6462
8125
  timeoutMs,
6463
- fetch: implementation
8126
+ fetch: wrapFetch(implementation),
8127
+ ...localBuild === void 0 ? {} : { localBuild }
6464
8128
  });
6465
8129
  };
6466
8130
  var requestSignal = (timeoutMs, external) => {
@@ -6570,18 +8234,18 @@ var encodeBase58 = (bytes) => {
6570
8234
  }
6571
8235
  let result = "1".repeat(zeroes);
6572
8236
  for (let index = digits.length - 1; index >= 0; index -= 1) {
6573
- result += BASE58_ALPHABET[digits[index] ?? 0] ?? "";
8237
+ result += BASE58_ALPHABET2[digits[index] ?? 0] ?? "";
6574
8238
  }
6575
8239
  return result === "" ? "1" : result;
6576
8240
  };
6577
8241
  var decodeBase58 = (value, expectedBytes, code) => {
6578
8242
  const text = requireString(value, code);
6579
- if (text.length > expectedBytes * 2 || [...text].some((char) => !BASE58_ALPHABET.includes(char))) {
8243
+ if (text.length > expectedBytes * 2 || [...text].some((char) => !BASE58_ALPHABET2.includes(char))) {
6580
8244
  fail(code);
6581
8245
  }
6582
8246
  const bytes = [0];
6583
8247
  for (const char of text) {
6584
- const digit = BASE58_ALPHABET.indexOf(char);
8248
+ const digit = BASE58_ALPHABET2.indexOf(char);
6585
8249
  let carry = digit;
6586
8250
  for (let index = 0; index < bytes.length; index += 1) {
6587
8251
  const current = (bytes[index] ?? 0) * 58 + carry;
@@ -6725,7 +8389,7 @@ var providerInteger = (node, key) => {
6725
8389
  var providerAddress = (node, key, expected) => {
6726
8390
  const value = providerString(node, key);
6727
8391
  if (!providerAddressEquals(value, expected)) providerInvalid();
6728
- return EVM_ADDRESS2.test(value) ? value.toLowerCase() : value;
8392
+ return EVM_ADDRESS3.test(value) ? value.toLowerCase() : value;
6729
8393
  };
6730
8394
  var providerUint64 = (node, key, positive) => {
6731
8395
  const value = providerString(node, key);
@@ -6744,14 +8408,14 @@ var providerToken = (node, expected) => {
6744
8408
  if (mint !== expected.mint) providerInvalid();
6745
8409
  const realOrigin = providerString(node, "realOriginContractAddress");
6746
8410
  if (!providerAddressEquals(realOrigin, expected.address)) providerInvalid();
6747
- if (providerString(node, "name") !== "EuroC") providerInvalid();
8411
+ if (providerString(node, "name") !== expected.name) providerInvalid();
6748
8412
  if (providerString(node, "standard") !== expected.standard) providerInvalid();
6749
8413
  if (providerInteger(node, "chainId") !== expected.chainId) providerInvalid();
6750
8414
  if (providerInteger(node, "wChainId") !== expected.wormholeChainId) providerInvalid();
6751
8415
  if (providerInteger(node, "realOriginChainId") !== expected.wormholeChainId) providerInvalid();
6752
8416
  if (providerInteger(node, "decimals") !== 6) providerInvalid();
6753
8417
  };
6754
- var quoteProviderStandard = (facts) => facts.sourceChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl";
8418
+ var quoteProviderStandard = (facts) => facts.sourceChainId === ETHEREUM_CHAIN_ID2 ? "erc20" : "spl";
6755
8419
  var ensureQuoteDeadline = (deadlineValue, margin) => {
6756
8420
  const now = BigInt(Math.floor(Date.now() / 1e3));
6757
8421
  if (!Number.isSafeInteger(Number(now)) || deadlineValue < now + BigInt(margin)) {
@@ -6783,17 +8447,19 @@ var validateProviderQuote = (node, text, request, facts, config) => {
6783
8447
  const destinationToken = requiredNode(node, "toToken");
6784
8448
  providerToken(sourceToken, {
6785
8449
  address: facts.sourceTokenAddress,
6786
- standard: facts.sourceChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl",
8450
+ standard: facts.sourceChainId === ETHEREUM_CHAIN_ID2 ? "erc20" : "spl",
6787
8451
  chainId: facts.sourceProviderChainId,
6788
8452
  wormholeChainId: facts.sourceWormholeChainId,
6789
- mint: facts.sourceEurcMint
8453
+ mint: facts.sourceTokenMint,
8454
+ name: facts.sourceTokenName
6790
8455
  });
6791
8456
  providerToken(destinationToken, {
6792
8457
  address: facts.destinationTokenAddress,
6793
- standard: facts.destinationChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl",
8458
+ standard: facts.destinationChainId === ETHEREUM_CHAIN_ID2 ? "erc20" : "spl",
6794
8459
  chainId: facts.destinationProviderChainId,
6795
8460
  wormholeChainId: facts.destinationWormholeChainId,
6796
- mint: facts.destinationEurcMint
8461
+ mint: facts.destinationTokenMint,
8462
+ name: facts.destinationTokenName
6797
8463
  });
6798
8464
  const sourceUsdcStandard = quoteProviderStandard(facts);
6799
8465
  if (providerAddress(node, "swiftInputContract", facts.sourceUsdcAddress) !== facts.sourceUsdcAddress) {
@@ -6810,23 +8476,27 @@ var validateProviderQuote = (node, text, request, facts, config) => {
6810
8476
  }
6811
8477
  let routerAddress;
6812
8478
  let routerKind;
6813
- if (facts.sourceChainId === ETHEREUM_CHAIN_ID) {
6814
- routerAddress = normalizeEvmAddress3(
8479
+ const evmRouter = objectValue5(node, "evmSwapRouterAddress");
8480
+ if (facts.asset === "usdc") {
8481
+ if (evmRouter !== void 0 && evmRouter !== null) providerInvalid();
8482
+ routerAddress = null;
8483
+ routerKind = null;
8484
+ } else if (facts.sourceChainId === ETHEREUM_CHAIN_ID2) {
8485
+ routerAddress = normalizeEvmAddress4(
6815
8486
  providerString(node, "evmSwapRouterAddress"),
6816
8487
  "BRIDGE_PROVIDER_INVALID_RESPONSE"
6817
8488
  );
6818
8489
  routerKind = "provider-selected-evm";
6819
8490
  } else {
6820
- routerAddress = SOLANA_JUPITER_V6;
8491
+ routerAddress = SOLANA_JUPITER_V62;
6821
8492
  routerKind = "jupiter-v6";
6822
- const evmRouter = objectValue5(node, "evmSwapRouterAddress");
6823
8493
  if (evmRouter !== void 0 && evmRouter !== null) providerInvalid();
6824
8494
  }
6825
8495
  const quoteId = providerString(node, "quoteId");
6826
8496
  if (!/^0x[0-9a-fA-F]{32}$/u.test(quoteId)) providerInvalid();
6827
8497
  const signature = providerString(node, "signature");
6828
8498
  if (!EVM_SIGNATURE.test(signature)) providerInvalid();
6829
- const dependencies = facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
8499
+ const dependencies = facts.asset === "usdc" ? [...DIRECT_USDC_DEPENDENCIES] : facts.sourceChainId === SOLANA_CHAIN_ID2 ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
6830
8500
  const quote = {
6831
8501
  quoteKind: "mayan-swift-v2",
6832
8502
  providerId: "mayan-swift-v2",
@@ -6843,8 +8513,8 @@ var validateProviderQuote = (node, text, request, facts, config) => {
6843
8513
  quoteId: quoteId.toLowerCase(),
6844
8514
  providerSignature: signature.toLowerCase(),
6845
8515
  sourceSwap: {
6846
- required: true,
6847
- inputTokenDeploymentId: facts.sourceTokenDeploymentId,
8516
+ required: facts.asset === "eurc",
8517
+ inputTokenDeploymentId: facts.asset === "usdc" ? facts.sourceUsdcDeploymentId : facts.sourceTokenDeploymentId,
6848
8518
  intermediateTokenDeploymentId: facts.sourceUsdcDeploymentId,
6849
8519
  intermediateTokenAddress: facts.sourceUsdcAddress,
6850
8520
  intermediateTokenStandard: sourceUsdcStandard,
@@ -6901,10 +8571,10 @@ var exactObjectKeys = (value, expected, code) => {
6901
8571
  fail(code);
6902
8572
  }
6903
8573
  };
6904
- var stableJson = (value) => {
6905
- if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
8574
+ var stableJson2 = (value) => {
8575
+ if (Array.isArray(value)) return `[${value.map(stableJson2).join(",")}]`;
6906
8576
  if (isRecord4(value)) {
6907
- return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
8577
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson2(value[key])}`).join(",")}}`;
6908
8578
  }
6909
8579
  return JSON.stringify(value);
6910
8580
  };
@@ -6921,8 +8591,23 @@ var validateNormalizedQuoteShape = (quote, code) => {
6921
8591
  if (value.quoteKind !== "mayan-swift-v2" || value.providerId !== "mayan-swift-v2") fail(code);
6922
8592
  const sourceChainId = requireString(value.sourceChainId, code);
6923
8593
  const destinationChainId = requireString(value.destinationChainId, code);
6924
- const facts = directionFacts(sourceChainId, destinationChainId);
6925
- if (value.sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || value.destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) fail(code);
8594
+ const sourceTokenDeploymentId = requireString(value.sourceTokenDeploymentId, code);
8595
+ const destinationTokenDeploymentId = requireString(value.destinationTokenDeploymentId, code);
8596
+ let facts;
8597
+ try {
8598
+ facts = directionFacts(
8599
+ sourceChainId,
8600
+ destinationChainId,
8601
+ sourceTokenDeploymentId,
8602
+ destinationTokenDeploymentId
8603
+ );
8604
+ } catch (error) {
8605
+ if (error instanceof BridgeError && error.code === "BRIDGE_UNSUPPORTED_ROUTE") {
8606
+ return fail(code);
8607
+ }
8608
+ throw error;
8609
+ }
8610
+ if (sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) fail(code);
6926
8611
  const amountIn = normalizePositiveUint64(value.amountIn, code);
6927
8612
  const expectedAmountOut = normalizePositiveUint64(value.expectedAmountOut, code);
6928
8613
  const minimumAmountOut = normalizePositiveUint64(value.minimumAmountOut, code);
@@ -6937,29 +8622,33 @@ var validateNormalizedQuoteShape = (quote, code) => {
6937
8622
  if (!EVM_SIGNATURE.test(signature)) fail(code);
6938
8623
  const sourceSwap = requireRecord(value.sourceSwap, code);
6939
8624
  exactObjectKeys(sourceSwap, SOURCE_SWAP_KEYS, code);
6940
- if (sourceSwap.required !== true) fail(code);
6941
- if (sourceSwap.inputTokenDeploymentId !== facts.sourceTokenDeploymentId || sourceSwap.intermediateTokenDeploymentId !== facts.sourceUsdcDeploymentId) fail(code);
8625
+ if (sourceSwap.required !== (facts.asset === "eurc")) fail(code);
8626
+ if (sourceSwap.inputTokenDeploymentId !== (facts.asset === "usdc" ? facts.sourceUsdcDeploymentId : facts.sourceTokenDeploymentId) || sourceSwap.intermediateTokenDeploymentId !== facts.sourceUsdcDeploymentId) fail(code);
6942
8627
  if (sourceSwap.intermediateTokenAddress !== facts.sourceUsdcAddress) fail(code);
6943
- const providerStandard = quoteProviderStandard(facts);
6944
- if (sourceSwap.intermediateTokenStandard !== providerStandard || sourceSwap.intermediateTokenDecimals !== 6) fail(code);
8628
+ const providerStandard2 = quoteProviderStandard(facts);
8629
+ if (sourceSwap.intermediateTokenStandard !== providerStandard2 || sourceSwap.intermediateTokenDecimals !== 6) fail(code);
6945
8630
  const providerMinimumAmount = sourceSwap.providerMinimumAmount;
6946
8631
  if (typeof providerMinimumAmount !== "string" || providerMinimumAmount.length === 0) fail(code);
6947
8632
  let normalizedRouterAddress;
6948
8633
  let normalizedRouterKind;
6949
- if (facts.sourceChainId === ETHEREUM_CHAIN_ID) {
8634
+ if (facts.asset === "usdc") {
8635
+ if (sourceSwap.routerKind !== null || sourceSwap.routerAddress !== null) fail(code);
8636
+ normalizedRouterAddress = null;
8637
+ normalizedRouterKind = null;
8638
+ } else if (facts.sourceChainId === ETHEREUM_CHAIN_ID2) {
6950
8639
  const routerAddress = sourceSwap.routerAddress;
6951
- if (sourceSwap.routerKind !== "provider-selected-evm" || typeof routerAddress !== "string" || !EVM_ADDRESS2.test(routerAddress) || /^0x0{40}$/iu.test(routerAddress)) return fail(code);
8640
+ if (sourceSwap.routerKind !== "provider-selected-evm" || typeof routerAddress !== "string" || !EVM_ADDRESS3.test(routerAddress) || /^0x0{40}$/iu.test(routerAddress)) return fail(code);
6952
8641
  normalizedRouterAddress = routerAddress.toLowerCase();
6953
8642
  normalizedRouterKind = "provider-selected-evm";
6954
- } else if (sourceSwap.routerKind !== "jupiter-v6" || sourceSwap.routerAddress !== SOLANA_JUPITER_V6) {
8643
+ } else if (sourceSwap.routerKind !== "jupiter-v6" || sourceSwap.routerAddress !== SOLANA_JUPITER_V62) {
6955
8644
  return fail(code);
6956
8645
  } else {
6957
- normalizedRouterAddress = SOLANA_JUPITER_V6;
8646
+ normalizedRouterAddress = SOLANA_JUPITER_V62;
6958
8647
  normalizedRouterKind = "jupiter-v6";
6959
8648
  }
6960
8649
  if (!Array.isArray(value.dependencies)) fail(code);
6961
- const wantedDependencies = facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
6962
- if (stableJson(value.dependencies) !== stableJson(wantedDependencies)) fail(code);
8650
+ const wantedDependencies = facts.asset === "usdc" ? [...DIRECT_USDC_DEPENDENCIES] : facts.sourceChainId === SOLANA_CHAIN_ID2 ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
8651
+ if (stableJson2(value.dependencies) !== stableJson2(wantedDependencies)) fail(code);
6963
8652
  const rawSignedQuoteJson = requireString(value.rawSignedQuoteJson, code);
6964
8653
  if (byteLength(rawSignedQuoteJson) > MAX_RAW_QUOTE_BYTES) fail(code);
6965
8654
  return {
@@ -6978,11 +8667,11 @@ var validateNormalizedQuoteShape = (quote, code) => {
6978
8667
  quoteId: quoteId.toLowerCase(),
6979
8668
  providerSignature: signature.toLowerCase(),
6980
8669
  sourceSwap: {
6981
- required: true,
6982
- inputTokenDeploymentId: facts.sourceTokenDeploymentId,
8670
+ required: facts.asset === "eurc",
8671
+ inputTokenDeploymentId: facts.asset === "usdc" ? facts.sourceUsdcDeploymentId : facts.sourceTokenDeploymentId,
6983
8672
  intermediateTokenDeploymentId: facts.sourceUsdcDeploymentId,
6984
8673
  intermediateTokenAddress: facts.sourceUsdcAddress,
6985
- intermediateTokenStandard: providerStandard,
8674
+ intermediateTokenStandard: providerStandard2,
6986
8675
  intermediateTokenDecimals: 6,
6987
8676
  providerMinimumAmount,
6988
8677
  routerKind: normalizedRouterKind,
@@ -7063,7 +8752,7 @@ var buildRequestSnapshot = (value) => {
7063
8752
  };
7064
8753
  };
7065
8754
  var normalizeChainAddress = (value, chainId, code) => {
7066
- if (chainId === ETHEREUM_CHAIN_ID) return normalizeEvmAddress3(value, code);
8755
+ if (chainId === ETHEREUM_CHAIN_ID2) return normalizeEvmAddress4(value, code);
7067
8756
  const address = requireString(value, code);
7068
8757
  decodeBase58(address, 32, code);
7069
8758
  return address;
@@ -7078,9 +8767,9 @@ var isCanonicalSolanaAddress = (value) => {
7078
8767
  }
7079
8768
  };
7080
8769
  var rejectAddressFromOtherChain = (value, expectedChainId) => {
7081
- const isEvm = typeof value === "string" && EVM_ADDRESS2.test(value) && !/^0x0{40}$/iu.test(value);
8770
+ const isEvm = typeof value === "string" && EVM_ADDRESS3.test(value) && !/^0x0{40}$/iu.test(value);
7082
8771
  const isSolana = isCanonicalSolanaAddress(value);
7083
- if (expectedChainId === ETHEREUM_CHAIN_ID && isSolana || expectedChainId === SOLANA_CHAIN_ID && isEvm) {
8772
+ if (expectedChainId === ETHEREUM_CHAIN_ID2 && isSolana || expectedChainId === SOLANA_CHAIN_ID2 && isEvm) {
7084
8773
  fail("BRIDGE_QUOTE_MISMATCH");
7085
8774
  }
7086
8775
  };
@@ -7095,7 +8784,7 @@ var buildRouteFromQuote = (quote) => {
7095
8784
  if (error instanceof BridgeError) throw error;
7096
8785
  return fail("BRIDGE_QUOTE_MISMATCH");
7097
8786
  }
7098
- if (stableJson(quote) !== stableJson(normalizedQuote)) fail("BRIDGE_QUOTE_MISMATCH");
8787
+ if (stableJson2(quote) !== stableJson2(normalizedQuote)) fail("BRIDGE_QUOTE_MISMATCH");
7099
8788
  const route = validateBridgeRoute({
7100
8789
  sourceChainId: normalizedQuote.sourceChainId,
7101
8790
  destinationChainId: normalizedQuote.destinationChainId,
@@ -7130,7 +8819,9 @@ var validateRawQuoteForBuild = (quote, route, config) => {
7130
8819
  if (error instanceof BridgeError && error.code === "BRIDGE_QUOTE_EXPIRED") throw error;
7131
8820
  return fail("BRIDGE_QUOTE_MISMATCH");
7132
8821
  }
7133
- if (stableJson(rebuilt.quote) !== stableJson(quote)) fail("BRIDGE_QUOTE_MISMATCH");
8822
+ if (stableJson2(rebuilt.quote) !== stableJson2(quote)) {
8823
+ fail("BRIDGE_QUOTE_MISMATCH");
8824
+ }
7134
8825
  return deepFreeze6(quote);
7135
8826
  };
7136
8827
  var numericZero = (value) => {
@@ -7139,26 +8830,29 @@ var numericZero = (value) => {
7139
8830
  if (value === "0") return true;
7140
8831
  return /^0x0+$/iu.test(value);
7141
8832
  };
7142
- var validateEvmBuildResult = (wrapper, swapperAddress) => {
8833
+ var validateEvmBuildResult = (wrapper, swapperAddress, facts) => {
8834
+ const forwarderAddress = facts.forwarderAddress ?? providerInvalid();
8835
+ const forwarderFunctionSelector = facts.forwarderFunctionSelector ?? providerInvalid();
7143
8836
  if (providerString(wrapper, "chainCategory") !== "evm") providerInvalid();
7144
8837
  if (providerString(wrapper, "quoteType") !== "SWIFT") providerInvalid();
7145
8838
  if (providerBoolean(wrapper, "gasless")) providerInvalid();
7146
8839
  const transaction = requiredNode(wrapper, "transaction");
7147
8840
  if (!isRecord4(transaction.value)) providerInvalid();
7148
8841
  const to = providerString(transaction, "to");
7149
- if (!providerAddressEquals(to, ETHEREUM_FORWARDER)) providerInvalid();
8842
+ if (!providerAddressEquals(to, forwarderAddress)) providerInvalid();
7150
8843
  const chainId = providerInteger(transaction, "chainId");
7151
8844
  if (chainId !== ETHEREUM_PROVIDER_CHAIN_ID) providerInvalid();
7152
8845
  if (!numericZero(objectValue5(transaction, "value"))) providerInvalid();
7153
8846
  const data = providerString(transaction, "data").toLowerCase();
7154
- if (!HEX_BYTES2.test(data) || data.length % 2 !== 0 || !data.startsWith(ETHEREUM_FORWARDER_SELECTOR) || data.length < 2 + 8 + 13 * 64) {
8847
+ const minimumWords = facts.asset === "usdc" ? 10 : 13;
8848
+ if (!HEX_BYTES3.test(data) || data.length % 2 !== 0 || !data.startsWith(forwarderFunctionSelector) || data.length < 2 + 8 + minimumWords * 64) {
7155
8849
  providerInvalid();
7156
8850
  }
7157
8851
  return {
7158
8852
  kind: "evm-unsigned-transaction",
7159
8853
  chainId: "eip155:1",
7160
8854
  from: swapperAddress,
7161
- to: ETHEREUM_FORWARDER,
8855
+ to: forwarderAddress,
7162
8856
  data,
7163
8857
  value: "0"
7164
8858
  };
@@ -7172,7 +8866,7 @@ var validateSolanaBuildResult = (wrapper, swapperAddress) => {
7172
8866
  const encoded = validateSolanaTransaction(transaction.value, swapperAddress);
7173
8867
  return {
7174
8868
  kind: "solana-v0-unsigned-transaction",
7175
- chainId: SOLANA_CHAIN_ID,
8869
+ chainId: SOLANA_CHAIN_ID2,
7176
8870
  feePayer: swapperAddress,
7177
8871
  transactionBase64: encoded
7178
8872
  };
@@ -7193,7 +8887,7 @@ var validateBuildResponse = (response, quote, facts, swapperAddress) => {
7193
8887
  }
7194
8888
  let transaction;
7195
8889
  try {
7196
- transaction = facts.sourceChainId === ETHEREUM_CHAIN_ID ? validateEvmBuildResult(wrapper, swapperAddress) : validateSolanaBuildResult(wrapper, swapperAddress);
8890
+ transaction = facts.sourceChainId === ETHEREUM_CHAIN_ID2 ? validateEvmBuildResult(wrapper, swapperAddress, facts) : validateSolanaBuildResult(wrapper, swapperAddress);
7197
8891
  } catch (error) {
7198
8892
  if (error instanceof BridgeError) {
7199
8893
  if (error.code === "BRIDGE_BUILD_INVALID") throw error;
@@ -7208,11 +8902,11 @@ var validateBuildResponse = (response, quote, facts, swapperAddress) => {
7208
8902
  sourceChainId: quote.sourceChainId,
7209
8903
  destinationChainId: quote.destinationChainId,
7210
8904
  transaction,
7211
- allowance: facts.sourceChainId === ETHEREUM_CHAIN_ID ? {
7212
- tokenDeploymentId: "deployment-0011",
7213
- tokenAddress: ETHEREUM_EURC_ADDRESS,
8905
+ allowance: facts.sourceChainId === ETHEREUM_CHAIN_ID2 ? {
8906
+ tokenDeploymentId: facts.sourceTokenDeploymentId,
8907
+ tokenAddress: facts.sourceTokenAddress,
7214
8908
  owner: swapperAddress,
7215
- spender: ETHEREUM_FORWARDER,
8909
+ spender: facts.forwarderAddress,
7216
8910
  requiredAmount: quote.amountIn
7217
8911
  } : null,
7218
8912
  validation: {
@@ -7238,14 +8932,14 @@ var statusRequestSnapshot = (value) => {
7238
8932
  };
7239
8933
  var normalizeStatusRequest = (value) => {
7240
8934
  const request = statusRequestSnapshot(value);
7241
- if (request.sourceChainId === ETHEREUM_CHAIN_ID) {
8935
+ if (request.sourceChainId === ETHEREUM_CHAIN_ID2) {
7242
8936
  if (!EVM_HASH.test(request.sourceTransactionHash)) fail("BRIDGE_INVALID_ARGUMENT");
7243
8937
  return {
7244
8938
  sourceChainId: request.sourceChainId,
7245
8939
  sourceTransactionHash: request.sourceTransactionHash.toLowerCase()
7246
8940
  };
7247
8941
  }
7248
- if (request.sourceChainId === SOLANA_CHAIN_ID) {
8942
+ if (request.sourceChainId === SOLANA_CHAIN_ID2) {
7249
8943
  decodeBase58(request.sourceTransactionHash, 64, "BRIDGE_INVALID_ARGUMENT");
7250
8944
  return request;
7251
8945
  }
@@ -7281,7 +8975,7 @@ var buildBody = (quote, sourceChainId, swapperAddress, destinationAddress, refun
7281
8975
  swapperAddress,
7282
8976
  destinationAddress
7283
8977
  };
7284
- if (sourceChainId === ETHEREUM_CHAIN_ID) params.signerChainId = 1;
8978
+ if (sourceChainId === ETHEREUM_CHAIN_ID2) params.signerChainId = 1;
7285
8979
  if (refundAddress !== void 0) params.swiftRefundAddress = refundAddress;
7286
8980
  return `{"quote":${quote.rawSignedQuoteJson},"params":${JSON.stringify(params)}}`;
7287
8981
  };
@@ -7361,11 +9055,42 @@ var MayanSwiftV2BridgeClient = class {
7361
9055
  const parsed = await providerJson(response, "status");
7362
9056
  return statusFromResponse(parsed, normalized);
7363
9057
  }
9058
+ async prepareSourceSwap(context, options) {
9059
+ return prepareSourceSwap(context, this.#localRuntime(), options);
9060
+ }
9061
+ async buildLocalUnsigned(request, options) {
9062
+ return buildLocalUnsigned(request, this.#localRuntime(), options);
9063
+ }
9064
+ #localRuntime() {
9065
+ return {
9066
+ localBuild: this.#config.localBuild,
9067
+ fetch: this.#config.fetch,
9068
+ timeoutMs: this.#config.timeoutMs,
9069
+ minimumQuoteValiditySeconds: this.#config.minimumQuoteValiditySeconds,
9070
+ validateQuote: (quote, invalidCode) => {
9071
+ try {
9072
+ const { route, normalizedQuote } = buildRouteFromQuote(quote);
9073
+ const validationQuote = /[ \t\r\n]$/u.test(normalizedQuote.rawSignedQuoteJson) ? {
9074
+ ...normalizedQuote,
9075
+ rawSignedQuoteJson: normalizedQuote.rawSignedQuoteJson.replace(/[ \t\r\n]+$/gu, "")
9076
+ } : normalizedQuote;
9077
+ validateRawQuoteForBuild(validationQuote, route, this.#config);
9078
+ return quote;
9079
+ } catch (error) {
9080
+ if (error instanceof BridgeError && error.code === "BRIDGE_QUOTE_EXPIRED") {
9081
+ throw error;
9082
+ }
9083
+ return fail(invalidCode);
9084
+ }
9085
+ },
9086
+ fail
9087
+ };
9088
+ }
7364
9089
  close() {
7365
9090
  }
7366
9091
  };
7367
9092
  var createMayanSwiftV2BridgeClient = (config) => new MayanSwiftV2BridgeClient(config);
7368
9093
 
7369
- 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 };
9094
+ 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_BASE_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 };
7370
9095
  //# sourceMappingURL=index.js.map
7371
9096
  //# sourceMappingURL=index.js.map