@shogun-sdk/swap 0.0.2-test.4 → 0.0.2-test.41

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
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,45 +17,29 @@ var __copyProps = (to, from, except, desc) => {
16
17
  return to;
17
18
  };
18
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
19
21
 
20
22
  // src/index.ts
21
23
  var src_exports = {};
22
24
  __export(src_exports, {
23
- NATIVE_TOKEN: () => NATIVE_TOKEN,
24
- SOLANA_CHAIN_ID: () => SOLANA_CHAIN_ID,
25
+ ChainId: () => ChainId,
26
+ OrderExecutionType: () => OrderExecutionType,
25
27
  SupportedChains: () => SupportedChains,
26
- adaptEthersSigner: () => adaptEthersSigner,
27
- adaptSolanaWallet: () => adaptSolanaWallet,
28
- adaptViemWallet: () => adaptViemWallet,
28
+ SwapSDK: () => SwapSDK,
29
29
  buildQuoteParams: () => buildQuoteParams,
30
- executeOrder: () => executeOrder,
31
- getBalances: () => getBalances,
32
- getQuote: () => getQuote,
33
- getTokenList: () => getTokenList,
34
- isNativeAddress: () => isNativeAddress,
35
- isViemWalletClient: () => isViemWalletClient,
36
- serializeBigIntsToStrings: () => serializeBigIntsToStrings,
37
- useBalances: () => useBalances,
38
- useExecuteOrder: () => useExecuteOrder,
39
- useQuote: () => useQuote,
40
- useTokenList: () => useTokenList
30
+ isEvmChain: () => isEvmChain
41
31
  });
42
32
  module.exports = __toCommonJS(src_exports);
43
33
 
44
- // src/core/token-list.ts
45
- var import_intents_sdk = require("@shogun-sdk/intents-sdk");
46
- async function getTokenList(params) {
47
- return (0, import_intents_sdk.getTokenList)(params);
48
- }
49
-
50
34
  // src/core/getQuote.ts
51
- var import_intents_sdk4 = require("@shogun-sdk/intents-sdk");
52
- var import_viem = require("viem");
53
-
54
- // src/core/executeOrder/normalizeNative.ts
55
35
  var import_intents_sdk3 = require("@shogun-sdk/intents-sdk");
36
+ var import_viem2 = require("viem");
37
+
38
+ // src/core/execute/normalizeNative.ts
39
+ var import_intents_sdk2 = require("@shogun-sdk/intents-sdk");
56
40
 
57
41
  // src/utils/address.ts
