@elsoul/erpc-sdk 0.8.1 → 0.9.0

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