@elsoul/erpc-sdk 0.8.1 → 0.9.1

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