42
+ var import_viem = require("viem");
58
43
  var NATIVE_TOKEN = {
59
44
  ETH: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
60
45
  SOL: "So11111111111111111111111111111111111111111",
@@ -65,13 +50,32 @@ var isNativeAddress = (tokenAddress) => {
65
50
  const normalizedTokenAddress = tokenAddress.toLowerCase();
66
51
  return !!tokenAddress && NATIVE_ADDRESSES.includes(normalizedTokenAddress);
67
52
  };
53
+ function normalizeEvmTokenAddress(address) {
54
+ const lower = address.toLowerCase();
55
+ return lower === NATIVE_TOKEN.ETH.toLowerCase() ? import_viem.zeroAddress : address;
56
+ }
68
57
 
69
58
  // src/utils/chain.ts
70
- var import_intents_sdk2 = require("@shogun-sdk/intents-sdk");
71
- var SOLANA_CHAIN_ID = import_intents_sdk2.ChainID.Solana;
72
- var SupportedChains = [
59
+ var import_intents_sdk = require("@shogun-sdk/intents-sdk");
60
+ var SOLANA_CHAIN_ID = import_intents_sdk.ChainID.Solana;
61
+ var CURRENT_SUPPORTED = [
62
+ import_intents_sdk.ChainID.Solana,
63
+ import_intents_sdk.ChainID.BSC,
64
+ import_intents_sdk.ChainID.Base,
65
+ import_intents_sdk.ChainID.MONAD
66
+ ];
67
+ var ChainId = Object.entries(import_intents_sdk.ChainID).reduce(
68
+ (acc, [key, value]) => {
69
+ if (typeof value === "number" && CURRENT_SUPPORTED.includes(value)) {
70
+ acc[key] = value;
71
+ }
72
+ return acc;
73
+ },
74
+ {}
75
+ );
76
+ var SupportedChainsInternal = [
73
77
  {
74
- id: import_intents_sdk2.ChainID.Arbitrum,
78
+ id: import_intents_sdk.ChainID.Arbitrum,
75
79
  name: "Arbitrum",
76
80
  isEVM: true,
77
81
  wrapped: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
@@ -80,7 +84,7 @@ var SupportedChains = [
80
84
  tokenAddress: NATIVE_TOKEN.ETH
81
85
  },
82
86
  {
83
- id: import_intents_sdk2.ChainID.Optimism,
87
+ id: import_intents_sdk.ChainID.Optimism,
84
88
  name: "Optimism",
85
89
  isEVM: true,
86
90
  wrapped: "0x4200000000000000000000000000000000000006",
@@ -89,7 +93,7 @@ var SupportedChains = [
89
93
  tokenAddress: NATIVE_TOKEN.ETH
90
94
  },
91
95
  {
92
- id: import_intents_sdk2.ChainID.Base,
96
+ id: import_intents_sdk.ChainID.Base,
93
97
  name: "Base",
94
98
  isEVM: true,
95
99
  wrapped: "0x4200000000000000000000000000000000000006",
@@ -98,7 +102,7 @@ var SupportedChains = [
98
102
  tokenAddress: NATIVE_TOKEN.ETH
99
103
  },
100
104
  {
101
- id: import_intents_sdk2.ChainID.Hyperliquid,
105
+ id: import_intents_sdk.ChainID.Hyperliquid,
102
106
  name: "Hyperliquid",
103
107
  isEVM: true,
104
108
  wrapped: "0x5555555555555555555555555555555555555555",
@@ -107,7 +111,7 @@ var SupportedChains = [
107
111
  tokenAddress: NATIVE_TOKEN.ETH
108
112
  },
109
113
  {
110
- id: import_intents_sdk2.ChainID.BSC,
114
+ id: import_intents_sdk.ChainID.BSC,
111
115
  name: "BSC",
112
116
  isEVM: true,
113
117
  wrapped: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
@@ -123,8 +127,21 @@ var SupportedChains = [
123
127
  symbol: "SOL",
124
128
  decimals: 9,
125
129
  tokenAddress: NATIVE_TOKEN.SOL
130
+ },
131
+ {
132
+ id: import_intents_sdk.ChainID.MONAD,
133
+ name: "Monad",
134
+ isEVM: true,
135
+ wrapped: "0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A",
136
+ symbol: "MON",
137
+ decimals: 18,
138
+ tokenAddress: NATIVE_TOKEN.ETH
126
139
  }
127
140
  ];
141
+ var SupportedChains = SupportedChainsInternal.filter(
142
+ (c) => CURRENT_SUPPORTED.includes(c.id)
143
+ );
144
+ var isEvmChain = import_intents_sdk.isEvmChain;
128
145
 
129
146
  // src/utils/viem.ts
130
147
  function isViemWalletClient(wallet) {
@@ -152,9 +169,9 @@ function serializeBigIntsToStrings(obj) {
152
169
  return obj;
153
170
  }
154
171
 
155
- // src/core/executeOrder/normalizeNative.ts
172
+ // src/core/execute/normalizeNative.ts
156
173
  function normalizeNative(chainId, address) {
157
- if ((0, import_intents_sdk3.isEvmChain)(chainId) && isNativeAddress(address)) {
174
+ if ((0, import_intents_sdk2.isEvmChain)(chainId) && isNativeAddress(address)) {
158
175
  const chain = SupportedChains.find((c) => c.id === chainId);
159
176
  if (!chain?.wrapped)
160
177
  throw new Error(`Wrapped token not found for chainId ${chainId}`);
@@ -165,39 +182,72 @@ function normalizeNative(chainId, address) {
165
182
 
166
183
  // src/core/getQuote.ts
167
184
  async function getQuote(params) {
185
+ const amount = BigInt(params.amount);
168
186
  if (!params.tokenIn?.address || !params.tokenOut?.address) {
169
187
  throw new Error("Both tokenIn and tokenOut must include an address.");
170
188
  }
171
189
  if (!params.sourceChainId || !params.destChainId) {
172
190
  throw new Error("Both sourceChainId and destChainId are required.");
173
191
  }
174
- if (params.amount <= 0n) {
192
+ if (amount <= 0n) {
175
193
  throw new Error("Amount must be greater than 0.");
176
194
  }
177
- const normalizedTokenIn = normalizeNative(params.sourceChainId, params.tokenIn.address);
178
- const data = await import_intents_sdk4.QuoteProvider.getQuote({
179
- sourceChainId: params.sourceChainId,
180
- destChainId: params.destChainId,
181
- tokenIn: normalizedTokenIn,
182
- tokenOut: params.tokenOut.address,
183
- amount: params.amount
184
- });
185
- const inputSlippage = params.slippage ?? 5;
186
- const slippageDecimal = inputSlippage / 100;
187
- const slippage = Math.min(Math.max(slippageDecimal, 0), 0.5);
195
+ const slippagePercent = Math.min(Math.max(params.slippage ?? 0.5, 0), 50);
196
+ const slippageBps = BigInt(Math.round(slippagePercent * 100));
197
+ const applyUserSlippage = (value) => value * (10000n - slippageBps) / 10000n;
188
198
  let warning;
189
- if (slippage > 0.1) {
190
- warning = `\u26A0\uFE0F High slippage tolerance (${(slippage * 100).toFixed(2)}%) \u2014 price may vary significantly.`;
199
+ if (slippagePercent > 10) {
200
+ warning = `\u26A0\uFE0F High slippage tolerance (${slippagePercent.toFixed(2)}%) \u2014 price may vary significantly.`;
191
201
  }
192
- const estimatedAmountOut = BigInt(data.estimatedAmountOutReduced);
193
- const slippageBps = BigInt(Math.round(slippage * 1e4));
194
- const estimatedAmountOutAfterSlippage = estimatedAmountOut * (10000n - slippageBps) / 10000n;
195
- const pricePerInputToken = estimatedAmountOut * 10n ** BigInt(params.tokenIn.decimals ?? 18) / BigInt(params.amount);
202
+ const normalizedTokenIn = normalizeNative(params.sourceChainId, params.tokenIn.address);
203
+ const isSingleChain = params.sourceChainId === params.destChainId;
204
+ let data;
205
+ let netFloor;
206
+ let minStablecoinsAmount;
207
+ if (isSingleChain) {
208
+ const { quote, netAmountOut } = await import_intents_sdk3.QuoteProvider.getSingleChainNetQuote({
209
+ chainId: params.sourceChainId,
210
+ amount,
211
+ tokenIn: normalizedTokenIn,
212
+ tokenOut: params.tokenOut.address
213
+ });
214
+ netFloor = netAmountOut;
215
+ minStablecoinsAmount = 0n;
216
+ data = {
217
+ amountInUsd: quote.amountInUsd,
218
+ estimatedAmountInAsMinStablecoinAmount: 0n,
219
+ estimatedAmountOut: quote.amountOut,
220
+ estimatedAmountOutUsd: quote.amountOutUsd,
221
+ // filled in below once the user slippage buffer is known
222
+ estimatedAmountOutReduced: netAmountOut,
223
+ estimatedAmountOutUsdReduced: quote.amountOutUsd,
224
+ tokenIn: { address: params.tokenIn.address, chainId: params.sourceChainId },
225
+ tokenOut: { address: params.tokenOut.address, chainId: params.destChainId }
226
+ };
227
+ } else {
228
+ const crossChainQuote = await import_intents_sdk3.QuoteProvider.getCrossChainNetQuote({
229
+ sourceChainId: params.sourceChainId,
230
+ destChainId: params.destChainId,
231
+ tokenIn: normalizedTokenIn,
232
+ tokenOut: params.tokenOut.address,
233
+ amount
234
+ });
235
+ data = crossChainQuote;
236
+ netFloor = BigInt(crossChainQuote.estimatedAmountOutReduced);
237
+ minStablecoinsAmount = applyUserSlippage(
238
+ BigInt(crossChainQuote.estimatedAmountInAsMinStablecoinAmount)
239
+ );
240
+ }
241
+ const amountOut = applyUserSlippage(netFloor);
242
+ const grossAmountOut = BigInt(data.estimatedAmountOut);
243
+ const pricePerTokenOutInUsd = grossAmountOut > 0n ? data.estimatedAmountOutUsd / Number(grossAmountOut) : 0;
244
+ const amountOutUsd = Number(amountOut) * pricePerTokenOutInUsd;
245
+ const pricePerInputToken = grossAmountOut * 10n ** BigInt(params.tokenIn.decimals ?? 18) / amount;
196
246
  return {
197
- amountOut: estimatedAmountOut,
198
- amountOutUsd: data.estimatedAmountOutUsd,
247
+ amountOut,
248
+ amountOutUsd,
199
249
  amountInUsd: data.amountInUsd,
200
- minStablecoinsAmount: data.estimatedAmountInAsMinStablecoinAmount,
250
+ minStablecoinsAmount,
201
251
  tokenIn: {
202
252
  address: params.tokenIn.address,
203
253
  decimals: params.tokenIn.decimals ?? 18,
@@ -208,12 +258,13 @@ async function getQuote(params) {
208
258
  decimals: params.tokenOut.decimals ?? 18,
209
259
  chainId: params.destChainId
210
260
  },
211
- amountIn: params.amount,
261
+ amountIn: amount,
212
262
  pricePerInputToken,
213
- slippage,
263
+ slippage: slippagePercent,
214
264
  internal: {
215
265
  ...data,
216
- estimatedAmountOutReduced: estimatedAmountOutAfterSlippage
266
+ estimatedAmountOutReduced: amountOut,
267
+ estimatedAmountOutUsdReduced: amountOutUsd
217
268
  },
218
269
  warning
219
270
  };
@@ -231,13 +282,13 @@ function buildQuoteParams({
231
282
  tokenOut,
232
283
  sourceChainId,
233
284
  destChainId,
234
- amount: (0, import_viem.parseUnits)(amount.toString(), tokenIn.decimals ?? 18),
285
+ amount: (0, import_viem2.parseUnits)(amount.toString(), tokenIn.decimals ?? 18).toString(),
235
286
  slippage
236
287
  };
237
288
  }
238
289
 
239
290
  // src/core/getBalances.ts
240
- var import_intents_sdk5 = require("@shogun-sdk/intents-sdk");
291
+ var import_intents_sdk4 = require("@shogun-sdk/intents-sdk");
241
292
  async function getBalances(params, options) {
242
293
  const { addresses, cursorEvm, cursorSvm } = params;
243
294
  const { signal } = options ?? {};
@@ -250,7 +301,7 @@ async function getBalances(params, options) {
250
301
  cursorSvm
251
302
  });
252
303
  const start = performance.now();
253
- const response = await fetch(`${import_intents_sdk5.TOKEN_SEARCH_API_BASE_URL}/tokens/balances`, {
304
+ const response = await fetch(`${import_intents_sdk4.TOKEN_SEARCH_API_BASE_URL}/tokens/balances`, {
254
305
  method: "POST",
255
306
  headers: {
256
307
  accept: "application/json",
@@ -278,103 +329,70 @@ async function getBalances(params, options) {
278
329
  const evmItems = data.evm?.items ?? [];
279
330
  const svmItems = data.svm?.items ?? [];
280
331
  const combined = [...evmItems, ...svmItems];
332
+ const filtered = combined.filter(
333
+ (b) => CURRENT_SUPPORTED.includes(b.chainId)
334
+ );
281
335
  return {
282
- results: combined,
336
+ results: filtered,
283
337
  nextCursorEvm: data.evm?.cursor ?? null,
284
338
  nextCursorSvm: data.svm?.cursor ?? null
285
339
  };
286
340
  }
287
341
 
288
- // src/core/executeOrder/execute.ts
289
- var import_intents_sdk9 = require("@shogun-sdk/intents-sdk");
290
- var import_viem4 = require("viem");
291
-
292
- // src/wallet-adapter/svm-wallet-adapter/adapter.ts
293
- var import_web3 = require("@solana/web3.js");
294
- var adaptSolanaWallet = (walletAddress, chainId, rpcUrl, signAndSendTransaction) => {
295
- let _chainId = chainId;
296
- const connection = new import_web3.Connection(rpcUrl, { commitment: "confirmed" });
297
- const getChainId = async () => _chainId;
298
- const sendTransaction = async (transaction) => {
299
- const txHash = await signAndSendTransaction(transaction);
300
- console.log(`\u{1F6F0} Sent transaction: ${txHash}`);
301
- const maxRetries = 20;
302
- const delayMs = 2e3;
303
- for (let attempt = 0; attempt < maxRetries; attempt++) {
304
- const res = await connection.getSignatureStatus(txHash, { searchTransactionHistory: true });
305
- if (res?.value?.confirmationStatus === "confirmed" || res?.value?.confirmationStatus === "finalized") {
306
- return txHash;
307
- }
308
- await new Promise((resolve) => setTimeout(resolve, delayMs));
309
- }
310
- throw new Error(`Transaction not confirmed after ${maxRetries * (delayMs / 1e3)}s`);
311
- };
312
- const signTypedData = async () => {
313
- throw new Error("signTypedData not implemented for Solana");
314
- };
315
- const switchChain = async (newChainId) => {
316
- _chainId = newChainId;
317
- };
342
+ // src/core/token-list.ts
343
+ var import_intents_sdk5 = require("@shogun-sdk/intents-sdk");
344
+ async function getTokenList(params) {
345
+ const url = new URL(`${import_intents_sdk5.TOKEN_SEARCH_API_BASE_URL}/tokens/search`);
346
+ if (params.q) url.searchParams.append("q", params.q);
347
+ if (params.networkId) url.searchParams.append("networkId", String(params.networkId));
348
+ if (params.page) url.searchParams.append("page", String(params.page));
349
+ if (params.limit) url.searchParams.append("limit", String(params.limit));
350
+ const res = await fetch(url.toString(), {
351
+ signal: params.signal
352
+ });
353
+ if (!res.ok) {
354
+ throw new Error(`Failed to fetch tokens: ${res.status} ${res.statusText}`);
355
+ }
356
+ const data = await res.json();
357
+ const filteredResults = data.results.filter(
358
+ (token) => CURRENT_SUPPORTED.includes(token.chainId)
359
+ );
318
360
  return {
319
- vmType: "SVM" /* SVM */,
320
- getChainId,
321
- address: async () => walletAddress,
322
- sendTransaction,
323
- switchChain,
324
- signTypedData,
325
- rpcUrl
361
+ ...data,
362
+ results: filteredResults,
363
+ count: filteredResults.length
326
364
  };
327
- };
365
+ }
366
+
367
+ // src/core/token.ts
368
+ var import_intents_sdk6 = require("@shogun-sdk/intents-sdk");
369
+ async function getTokensData(addresses) {
370
+ if (!addresses?.length) return [];
371
+ const response = await fetch(`${import_intents_sdk6.TOKEN_SEARCH_API_BASE_URL}/tokens/tokens`, {
372
+ method: "POST",
373
+ headers: {
374
+ "Content-Type": "application/json",
375
+ accept: "*/*"
376
+ },
377
+ body: JSON.stringify({ addresses })
378
+ });
379
+ if (!response.ok) {
380
+ throw new Error(`Failed to fetch token data: ${response.statusText}`);
381
+ }
382
+ const data = await response.json();
383
+ const filtered = data.filter((t) => CURRENT_SUPPORTED.includes(Number(t.chainId)));
384
+ return filtered;
385
+ }
386
+
387
+ // src/core/execute/execute.ts
388
+ var import_intents_sdk12 = require("@shogun-sdk/intents-sdk");
389
+ var import_viem7 = require("viem");
328
390
 
329
391
  // src/wallet-adapter/evm-wallet-adapter/adapter.ts
330
- var import_ethers = require("ethers/lib/ethers.js");
331
- var import_utils2 = require("ethers/lib/utils.js");
332
- var import_viem2 = require("viem");
392
+ var import_viem3 = require("viem");
333
393
  function isEVMTransaction(tx) {
334
394
  return typeof tx.from === "string";
335
395
  }
336
- var adaptEthersSigner = (signer, transport) => {
337
- const signTypedData = async (signData) => {
338
- const typedSigner = signer;
339
- return await typedSigner._signTypedData(
340
- signData.domain,
341
- signData.types,
342
- signData.value
343
- );
344
- };
345
- const sendTransaction = async (transaction) => {
346
- if (!isEVMTransaction(transaction)) {
347
- throw new Error("Expected EVMTransaction but got SolanaTransaction");
348
- }
349
- const tx = await signer.sendTransaction({
350
- from: transaction.from,
351
- to: transaction.to,
352
- data: transaction.data,
353
- value: transaction.value
354
- });
355
- return tx.hash;
356
- };
357
- const switchChain = async (chainId) => {
358
- try {
359
- await window.ethereum.request({
360
- method: "wallet_switchEthereumChain",
361
- params: [{ chainId: (0, import_utils2.hexValue)(chainId) }]
362
- });
363
- } catch (error) {
364
- console.error("Failed to switch chain:", error);
365
- throw error;
366
- }
367
- };
368
- return {
369
- vmType: "EVM" /* EVM */,
370
- transport,
371
- getChainId: async () => signer.getChainId(),
372
- address: async () => signer.getAddress(),
373
- sendTransaction,
374
- signTypedData,
375
- switchChain
376
- };
377
- };
378
396
  var adaptViemWallet = (wallet) => {
379
397
  const signTypedData = async (signData) => {
380
398
  return await wallet.signTypedData({
@@ -389,15 +407,26 @@ var adaptViemWallet = (wallet) => {
389
407
  if (!isEVMTransaction(transaction)) {
390
408
  throw new Error("Expected EVMTransaction but got SolanaTransaction");
391
409
  }
392
- const tx = await wallet.sendTransaction({
393
- from: transaction.from,
394
- to: transaction.to,
395
- data: transaction.data,
396
- value: transaction.value,
397
- account: wallet.account?.address,
398
- chain: wallet.chain
399
- });
400
- return tx;
410
+ if (wallet.transport.type === "http") {
411
+ const request = await wallet.prepareTransactionRequest({
412
+ to: transaction.to,
413
+ data: transaction.data,
414
+ value: transaction.value,
415
+ chain: wallet.chain
416
+ });
417
+ const serializedTransaction = await wallet.signTransaction(request);
418
+ const tx = await wallet.sendRawTransaction({ serializedTransaction });
419
+ return tx;
420
+ } else {
421
+ const hash = await wallet.sendTransaction({
422
+ to: transaction.to,
423
+ data: transaction.data,
424
+ value: transaction.value,
425
+ chain: wallet.chain,
426
+ account: wallet.account
427
+ });
428
+ return hash;
429
+ }
401
430
  };
402
431
  const switchChain = async (chainId) => {
403
432
  try {
@@ -420,55 +449,96 @@ var adaptViemWallet = (wallet) => {
420
449
  if (!addr) throw new Error("No address found");
421
450
  return addr;
422
451
  };
452
+ const readContract = async ({
453
+ address: address2,
454
+ abi,
455
+ functionName,
456
+ args = []
457
+ }) => {
458
+ const publicClient = wallet.extend(import_viem3.publicActions);
459
+ return await publicClient.readContract({
460
+ address: address2,
461
+ abi,
462
+ functionName,
463
+ args
464
+ });
465
+ };
423
466
  return {
424
467
  vmType: "EVM" /* EVM */,
425
- transport: (0, import_viem2.custom)(wallet.transport),
468
+ transport: (0, import_viem3.custom)(wallet.transport),
426
469
  getChainId: async () => wallet.getChainId(),
427
470
  address,
428
471
  sendTransaction,
429
472
  signTypedData,
430
- switchChain
473
+ switchChain,
474
+ readContract
431
475
  };
432
476
  };
433
477
 
434
- // src/core/executeOrder/handleEvmExecution.ts
435
- var import_intents_sdk7 = require("@shogun-sdk/intents-sdk");
436
- var import_viem3 = require("viem");
478
+ // src/core/execute/handleEvmExecution.ts
479
+ var import_intents_sdk10 = require("@shogun-sdk/intents-sdk");
480
+ var import_viem6 = require("viem");
437
481
 
438
- // src/core/executeOrder/stageMessages.ts
482
+ // src/core/execute/stageMessages.ts
439
483
  var DEFAULT_STAGE_MESSAGES = {
440
484
  processing: "Preparing transaction for execution",
441
485
  approving: "Approving token allowance",
442
486
  approved: "Token approved successfully",
443
- signing: "Signing order for submission",
444
- submitting: "Submitting order to Auctioneer",
445
- success: "Order executed successfully",
446
- error: "Order execution failed"
487
+ signing: "Signing transaction for submission",
488
+ submitting: "Submitting transaction",
489
+ initiated: "Transaction initiated.",
490
+ success: "Transaction Executed successfully",
491
+ success_limit: "Limit order has been submitted successfully.",
492
+ shogun_processing: "Shogun is processing your transaction",
493
+ error: "Transaction failed during submission"
447
494
  };
448
495
 
449
- // src/core/executeOrder/buildOrder.ts
450
- var import_intents_sdk6 = require("@shogun-sdk/intents-sdk");
496
+ // src/core/execute/buildOrder.ts
497
+ var import_intents_sdk7 = require("@shogun-sdk/intents-sdk");
498
+ var import_viem4 = require("viem");
499
+
500
+ // src/utils/order.ts
501
+ var OrderExecutionType = /* @__PURE__ */ ((OrderExecutionType2) => {
502
+ OrderExecutionType2["LIMIT"] = "limit";
503
+ OrderExecutionType2["MARKET"] = "market";
504
+ return OrderExecutionType2;
505
+ })(OrderExecutionType || {});
506
+
507
+ // src/core/execute/buildOrder.ts
451
508
  async function buildOrder({
452
509
  quote,
453
510
  accountAddress,
454
511
  destination,
455
512
  deadline,
456
- isSingleChain
513
+ isSingleChain,
514
+ orderType,
515
+ options
457
516
  }) {
458
517
  const { tokenIn, tokenOut } = quote;
518
+ let amountOutMin = BigInt(quote.internal.estimatedAmountOutReduced);
519
+ if (orderType === "limit" /* LIMIT */ && options && "executionPrice" in options) {
520
+ const executionPrice = Number(options.executionPrice);
521
+ if (Number.isFinite(executionPrice) && executionPrice > 0) {
522
+ const decimalsIn = tokenIn.decimals ?? 18;
523
+ const decimalsOut = tokenOut.decimals ?? 18;
524
+ const formattedAmountIn = Number((0, import_viem4.formatUnits)(BigInt(quote.amountIn.toString()), decimalsIn));
525
+ const rawAmountOut = formattedAmountIn * executionPrice;
526
+ amountOutMin = (0, import_viem4.parseUnits)(rawAmountOut.toString(), decimalsOut);
527
+ }
528
+ }
459
529
  if (isSingleChain) {
460
- return await import_intents_sdk6.SingleChainOrder.create({
530
+ return await import_intents_sdk7.SingleChainOrder.create({
461
531
  user: accountAddress,
462
532
  chainId: tokenIn.chainId,
463
533
  tokenIn: tokenIn.address,
464
534
  tokenOut: tokenOut.address,
465
535
  amountIn: quote.amountIn,
466
- amountOutMin: quote.internal.estimatedAmountOutReduced,
536
+ amountOutMin,
467
537
  deadline,
468
538
  destinationAddress: destination
469
539
  });
470
540
  }
471
- return await import_intents_sdk6.CrossChainOrder.create({
541
+ return await import_intents_sdk7.CrossChainOrder.create({
472
542
  user: accountAddress,
473
543
  sourceChainId: tokenIn.chainId,
474
544
  sourceTokenAddress: tokenIn.address,
@@ -477,12 +547,166 @@ async function buildOrder({
477
547
  destinationTokenAddress: tokenOut.address,
478
548
  destinationAddress: destination,
479
549
  deadline,
480
- destinationTokenMinAmount: quote.internal.estimatedAmountOutReduced,
550
+ destinationTokenMinAmount: amountOutMin,
481
551
  minStablecoinAmount: quote.minStablecoinsAmount
482
552
  });
483
553
  }
484
554
 
485
- // src/core/executeOrder/handleEvmExecution.ts
555
+ // src/utils/pollOrderStatus.ts
556
+ var import_intents_sdk8 = require("@shogun-sdk/intents-sdk");
557
+ async function pollOrderStatus(address, orderId, options = {}) {
558
+ const { intervalMs = 2e3, timeoutMs = 3e5, authToken } = options;
559
+ const startTime = Date.now();
560
+ const isDebug = process.env.NODE_ENV !== "production";
561
+ const isEvmAddress = /^0x[a-fA-F0-9]{40}$/.test(address);
562
+ const isSuiAddress = /^0x[a-fA-F0-9]{64}$/.test(address);
563
+ const isSolanaAddress = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
564
+ let queryParam;
565
+ if (isEvmAddress) queryParam = `evmWallets=${address}`;
566
+ else if (isSuiAddress) queryParam = `suiWallets=${address}`;
567
+ else if (isSolanaAddress) queryParam = `solanaWallets=${address}`;
568
+ else throw new Error(`Unrecognized wallet address format: ${address}`);
569
+ const queryUrl = `${import_intents_sdk8.AUCTIONEER_URL}/user_intent?${queryParam}`;
570
+ return new Promise((resolve, reject) => {
571
+ const pollInterval = setInterval(async () => {
572
+ try {
573
+ if (Date.now() - startTime > timeoutMs) {
574
+ clearInterval(pollInterval);
575
+ return resolve("Timeout");
576
+ }
577
+ const res = await fetch(queryUrl, {
578
+ method: "GET",
579
+ headers: {
580
+ "Content-Type": "application/json",
581
+ // The /user_intent status endpoint requires the SIWE JWT; without it
582
+ // the request 401s after the order has already been submitted.
583
+ ...authToken ? { Authorization: `Bearer ${authToken}` } : {}
584
+ }
585
+ });
586
+ if (!res.ok) {
587
+ clearInterval(pollInterval);
588
+ return reject(
589
+ new Error(`Failed to fetch orders: ${res.status} ${res.statusText}`)
590
+ );
591
+ }
592
+ const json = await res.json();
593
+ const data = json?.data ?? {};
594
+ const allOrders = [
595
+ ...data.crossChainDcaOrders ?? [],
596
+ ...data.crossChainLimitOrders ?? [],
597
+ ...data.singleChainDcaOrders ?? [],
598
+ ...data.singleChainLimitOrders ?? []
599
+ ];
600
+ const targetOrder = allOrders.find((o) => o.orderId === orderId);
601
+ if (!targetOrder) {
602
+ if (isDebug)
603
+ console.debug(`[pollOrderStatus] [${orderId}] Not found yet`);
604
+ return;
605
+ }
606
+ const { orderStatus } = targetOrder;
607
+ if (isDebug) {
608
+ const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
609
+ console.debug(`targetOrder`, targetOrder);
610
+ console.debug(
611
+ `[pollOrderStatus] [${orderId}] status=${orderStatus} (elapsed ${elapsed}s)`
612
+ );
613
+ }
614
+ if (["Fulfilled", "Cancelled", "Outdated"].includes(orderStatus)) {
615
+ clearInterval(pollInterval);
616
+ return resolve(orderStatus);
617
+ }
618
+ } catch (error) {
619
+ clearInterval(pollInterval);
620
+ return reject(error);
621
+ }
622
+ }, intervalMs);
623
+ });
624
+ }
625
+
626
+ // src/core/execute/handleOrderPollingResult.ts
627
+ async function handleOrderPollingResult({
628
+ status,
629
+ orderId,
630
+ chainId,
631
+ update,
632
+ messageFor
633
+ }) {
634
+ switch (status) {
635
+ case "Fulfilled":
636
+ update("success", messageFor("success"));
637
+ return {
638
+ status: true,
639
+ orderId,
640
+ chainId,
641
+ finalStatus: status,
642
+ stage: "success"
643
+ };
644
+ case "Cancelled":
645
+ update("error", "Order was cancelled before fulfillment");
646
+ break;
647
+ case "Timeout":
648
+ update("error", "Order polling timed out");
649
+ break;
650
+ case "NotFound":
651
+ default:
652
+ update("error", "Order not found");
653
+ break;
654
+ }
655
+ return {
656
+ status: false,
657
+ orderId,
658
+ chainId,
659
+ finalStatus: status,
660
+ stage: "error"
661
+ };
662
+ }
663
+
664
+ // src/core/execute/ensurePermit2Allowance.ts
665
+ var import_viem5 = require("viem");
666
+ var import_intents_sdk9 = require("@shogun-sdk/intents-sdk");
667
+ async function ensurePermit2Allowance({
668
+ chainId,
669
+ tokenIn,
670
+ wallet,
671
+ accountAddress,
672
+ requiredAmount,
673
+ increaseByDelta = false
674
+ }) {
675
+ const spender = import_intents_sdk9.PERMIT2_ADDRESS[chainId];
676
+ let currentAllowance = 0n;
677
+ try {
678
+ if (!wallet.readContract) {
679
+ throw new Error("Wallet does not implement readContract()");
680
+ }
681
+ currentAllowance = await wallet.readContract({
682
+ address: tokenIn,
683
+ abi: import_viem5.erc20Abi,
684
+ functionName: "allowance",
685
+ args: [accountAddress, spender]
686
+ });
687
+ } catch (error) {
688
+ console.warn(`[Permit2] Failed to read allowance for ${tokenIn}`, error);
689
+ }
690
+ const approvalAmount = increaseByDelta ? currentAllowance + requiredAmount : import_viem5.maxUint256;
691
+ console.debug(
692
+ `[Permit2] Approving ${approvalAmount} for ${tokenIn} (current: ${currentAllowance}, required: ${requiredAmount})`
693
+ );
694
+ await wallet.sendTransaction({
695
+ to: tokenIn,
696
+ from: accountAddress,
697
+ data: (0, import_viem5.encodeFunctionData)({
698
+ abi: import_viem5.erc20Abi,
699
+ functionName: "approve",
700
+ args: [spender, approvalAmount]
701
+ }),
702
+ value: 0n
703
+ });
704
+ console.info(
705
+ `[Permit2] Approval transaction sent for ${tokenIn} on chain ${chainId}`
706
+ );
707
+ }
708
+
709
+ // src/core/execute/handleEvmExecution.ts
486
710
  async function handleEvmExecution({
487
711
  recipientAddress,
488
712
  quote,
@@ -490,18 +714,22 @@ async function handleEvmExecution({
490
714
  accountAddress,
491
715
  wallet,
492
716
  isSingleChain,
493
- deadline,
494
- update
717
+ update,
718
+ orderType,
719
+ options
495
720
  }) {
496
- const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
721
+ const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage] ?? "";
722
+ const deadline = options?.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
497
723
  await wallet.switchChain(chainId);
498
724
  const tokenIn = normalizeNative(chainId, quote.tokenIn.address);
725
+ quote.tokenOut.address = normalizeEvmTokenAddress(quote.tokenOut.address);
499
726
  const shouldWrapNative = isNativeAddress(quote.tokenIn.address);
500
727
  update("processing", shouldWrapNative ? `${messageFor("processing")} (wrapping native token)` : messageFor("processing"));
501
728
  if (shouldWrapNative) {
729
+ quote.tokenIn.address === tokenIn;
502
730
  await wallet.sendTransaction({
503
731
  to: tokenIn,
504
- data: (0, import_viem3.encodeFunctionData)({
732
+ data: (0, import_viem6.encodeFunctionData)({
505
733
  abi: [{ type: "function", name: "deposit", stateMutability: "payable", inputs: [], outputs: [] }],
506
734
  functionName: "deposit",
507
735
  args: []
@@ -510,44 +738,71 @@ async function handleEvmExecution({
510
738
  from: accountAddress
511
739
  });
512
740
  }
513
- update("approving", messageFor("approving"));
514
- await wallet.sendTransaction({
515
- to: tokenIn,
516
- data: (0, import_viem3.encodeFunctionData)({
517
- abi: import_viem3.erc20Abi,
518
- functionName: "approve",
519
- args: [import_intents_sdk7.PERMIT2_ADDRESS[chainId], BigInt(quote.amountIn)]
520
- }),
521
- value: 0n,
522
- from: accountAddress
741
+ update("processing", messageFor("approving"));
742
+ await ensurePermit2Allowance({
743
+ chainId,
744
+ tokenIn,
745
+ wallet,
746
+ accountAddress,
747
+ requiredAmount: BigInt(quote.amountIn)
523
748
  });
524
- update("approved", messageFor("approved"));
749
+ update("processing", messageFor("approved"));
525
750
  const destination = recipientAddress ?? accountAddress;
526
751
  const order = await buildOrder({
527
752
  quote,
528
753
  accountAddress,
529
754
  destination,
530
755
  deadline,
531
- isSingleChain
756
+ isSingleChain,
757
+ orderType,
758
+ options
532
759
  });
533
- update("signing", messageFor("signing"));
534
- const { orderTypedData, nonce } = isSingleChain ? await (0, import_intents_sdk7.getEVMSingleChainOrderTypedData)(order) : await (0, import_intents_sdk7.getEVMCrossChainOrderTypedData)(order);
760
+ console.debug(`order`, order);
761
+ update("processing", messageFor("signing"));
762
+ const { orderTypedData, nonce } = isSingleChain ? await (0, import_intents_sdk10.getEVMSingleChainOrderTypedData)(order) : await (0, import_intents_sdk10.getEVMCrossChainOrderTypedData)(order);
763
+ const typedData = serializeBigIntsToStrings(orderTypedData);
535
764
  if (!wallet.signTypedData) {
536
765
  throw new Error("Wallet does not support EIP-712 signing");
537
766
  }
538
- const signature = await wallet.signTypedData(serializeBigIntsToStrings(orderTypedData));
539
- update("submitting", messageFor("submitting"));
767
+ const signature = await wallet.signTypedData({
768
+ domain: typedData.domain,
769
+ types: typedData.types,
770
+ primaryType: typedData.primaryType,
771
+ value: typedData.message,
772
+ message: typedData.message
773
+ });
774
+ update("processing", messageFor("submitting"));
540
775
  const res = await order.sendToAuctioneer({ signature, nonce: nonce.toString() });
541
776
  if (!res.success) {
542
777
  throw new Error("Auctioneer submission failed");
543
778
  }
544
- update("success", messageFor("success"));
545
- return { status: true, txHash: res.data, chainId, stage: "success" };
779
+ update("initiated", messageFor("initiated"));
780
+ const { intentId: orderId } = res.data;
781
+ update("initiated", messageFor("shogun_processing"));
782
+ if (orderType === "limit" /* LIMIT */) {
783
+ update("success", messageFor("success_limit"));
784
+ return {
785
+ status: true,
786
+ orderId,
787
+ chainId,
788
+ finalStatus: "OrderPlaced",
789
+ stage: "success"
790
+ };
791
+ } else {
792
+ const status = await pollOrderStatus(accountAddress, orderId, { authToken: options?.authToken });
793
+ return await handleOrderPollingResult({
794
+ status,
795
+ orderId,
796
+ chainId,
797
+ update,
798
+ messageFor
799
+ });
800
+ }
546
801
  }
547
802
 
548
- // src/core/executeOrder/handleSolanaExecution.ts
549
- var import_intents_sdk8 = require("@shogun-sdk/intents-sdk");
550
- var import_web32 = require("@solana/web3.js");
803
+ // src/core/execute/handleSolanaExecution.ts
804
+ var import_intents_sdk11 = require("@shogun-sdk/intents-sdk");
805
+ var import_web3 = require("@solana/web3.js");
551
806
  async function handleSolanaExecution({
552
807
  recipientAddress,
553
808
  quote,
@@ -555,12 +810,14 @@ async function handleSolanaExecution({
555
810
  isSingleChain,
556
811
  update,
557
812
  accountAddress,
558
- deadline
813
+ orderType,
814
+ options
559
815
  }) {
560
816
  if (!wallet.rpcUrl) {
561
817
  throw new Error("Solana wallet is missing rpcUrl");
562
818
  }
563
- const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
819
+ const deadline = options?.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
820
+ const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage] ?? "";
564
821
  update("processing", messageFor("processing"));
565
822
  const destination = recipientAddress ?? accountAddress;
566
823
  const order = await buildOrder({
@@ -568,18 +825,19 @@ async function handleSolanaExecution({
568
825
  accountAddress,
569
826
  destination,
570
827
  deadline,
571
- isSingleChain
828
+ isSingleChain,
829
+ orderType,
830
+ options
572
831
  });
573
832
  const txData = await getSolanaOrderInstructions({
574
833
  order,
575
834
  isSingleChain,
576
835
  rpcUrl: wallet.rpcUrl
577
836
  });
578
- const transaction = import_web32.VersionedTransaction.deserialize(Uint8Array.from(txData.txBytes));
579
- update("signing", messageFor("signing"));
580
- console.log({ order });
581
- const txSignature = await wallet.sendTransaction(transaction);
582
- update("submitting", messageFor("submitting"));
837
+ const transaction = import_web3.VersionedTransaction.deserialize(Uint8Array.from(txData.txBytes));
838
+ update("processing", messageFor("signing"));
839
+ await wallet.sendTransaction(transaction);
840
+ update("processing", messageFor("submitting"));
583
841
  const response = await submitToAuctioneer({
584
842
  order,
585
843
  isSingleChain,
@@ -588,13 +846,28 @@ async function handleSolanaExecution({
588
846
  if (!response.success) {
589
847
  throw new Error("Auctioneer submission failed");
590
848
  }
591
- update("success", messageFor("success"));
592
- return {
593
- status: true,
594
- txHash: txSignature,
595
- chainId: import_intents_sdk8.ChainID.Solana,
596
- stage: "success"
597
- };
849
+ update("initiated", messageFor("initiated"));
850
+ const { intentId: orderId } = response.data;
851
+ update("initiated", messageFor("shogun_processing"));
852
+ if (orderType === "limit" /* LIMIT */) {
853
+ update("success", messageFor("success_limit"));
854
+ return {
855
+ status: true,
856
+ orderId,
857
+ chainId: SOLANA_CHAIN_ID,
858
+ finalStatus: "OrderPlaced",
859
+ stage: "success"
860
+ };
861
+ } else {
862
+ const status = await pollOrderStatus(accountAddress, orderId, { authToken: options?.authToken });
863
+ return await handleOrderPollingResult({
864
+ status,
865
+ orderId,
866
+ chainId: SOLANA_CHAIN_ID,
867
+ update,
868
+ messageFor
869
+ });
870
+ }
598
871
  }
599
872
  async function getSolanaOrderInstructions({
600
873
  order,
@@ -602,11 +875,11 @@ async function getSolanaOrderInstructions({
602
875
  rpcUrl
603
876
  }) {
604
877
  if (isSingleChain) {
605
- return await (0, import_intents_sdk8.getSolanaSingleChainOrderInstructions)(order, {
878
+ return await (0, import_intents_sdk11.getSolanaSingleChainOrderInstructions)(order, {
606
879
  rpcUrl
607
880
  });
608
881
  }
609
- return await (0, import_intents_sdk8.getSolanaCrossChainOrderInstructions)(order, {
882
+ return await (0, import_intents_sdk11.getSolanaCrossChainOrderInstructions)(order, {
610
883
  rpcUrl
611
884
  });
612
885
  }
@@ -627,52 +900,93 @@ async function submitToAuctioneer({
627
900
  });
628
901
  }
629
902
 
630
- // src/core/executeOrder/execute.ts
903
+ // src/core/execute/execute.ts
631
904
  async function executeOrder({
632
905
  quote,
633
906
  accountAddress,
634
907
  recipientAddress,
635
908
  wallet,
636
909
  onStatus,
910
+ orderType = "market" /* MARKET */,
637
911
  options = {}
638
912
  }) {
639
- const deadline = options.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
913
+ const isDev = process.env.NODE_ENV !== "production";
914
+ const log = (...args) => {
915
+ if (isDev) console.debug("[OneShot::executeOrder]", ...args);
916
+ };
640
917
  const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
641
- const update = (stage, message) => onStatus?.(stage, message ?? messageFor(stage));
918
+ const update = (stage, message) => {
919
+ log("Stage:", stage, "| Message:", message ?? messageFor(stage));
920
+ onStatus?.(stage, message ?? messageFor(stage));
921
+ };
642
922
  try {
923
+ log("Starting execution:", {
924
+ accountAddress,
925
+ recipientAddress,
926
+ tokenIn: quote?.tokenIn,
927
+ tokenOut: quote?.tokenOut
928
+ });
643
929
  const adapter = normalizeWallet(wallet);
644
930
  if (!adapter) throw new Error("No wallet provided");
645
931
  const { tokenIn, tokenOut } = quote;
932
+ const srcChain = Number(tokenIn.chainId);
933
+ const destChain = Number(tokenOut.chainId);
934
+ if (!CURRENT_SUPPORTED.includes(srcChain) || !CURRENT_SUPPORTED.includes(destChain)) {
935
+ const unsupportedChains = [
936
+ !CURRENT_SUPPORTED.includes(srcChain) ? srcChain : null,
937
+ !CURRENT_SUPPORTED.includes(destChain) ? destChain : null
938
+ ].filter(Boolean).join(", ");
939
+ const errorMsg = `Unsupported chain(s): ${unsupportedChains}`;
940
+ update("error", errorMsg);
941
+ log("Error:", errorMsg);
942
+ throw new Error(errorMsg);
943
+ }
646
944
  const isSingleChain = tokenIn.chainId === tokenOut.chainId;
647
945
  const chainId = Number(tokenIn.chainId);
648
- update("processing", messageFor("processing"));
649
- if ((0, import_intents_sdk9.isEvmChain)(chainId)) {
650
- return await handleEvmExecution({
946
+ update("processing");
947
+ if ((0, import_intents_sdk12.isEvmChain)(chainId)) {
948
+ log("Detected EVM chain:", chainId);
949
+ const result = await handleEvmExecution({
651
950
  recipientAddress,
652
951
  quote,
653
952
  chainId,
654
953
  accountAddress,
655
954
  wallet: adapter,
656
955
  isSingleChain,
657
- deadline,
658
- update
956
+ update,
957
+ orderType,
958
+ options
659
959
  });
960
+ log("EVM execution result:", result);
961
+ return result;
660
962
  }
661
- if (chainId === import_intents_sdk9.ChainID.Solana) {
662
- return await handleSolanaExecution({
963
+ if (chainId === import_intents_sdk12.ChainID.Solana) {
964
+ log("Detected Solana chain");
965
+ const result = await handleSolanaExecution({
663
966
  recipientAddress,
664
967
  quote,
665
968
  accountAddress,
666
969
  wallet: adapter,
667
970
  isSingleChain,
668
- deadline,
669
- update
971
+ update,
972
+ orderType,
973
+ options
670
974
  });
975
+ log("Solana execution result:", result);
976
+ return result;
671
977
  }
672
- update("error", "Unsupported chain");
673
- return { status: false, message: "Unsupported chain", stage: "error" };
978
+ const unsupported = `Unsupported chain: ${chainId}`;
979
+ update("error", unsupported);
980
+ log("Error:", unsupported);
981
+ return { status: false, message: unsupported, stage: "error" };
674
982
  } catch (error) {
675
- const message = error instanceof import_viem4.BaseError ? error.shortMessage : error instanceof Error ? error.message : String(error);
983
+ let message = "An unknown error occurred";
984
+ if (error && typeof error === "object") {
985
+ const err = error;
986
+ message = err.details ?? err.message ?? message;
987
+ } else if (typeof error === "string") {
988
+ message = error;
989
+ }
676
990
  update("error", message);
677
991
  return { status: false, message, stage: "error" };
678
992
  }
@@ -683,319 +997,508 @@ function normalizeWallet(wallet) {
683
997
  return wallet;
684
998
  }
685
999
 
686
- // src/react/useTokenList.ts
687
- var import_react = require("react");
688
- var tokenCache = /* @__PURE__ */ new Map();
689
- function useTokenList(params) {
690
- const [data, setData] = (0, import_react.useState)(null);
691
- const [loading, setLoading] = (0, import_react.useState)(false);
692
- const [error, setError] = (0, import_react.useState)(null);
693
- const controllerRef = (0, import_react.useRef)(null);
694
- const debounceRef = (0, import_react.useRef)(null);
695
- const debounceMs = params.debounceMs ?? 250;
696
- const cacheKey = (0, import_react.useMemo)(() => {
697
- return JSON.stringify({
698
- q: params.q?.trim().toLowerCase() ?? "",
699
- networkId: params.networkId ?? "all",
700
- page: params.page ?? 1,
701
- limit: params.limit ?? 50
702
- });
703
- }, [params.q, params.networkId, params.page, params.limit]);
704
- async function fetchTokens(signal) {
705
- if (tokenCache.has(cacheKey)) {
706
- setData(tokenCache.get(cacheKey));
707
- setLoading(false);
708
- setError(null);
709
- return;
710
- }
711
- try {
712
- setLoading(true);
713
- const result = await getTokenList({ ...params, signal });
714
- tokenCache.set(cacheKey, result);
715
- setData(result);
716
- setError(null);
717
- } catch (err) {
718
- if (err.name !== "AbortError") {
719
- const e = err instanceof Error ? err : new Error("Unknown error while fetching tokens");
720
- setError(e);
721
- }
722
- } finally {
723
- setLoading(false);
724
- }
1000
+ // src/core/orders/getOrders.ts
1001
+ var import_intents_sdk13 = require("@shogun-sdk/intents-sdk");
1002
+ async function getOrders({
1003
+ evmAddress,
1004
+ solAddress
1005
+ }) {
1006
+ const wallets = [evmAddress, solAddress].filter(
1007
+ (wallet) => Boolean(wallet)
1008
+ );
1009
+ if (wallets.length === 0) {
1010
+ throw new Error("At least one wallet address (EVM, Solana) must be provided.");
725
1011
  }
726
- (0, import_react.useEffect)(() => {
727
- if (!params.q && !params.networkId) return;
728
- if (debounceRef.current) clearTimeout(debounceRef.current);
729
- if (controllerRef.current) controllerRef.current.abort();
730
- const controller = new AbortController();
731
- controllerRef.current = controller;
732
- debounceRef.current = setTimeout(() => {
733
- fetchTokens(controller.signal);
734
- }, debounceMs);
735
- return () => {
736
- controller.abort();
737
- if (debounceRef.current) clearTimeout(debounceRef.current);
738
- };
739
- }, [cacheKey, debounceMs]);
740
- return (0, import_react.useMemo)(
741
- () => ({
742
- /** Current fetched data (cached when possible) */
743
- data,
744
- /** Whether a request is in progress */
745
- loading,
746
- /** Error object if a request failed */
747
- error,
748
- /** Manually refetch the token list */
749
- refetch: () => fetchTokens(),
750
- /** Clear all cached token results (shared across hook instances) */
751
- clearCache: () => tokenCache.clear()
752
- }),
753
- [data, loading, error]
1012
+ const results = await Promise.all(
1013
+ wallets.map((wallet) => (0, import_intents_sdk13.fetchUserOrders)({ wallet }))
754
1014
  );
755
- }
756
-
757
- // src/react/useExecuteOrder.ts
758
- var import_react2 = require("react");
759
- function useExecuteOrder() {
760
- const [status, setStatus] = (0, import_react2.useState)("processing");
761
- const [message, setMessage] = (0, import_react2.useState)(null);
762
- const [loading, setLoading] = (0, import_react2.useState)(false);
763
- const [data, setData] = (0, import_react2.useState)(null);
764
- const [error, setError] = (0, import_react2.useState)(null);
765
- const isMounted = (0, import_react2.useRef)(true);
766
- (0, import_react2.useEffect)(() => {
767
- return () => {
768
- isMounted.current = false;
769
- };
770
- }, []);
771
- const execute = (0, import_react2.useCallback)(
772
- async ({
773
- quote,
774
- accountAddress,
775
- recipientAddress,
776
- wallet,
777
- deadline
778
- }) => {
779
- if (!quote || !wallet) {
780
- throw new Error("Quote and wallet are required for order execution.");
781
- }
782
- setLoading(true);
783
- setError(null);
784
- setData(null);
785
- setMessage(null);
786
- try {
787
- const effectiveDeadline = deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
788
- const onStatus = (stage, msg) => {
789
- if (!isMounted.current) return;
790
- setStatus(stage);
791
- if (msg) setMessage(msg);
792
- };
793
- const result = await executeOrder({
794
- quote,
795
- accountAddress,
796
- recipientAddress,
797
- wallet,
798
- onStatus,
799
- options: { deadline: effectiveDeadline }
800
- });
801
- if (!isMounted.current) return result;
802
- setData(result);
803
- setStatus(result.stage);
804
- setMessage("Order executed successfully");
805
- return result;
806
- } catch (err) {
807
- const errorObj = err instanceof Error ? err : new Error(String(err));
808
- if (isMounted.current) {
809
- setError(errorObj);
810
- setStatus("error");
811
- setMessage(errorObj.message);
812
- setData({
813
- status: false,
814
- stage: "error",
815
- message: errorObj.message
816
- });
817
- }
818
- return {
819
- status: false,
820
- stage: "error",
821
- message: errorObj.message
822
- };
823
- } finally {
824
- if (isMounted.current) setLoading(false);
825
- }
1015
+ return results.reduce(
1016
+ (merged, orders) => {
1017
+ merged.singleChainLimitOrders.push(...orders.singleChainLimitOrders);
1018
+ merged.crossChainLimitOrders.push(...orders.crossChainLimitOrders);
1019
+ return merged;
826
1020
  },
827
- []
1021
+ { singleChainLimitOrders: [], crossChainLimitOrders: [] }
828
1022
  );
829
- return {
830
- /** Executes the swap order. */
831
- execute,
832
- /** Current execution stage. */
833
- status,
834
- /** Human-readable status message. */
835
- message,
836
- /** Whether execution is ongoing. */
837
- loading,
838
- /** Raw SDK response data. */
839
- data,
840
- /** Captured error (if execution failed). */
841
- error
842
- };
843
1023
  }
844
1024
 
845
- // src/react/useQuote.ts
846
- var import_react3 = require("react");
847
- function useQuote(params, options) {
848
- const [data, setData] = (0, import_react3.useState)(null);
849
- const [loading, setLoading] = (0, import_react3.useState)(false);
850
- const [error, setError] = (0, import_react3.useState)(null);
851
- const [warning, setWarning] = (0, import_react3.useState)(null);
852
- const debounceMs = options?.debounceMs ?? 250;
853
- const autoRefreshMs = options?.autoRefreshMs;
854
- const abortRef = (0, import_react3.useRef)(null);
855
- const debounceRef = (0, import_react3.useRef)(null);
856
- const mounted = (0, import_react3.useRef)(false);
857
- (0, import_react3.useEffect)(() => {
858
- mounted.current = true;
859
- return () => {
860
- mounted.current = false;
861
- abortRef.current?.abort();
862
- if (debounceRef.current) clearTimeout(debounceRef.current);
863
- };
864
- }, []);
865
- const fetchQuote = (0, import_react3.useCallback)(
866
- async () => {
867
- if (!params) return;
868
- try {
869
- setLoading(true);
870
- setWarning(null);
871
- const result = await getQuote(params);
872
- const serializeResult = serializeBigIntsToStrings(result);
873
- if (!mounted.current) return;
874
- setData((prev) => {
875
- if (JSON.stringify(prev) === JSON.stringify(serializeResult)) return prev;
876
- return serializeResult;
877
- });
878
- setWarning(result.warning ?? null);
879
- setError(null);
880
- } catch (err) {
881
- if (err.name === "AbortError") return;
882
- console.error("[useQuote] fetch error:", err);
883
- if (mounted.current) setError(err instanceof Error ? err : new Error(String(err)));
884
- } finally {
885
- if (mounted.current) setLoading(false);
886
- }
887
- },
888
- [params]
889
- );
890
- (0, import_react3.useEffect)(() => {
891
- if (!params) return;
892
- if (debounceRef.current) clearTimeout(debounceRef.current);
893
- debounceRef.current = setTimeout(() => {
894
- fetchQuote();
895
- }, debounceMs);
896
- return () => {
897
- if (debounceRef.current) clearTimeout(debounceRef.current);
898
- abortRef.current?.abort();
899
- };
900
- }, [params, debounceMs, fetchQuote]);
901
- (0, import_react3.useEffect)(() => {
902
- if (!autoRefreshMs || !params) return;
903
- const interval = setInterval(() => fetchQuote(), autoRefreshMs);
904
- return () => clearInterval(interval);
905
- }, [autoRefreshMs, params, fetchQuote]);
906
- return (0, import_react3.useMemo)(
907
- () => ({
908
- data,
909
- loading,
910
- error,
911
- warning,
912
- refetch: () => fetchQuote()
913
- }),
914
- [data, loading, error, warning, fetchQuote]
915
- );
1025
+ // src/core/orders/cancelOrder.ts
1026
+ var import_intents_sdk14 = require("@shogun-sdk/intents-sdk");
1027
+ var import_web32 = require("@solana/web3.js");
1028
+ var import_viem8 = require("viem");
1029
+ var inFlightCancels = /* @__PURE__ */ new Map();
1030
+ function cancelIntentsOrder(args) {
1031
+ const srcChain = "srcChainId" in args.order ? args.order.srcChainId : args.order.chainId;
1032
+ const key = `${srcChain}:${args.order.orderId}`;
1033
+ const existing = inFlightCancels.get(key);
1034
+ if (existing) return existing;
1035
+ const pending = performCancel(args).finally(() => {
1036
+ inFlightCancels.delete(key);
1037
+ });
1038
+ inFlightCancels.set(key, pending);
1039
+ return pending;
916
1040
  }
917
-
918
- // src/react/useBalances.ts
919
- var import_react4 = require("react");
920
- function useBalances(params) {
921
- const [data, setData] = (0, import_react4.useState)(null);
922
- const [loading, setLoading] = (0, import_react4.useState)(false);
923
- const [error, setError] = (0, import_react4.useState)(null);
924
- const abortRef = (0, import_react4.useRef)(null);
925
- const stableParams = (0, import_react4.useMemo)(() => {
926
- if (!params) return null;
927
- const { addresses, cursorEvm, cursorSvm } = params;
928
- return {
929
- addresses: {
930
- evm: addresses?.evm ?? void 0,
931
- svm: addresses?.svm ?? void 0
932
- },
933
- cursorEvm,
934
- cursorSvm
935
- };
936
- }, [params?.addresses?.evm, params?.addresses?.svm, params?.cursorEvm, params?.cursorSvm]);
937
- const fetchBalances = (0, import_react4.useCallback)(async () => {
938
- if (!stableParams) return;
939
- if (abortRef.current) abortRef.current.abort();
940
- const controller = new AbortController();
941
- abortRef.current = controller;
942
- setLoading(true);
943
- setError(null);
944
- try {
945
- const result = await getBalances(stableParams, { signal: controller.signal });
946
- setData((prev) => {
947
- if (JSON.stringify(prev) === JSON.stringify(result)) return prev;
948
- return result;
1041
+ async function performCancel({
1042
+ order,
1043
+ wallet,
1044
+ sol_rpc
1045
+ }) {
1046
+ const isCrossChain = "srcChainId" in order && "destChainId" in order && order.srcChainId !== order.destChainId;
1047
+ const srcChain = "srcChainId" in order ? order.srcChainId : order.chainId;
1048
+ const isSolanaOrder = srcChain === import_intents_sdk14.ChainID.Solana;
1049
+ if (isSolanaOrder) {
1050
+ if (!isCrossChain) {
1051
+ const { versionedMessageBytes: versionedMessageBytes2 } = await (0, import_intents_sdk14.cancelSingleChainOrderInstructionsAsBytes)(
1052
+ order.orderId,
1053
+ order.user,
1054
+ { rpcUrl: sol_rpc }
1055
+ );
1056
+ const message2 = import_web32.VersionedMessage.deserialize(
1057
+ versionedMessageBytes2
1058
+ );
1059
+ const tx2 = new import_web32.VersionedTransaction(message2);
1060
+ return await wallet.sendTransaction(tx2);
1061
+ }
1062
+ const { versionedMessageBytes } = await (0, import_intents_sdk14.cancelCrossChainOrderInstructionsAsBytes)(
1063
+ order.orderId,
1064
+ order.user,
1065
+ { rpcUrl: sol_rpc }
1066
+ );
1067
+ const message = import_web32.VersionedMessage.deserialize(
1068
+ versionedMessageBytes
1069
+ );
1070
+ const tx = new import_web32.VersionedTransaction(message);
1071
+ return await wallet.sendTransaction(tx);
1072
+ }
1073
+ const chainId = srcChain;
1074
+ const { readContract } = wallet;
1075
+ if (!readContract) {
1076
+ throw new Error("Wallet does not support readContract");
1077
+ }
1078
+ const nonce = BigInt(order.nonce ?? "0");
1079
+ const nonceWordPos = nonce >> 8n;
1080
+ const nonceBitPos = nonce - nonceWordPos * 256n;
1081
+ if (isCrossChain) {
1082
+ const [orderData = [false, false], currentNonceBitmap = 0n] = await Promise.all([
1083
+ readContract({
1084
+ address: import_intents_sdk14.CROSS_CHAIN_GUARD_ADDRESSES[chainId],
1085
+ abi: [
1086
+ {
1087
+ inputs: [{ name: "orderId", type: "bytes32" }],
1088
+ name: "orderData",
1089
+ outputs: [
1090
+ { name: "initialized", type: "bool" },
1091
+ { name: "deactivated", type: "bool" }
1092
+ ],
1093
+ stateMutability: "view",
1094
+ type: "function"
1095
+ }
1096
+ ],
1097
+ functionName: "orderData",
1098
+ args: [order.orderId]
1099
+ }),
1100
+ readContract({
1101
+ address: import_intents_sdk14.PERMIT2_ADDRESS[chainId],
1102
+ abi: [
1103
+ {
1104
+ inputs: [
1105
+ { name: "owner", type: "address" },
1106
+ { name: "wordPos", type: "uint256" }
1107
+ ],
1108
+ name: "nonceBitmap",
1109
+ outputs: [{ name: "", type: "uint256" }],
1110
+ stateMutability: "view",
1111
+ type: "function"
1112
+ }
1113
+ ],
1114
+ functionName: "nonceBitmap",
1115
+ args: [order.user, nonceWordPos]
1116
+ })
1117
+ ]);
1118
+ const [initialized, deactivated] = orderData;
1119
+ if (initialized) {
1120
+ if (deactivated) {
1121
+ throw new Error("Order is already deactivated");
1122
+ }
1123
+ return await wallet.sendTransaction({
1124
+ to: import_intents_sdk14.CROSS_CHAIN_GUARD_ADDRESSES[order.srcChainId],
1125
+ data: (0, import_viem8.encodeFunctionData)({
1126
+ abi: [
1127
+ {
1128
+ inputs: [
1129
+ {
1130
+ components: [
1131
+ { name: "user", type: "address" },
1132
+ { name: "tokenIn", type: "address" },
1133
+ { name: "srcChainId", type: "uint256" },
1134
+ { name: "deadline", type: "uint256" },
1135
+ { name: "amountIn", type: "uint256" },
1136
+ { name: "minStablecoinsAmount", type: "uint256" },
1137
+ { name: "executionDetailsHash", type: "bytes32" },
1138
+ { name: "nonce", type: "uint256" }
1139
+ ],
1140
+ name: "orderInfo",
1141
+ type: "tuple"
1142
+ }
1143
+ ],
1144
+ name: "cancelOrder",
1145
+ outputs: [],
1146
+ stateMutability: "nonpayable",
1147
+ type: "function"
1148
+ }
1149
+ ],
1150
+ functionName: "cancelOrder",
1151
+ args: [
1152
+ {
1153
+ user: order.user,
1154
+ tokenIn: order.tokenIn,
1155
+ srcChainId: BigInt(order.srcChainId),
1156
+ deadline: BigInt(order.deadline),
1157
+ amountIn: BigInt(order.amountIn),
1158
+ minStablecoinsAmount: BigInt(order.minStablecoinsAmount),
1159
+ executionDetailsHash: order.executionDetailsHash,
1160
+ nonce
1161
+ }
1162
+ ]
1163
+ }),
1164
+ value: BigInt(0),
1165
+ from: order.user
1166
+ });
1167
+ } else {
1168
+ if ((currentNonceBitmap & 1n << nonceBitPos) !== 0n) {
1169
+ throw new Error("Nonce is already invalidated");
1170
+ }
1171
+ const mask2 = 1n << nonceBitPos;
1172
+ return await wallet.sendTransaction({
1173
+ to: import_intents_sdk14.PERMIT2_ADDRESS[order.srcChainId],
1174
+ data: (0, import_viem8.encodeFunctionData)({
1175
+ abi: [
1176
+ {
1177
+ inputs: [
1178
+ { name: "wordPos", type: "uint256" },
1179
+ { name: "mask", type: "uint256" }
1180
+ ],
1181
+ name: "invalidateUnorderedNonces",
1182
+ outputs: [],
1183
+ stateMutability: "nonpayable",
1184
+ type: "function"
1185
+ }
1186
+ ],
1187
+ functionName: "invalidateUnorderedNonces",
1188
+ args: [nonceWordPos, mask2]
1189
+ }),
1190
+ value: BigInt(0),
1191
+ from: order.user
949
1192
  });
950
- return result;
951
- } catch (err) {
952
- if (err.name === "AbortError") return;
953
- const e = err instanceof Error ? err : new Error(String(err));
954
- setError(e);
955
- throw e;
956
- } finally {
957
- setLoading(false);
958
1193
  }
959
- }, [stableParams]);
960
- (0, import_react4.useEffect)(() => {
961
- if (stableParams) fetchBalances().catch(() => {
1194
+ }
1195
+ const [wasManuallyInitialized, currentBitmap = 0n] = await Promise.all([
1196
+ readContract({
1197
+ address: import_intents_sdk14.SINGLE_CHAIN_GUARD_ADDRESSES[chainId],
1198
+ abi: [
1199
+ {
1200
+ inputs: [{ name: "orderHash", type: "bytes32" }],
1201
+ name: "orderManuallyInitialized",
1202
+ outputs: [{ name: "", type: "bool" }],
1203
+ stateMutability: "view",
1204
+ type: "function"
1205
+ }
1206
+ ],
1207
+ functionName: "orderManuallyInitialized",
1208
+ args: [order.orderId]
1209
+ }),
1210
+ readContract({
1211
+ address: import_intents_sdk14.PERMIT2_ADDRESS[chainId],
1212
+ abi: [
1213
+ {
1214
+ inputs: [
1215
+ { name: "owner", type: "address" },
1216
+ { name: "wordPos", type: "uint256" }
1217
+ ],
1218
+ name: "nonceBitmap",
1219
+ outputs: [{ name: "", type: "uint256" }],
1220
+ stateMutability: "view",
1221
+ type: "function"
1222
+ }
1223
+ ],
1224
+ functionName: "nonceBitmap",
1225
+ args: [order.user, nonceWordPos]
1226
+ })
1227
+ ]);
1228
+ if (wasManuallyInitialized) {
1229
+ return await wallet.sendTransaction({
1230
+ to: import_intents_sdk14.SINGLE_CHAIN_GUARD_ADDRESSES[chainId],
1231
+ data: (0, import_viem8.encodeFunctionData)({
1232
+ abi: [
1233
+ {
1234
+ inputs: [
1235
+ {
1236
+ name: "order",
1237
+ type: "tuple",
1238
+ components: [
1239
+ { name: "amountIn", type: "uint256" },
1240
+ { name: "tokenIn", type: "address" },
1241
+ { name: "deadline", type: "uint256" },
1242
+ { name: "nonce", type: "uint256" },
1243
+ { name: "encodedExternalCallData", type: "bytes" },
1244
+ {
1245
+ name: "extraTransfers",
1246
+ type: "tuple[]",
1247
+ components: [
1248
+ { name: "amount", type: "uint256" },
1249
+ { name: "receiver", type: "address" },
1250
+ { name: "token", type: "address" }
1251
+ ]
1252
+ },
1253
+ {
1254
+ name: "requestedOutput",
1255
+ type: "tuple",
1256
+ components: [
1257
+ { name: "amount", type: "uint256" },
1258
+ { name: "receiver", type: "address" },
1259
+ { name: "token", type: "address" }
1260
+ ]
1261
+ },
1262
+ { name: "user", type: "address" }
1263
+ ]
1264
+ }
1265
+ ],
1266
+ name: "cancelManuallyCreatedOrder",
1267
+ outputs: [],
1268
+ stateMutability: "nonpayable",
1269
+ type: "function"
1270
+ }
1271
+ ],
1272
+ functionName: "cancelManuallyCreatedOrder",
1273
+ args: [
1274
+ {
1275
+ amountIn: BigInt(order.amountIn),
1276
+ tokenIn: order.tokenIn,
1277
+ deadline: BigInt(order.deadline),
1278
+ nonce,
1279
+ encodedExternalCallData: "0x",
1280
+ extraTransfers: (order.extraTransfers || []).map((t) => ({
1281
+ amount: BigInt(t.amount),
1282
+ receiver: t.receiver,
1283
+ token: t.token
1284
+ })),
1285
+ requestedOutput: {
1286
+ amount: BigInt(order.amountOutMin),
1287
+ receiver: order.destinationAddress,
1288
+ token: order.tokenOut
1289
+ },
1290
+ user: order.user
1291
+ }
1292
+ ]
1293
+ }),
1294
+ value: 0n,
1295
+ from: order.user
962
1296
  });
963
- return () => {
964
- if (abortRef.current) abortRef.current.abort();
965
- };
966
- }, [fetchBalances]);
967
- return (0, import_react4.useMemo)(
968
- () => ({
969
- /** Latest fetched balance data */
970
- data,
971
- /** Whether the hook is currently fetching */
972
- loading,
973
- /** Error object if fetching failed */
974
- error,
975
- /** Manually trigger a refresh */
976
- refetch: fetchBalances
1297
+ }
1298
+ const mask = 1n << nonceBitPos;
1299
+ if ((currentBitmap & mask) !== 0n) {
1300
+ throw new Error("Nonce is already invalidated");
1301
+ }
1302
+ return await wallet.sendTransaction({
1303
+ to: import_intents_sdk14.PERMIT2_ADDRESS[chainId],
1304
+ data: (0, import_viem8.encodeFunctionData)({
1305
+ abi: [
1306
+ {
1307
+ inputs: [
1308
+ { name: "wordPos", type: "uint256" },
1309
+ { name: "mask", type: "uint256" }
1310
+ ],
1311
+ name: "invalidateUnorderedNonces",
1312
+ outputs: [],
1313
+ stateMutability: "nonpayable",
1314
+ type: "function"
1315
+ }
1316
+ ],
1317
+ functionName: "invalidateUnorderedNonces",
1318
+ args: [nonceWordPos, mask]
977
1319
  }),
978
- [data, loading, error, fetchBalances]
979
- );
1320
+ value: 0n,
1321
+ from: order.user
1322
+ });
980
1323
  }
981
- // Annotate the CommonJS export names for ESM import in node:
982
- 0 && (module.exports = {
983
- NATIVE_TOKEN,
984
- SOLANA_CHAIN_ID,
985
- SupportedChains,
986
- adaptEthersSigner,
987
- adaptSolanaWallet,
988
- adaptViemWallet,
989
- buildQuoteParams,
990
- executeOrder,
991
- getBalances,
992
- getQuote,
993
- getTokenList,
994
- isNativeAddress,
995
- isViemWalletClient,
996
- serializeBigIntsToStrings,
997
- useBalances,
998
- useExecuteOrder,
999
- useQuote,
1000
- useTokenList
1001
- });
1324
+
1325
+ // src/core/client.ts
1326
+ var SwapSDK = class {
1327
+ constructor(config) {
1328
+ __publicField(this, "apiKey");
1329
+ /**
1330
+ * Fetches metadata for one or more tokens from the Shogun Token Search API.
1331
+ *
1332
+ * ---
1333
+ * ### Overview
1334
+ * `getTokensData` retrieves normalized token information — such as symbol, name,
1335
+ * decimals, logo URI, and verified status — for a given list of token addresses.
1336
+ *
1337
+ * It supports both **EVM** and **SVM (Solana)** tokens, returning metadata from
1338
+ * Shogun’s unified token registry.
1339
+ *
1340
+ * ---
1341
+ * @example
1342
+ * ```ts
1343
+ * const tokens = await getTokensData([
1344
+ * "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
1345
+ * "So11111111111111111111111111111111111111112", // SOL
1346
+ * ]);
1347
+ *
1348
+ * console.log(tokens);
1349
+ * [
1350
+ * { symbol: "USDC", name: "USD Coin", chainId: 1, decimals: 6, ... },
1351
+ * { symbol: "SOL", name: "Solana", chainId: 101, decimals: 9, ... }
1352
+ * ]
1353
+ * ```
1354
+ *
1355
+ * @param addresses - An array of token addresses (EVM or SVM) to fetch metadata for.
1356
+ * @returns A promise resolving to an array of {@link TokenInfo} objects.
1357
+ *
1358
+ * @throws Will throw an error if the network request fails or the API responds with a non-OK status.
1359
+ */
1360
+ __publicField(this, "getTokensData", getTokensData.bind(this));
1361
+ if (!config.apiKey) {
1362
+ throw new Error("SwapSDK: Missing API key");
1363
+ }
1364
+ this.apiKey = config.apiKey;
1365
+ if (this.apiKey) void this.apiKey;
1366
+ }
1367
+ /**
1368
+ * Retrieves a swap quote for the given input and output tokens.
1369
+ *
1370
+ * @param params - Quote parameters including source/destination tokens and amount.
1371
+ * @returns A normalized `SwapQuoteResponse` containing output amount, route, and metadata.
1372
+ */
1373
+ async getQuote(params) {
1374
+ return getQuote(params);
1375
+ }
1376
+ /**
1377
+ * Fetches token balances for the specified user wallet(s).
1378
+ *
1379
+ * Supports both EVM and SVM (Solana) wallet addresses.
1380
+ *
1381
+ * @param params - Wallet address and optional chain filters.
1382
+ * @param options - Optional abort signal for cancellation.
1383
+ * @returns A unified balance response with per-chain token details.
1384
+ */
1385
+ async getBalances(params, options) {
1386
+ return getBalances(params, options);
1387
+ }
1388
+ /**
1389
+ * Retrieves a list of verified tokens based on search query or chain filter.
1390
+ *
1391
+ * @param params - Search parameters (query, chain ID, pagination options).
1392
+ * @returns Paginated `TokenSearchResponse` containing token metadata.
1393
+ */
1394
+ async getTokenList(params) {
1395
+ return getTokenList(params);
1396
+ }
1397
+ /**
1398
+ * Executes a prepared swap quote using the provided wallet and configuration.
1399
+ *
1400
+ * Handles:
1401
+ * - Token approval (if required)
1402
+ * - Transaction signing and broadcasting
1403
+ * - Confirmation polling and stage-based status updates
1404
+ *
1405
+ * Supports both:
1406
+ * - Market orders (with optional deadline)
1407
+ * - Limit orders (requires executionPrice and deadline)
1408
+ *
1409
+ * @param quote - The swap quote to execute, containing route and metadata.
1410
+ * @param accountAddress - The user's wallet address executing the swap.
1411
+ * @param recipientAddress - Optional recipient address for the output tokens (defaults to sender).
1412
+ * @param wallet - Adapted wallet instance (EVM/Solana) or a standard Viem `WalletClient`.
1413
+ * @param onStatus - Optional callback for receiving execution stage updates and messages.
1414
+ * @param orderType - Defines whether this is a market or limit order.
1415
+ * @param options - Execution parameters (different per order type).
1416
+ *
1417
+ * @returns A finalized execution result containing transaction hash, status, and any returned data.
1418
+ *
1419
+ * @example
1420
+ * ```ts
1421
+ * * Market order
1422
+ * const result = await sdk.executeTransaction({
1423
+ * quote,
1424
+ * accountAddress: "0x123...",
1425
+ * wallet,
1426
+ * orderType: OrderExecutionType.MARKET,
1427
+ * options: { deadline: 1800 },
1428
+ * onStatus: (stage, msg) => console.log(stage, msg),
1429
+ * });
1430
+ *
1431
+ * * Limit order
1432
+ * const result = await sdk.executeTransaction({
1433
+ * quote,
1434
+ * accountAddress: "0x123...",
1435
+ * wallet,
1436
+ * orderType: OrderExecutionType.LIMIT,
1437
+ * options: { executionPrice: "0.0021", deadline: 3600 },
1438
+ * });
1439
+ * ```
1440
+ */
1441
+ async executeTransaction({
1442
+ quote,
1443
+ accountAddress,
1444
+ recipientAddress,
1445
+ wallet,
1446
+ onStatus,
1447
+ orderType,
1448
+ options
1449
+ }) {
1450
+ return executeOrder({
1451
+ quote,
1452
+ wallet,
1453
+ accountAddress,
1454
+ recipientAddress,
1455
+ onStatus,
1456
+ orderType,
1457
+ options
1458
+ });
1459
+ }
1460
+ /**
1461
+ * Fetches all user orders (Market, Limit, Cross-chain) for connected wallets.
1462
+ *
1463
+ * ---
1464
+ * ### Overview
1465
+ * Retrieves both **single-chain** and **cross-chain** orders from the Shogun Intents API.
1466
+ * Works across EVM, Solana
1467
+ *
1468
+ * ---
1469
+ * @example
1470
+ * ```ts
1471
+ * const orders = await sdk.getOrders({
1472
+ * evmAddress: "0x123...",
1473
+ * solAddress: "9d12hF...abc",
1474
+ * });
1475
+ *
1476
+ * console.log(orders.singleChainLimitOrders);
1477
+ * ```
1478
+ *
1479
+ * @param params - Wallet addresses to fetch orders for (EVM, Solana).
1480
+ * @returns A structured {@link ApiUserOrders} object containing all user orders.
1481
+ */
1482
+ async getOrders(params) {
1483
+ return getOrders(params);
1484
+ }
1485
+ /**
1486
+ * Cancels an order (single-chain or cross-chain) on EVM or Solana.
1487
+ *
1488
+ * Internally routes to the correct guard contract or Solana program to
1489
+ * deactivate the order or invalidate its nonce.
1490
+ *
1491
+ * @param params.order - Order payload returned from the Intents API.
1492
+ * @param params.wallet - Adapted wallet used to submit the cancellation transaction.
1493
+ * @param params.solRpc - Solana RPC URL used for SVM cancellations.
1494
+ *
1495
+ * @returns A transaction signature or hash from the underlying wallet.
1496
+ */
1497
+ async cancelOrder(params) {
1498
+ return cancelIntentsOrder({
1499
+ order: params.order,
1500
+ wallet: params.wallet,
1501
+ sol_rpc: params.solRpc
1502
+ });
1503
+ }
1504
+ };