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