@shogun-sdk/swap 0.0.2-test.24 → 0.0.2-test.26
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/core.cjs +379 -112
- package/dist/core.d.cts +4 -136
- package/dist/core.d.ts +4 -136
- package/dist/core.js +353 -84
- package/dist/index-Czt8I0Vg.d.ts +351 -0
- package/dist/index-D62OxLwp.d.cts +351 -0
- package/dist/index.cjs +373 -500
- package/dist/index.d.cts +4 -9
- package/dist/index.d.ts +4 -9
- package/dist/index.js +347 -474
- package/dist/react.cjs +829 -476
- package/dist/react.d.cts +192 -82
- package/dist/react.d.ts +192 -82
- package/dist/react.js +799 -454
- package/dist/{wallet-BhuMJ3K_.d.cts → wallet-B9bKceyN.d.cts} +1 -2
- package/dist/{wallet-BhuMJ3K_.d.ts → wallet-B9bKceyN.d.ts} +1 -2
- package/dist/wallet-adapter.cjs +25607 -11
- package/dist/wallet-adapter.d.cts +1 -2
- package/dist/wallet-adapter.d.ts +1 -2
- package/dist/wallet-adapter.js +25626 -6
- package/package.json +44 -14
- package/dist/execute-D2qcOzkI.d.ts +0 -145
- package/dist/execute-Xvw4wXBo.d.cts +0 -145
package/dist/core.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
return intentsGetTokenList(params);
|
|
5
|
-
}
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
4
|
|
|
7
5
|
// src/core/getQuote.ts
|
|
8
6
|
import { QuoteProvider } from "@shogun-sdk/intents-sdk";
|
|
9
7
|
import { parseUnits } from "viem";
|
|
10
8
|
|
|
11
|
-
// src/core/
|
|
12
|
-
import { isEvmChain } from "@shogun-sdk/intents-sdk";
|
|
9
|
+
// src/core/execute/normalizeNative.ts
|
|
10
|
+
import { isEvmChain as isEvmChain2 } from "@shogun-sdk/intents-sdk";
|
|
13
11
|
|
|
14
12
|
// src/utils/address.ts
|
|
13
|
+
import { zeroAddress } from "viem";
|
|
15
14
|
var NATIVE_TOKEN = {
|
|
16
15
|
ETH: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
|
|
17
16
|
SOL: "So11111111111111111111111111111111111111111",
|
|
@@ -22,13 +21,31 @@ var isNativeAddress = (tokenAddress) => {
|
|
|
22
21
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
|
23
22
|
return !!tokenAddress && NATIVE_ADDRESSES.includes(normalizedTokenAddress);
|
|
24
23
|
};
|
|
24
|
+
function normalizeEvmTokenAddress(address) {
|
|
25
|
+
const lower = address.toLowerCase();
|
|
26
|
+
return lower === NATIVE_TOKEN.ETH.toLowerCase() ? zeroAddress : address;
|
|
27
|
+
}
|
|
25
28
|
|
|
26
29
|
// src/utils/chain.ts
|
|
27
|
-
import { ChainID } from "@shogun-sdk/intents-sdk";
|
|
28
|
-
var SOLANA_CHAIN_ID =
|
|
29
|
-
var
|
|
30
|
+
import { ChainID as BaseChainID, isEvmChain as isEvmChainIntent } from "@shogun-sdk/intents-sdk";
|
|
31
|
+
var SOLANA_CHAIN_ID = BaseChainID.Solana;
|
|
32
|
+
var CURRENT_SUPPORTED = [
|
|
33
|
+
BaseChainID.Solana,
|
|
34
|
+
BaseChainID.BSC,
|
|
35
|
+
BaseChainID.Base
|
|
36
|
+
];
|
|
37
|
+
var ChainId = Object.entries(BaseChainID).reduce(
|
|
38
|
+
(acc, [key, value]) => {
|
|
39
|
+
if (typeof value === "number" && CURRENT_SUPPORTED.includes(value)) {
|
|
40
|
+
acc[key] = value;
|
|
41
|
+
}
|
|
42
|
+
return acc;
|
|
43
|
+
},
|
|
44
|
+
{}
|
|
45
|
+
);
|
|
46
|
+
var SupportedChainsInternal = [
|
|
30
47
|
{
|
|
31
|
-
id:
|
|
48
|
+
id: BaseChainID.Arbitrum,
|
|
32
49
|
name: "Arbitrum",
|
|
33
50
|
isEVM: true,
|
|
34
51
|
wrapped: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -37,7 +54,7 @@ var SupportedChains = [
|
|
|
37
54
|
tokenAddress: NATIVE_TOKEN.ETH
|
|
38
55
|
},
|
|
39
56
|
{
|
|
40
|
-
id:
|
|
57
|
+
id: BaseChainID.Optimism,
|
|
41
58
|
name: "Optimism",
|
|
42
59
|
isEVM: true,
|
|
43
60
|
wrapped: "0x4200000000000000000000000000000000000006",
|
|
@@ -46,7 +63,7 @@ var SupportedChains = [
|
|
|
46
63
|
tokenAddress: NATIVE_TOKEN.ETH
|
|
47
64
|
},
|
|
48
65
|
{
|
|
49
|
-
id:
|
|
66
|
+
id: BaseChainID.Base,
|
|
50
67
|
name: "Base",
|
|
51
68
|
isEVM: true,
|
|
52
69
|
wrapped: "0x4200000000000000000000000000000000000006",
|
|
@@ -55,7 +72,7 @@ var SupportedChains = [
|
|
|
55
72
|
tokenAddress: NATIVE_TOKEN.ETH
|
|
56
73
|
},
|
|
57
74
|
{
|
|
58
|
-
id:
|
|
75
|
+
id: BaseChainID.Hyperliquid,
|
|
59
76
|
name: "Hyperliquid",
|
|
60
77
|
isEVM: true,
|
|
61
78
|
wrapped: "0x5555555555555555555555555555555555555555",
|
|
@@ -64,7 +81,7 @@ var SupportedChains = [
|
|
|
64
81
|
tokenAddress: NATIVE_TOKEN.ETH
|
|
65
82
|
},
|
|
66
83
|
{
|
|
67
|
-
id:
|
|
84
|
+
id: BaseChainID.BSC,
|
|
68
85
|
name: "BSC",
|
|
69
86
|
isEVM: true,
|
|
70
87
|
wrapped: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
|
|
@@ -82,6 +99,10 @@ var SupportedChains = [
|
|
|
82
99
|
tokenAddress: NATIVE_TOKEN.SOL
|
|
83
100
|
}
|
|
84
101
|
];
|
|
102
|
+
var SupportedChains = SupportedChainsInternal.filter(
|
|
103
|
+
(c) => CURRENT_SUPPORTED.includes(c.id)
|
|
104
|
+
);
|
|
105
|
+
var isEvmChain = isEvmChainIntent;
|
|
85
106
|
|
|
86
107
|
// src/utils/viem.ts
|
|
87
108
|
function isViemWalletClient(wallet) {
|
|
@@ -109,9 +130,9 @@ function serializeBigIntsToStrings(obj) {
|
|
|
109
130
|
return obj;
|
|
110
131
|
}
|
|
111
132
|
|
|
112
|
-
// src/core/
|
|
133
|
+
// src/core/execute/normalizeNative.ts
|
|
113
134
|
function normalizeNative(chainId, address) {
|
|
114
|
-
if (
|
|
135
|
+
if (isEvmChain2(chainId) && isNativeAddress(address)) {
|
|
115
136
|
const chain = SupportedChains.find((c) => c.id === chainId);
|
|
116
137
|
if (!chain?.wrapped)
|
|
117
138
|
throw new Error(`Wrapped token not found for chainId ${chainId}`);
|
|
@@ -122,13 +143,14 @@ function normalizeNative(chainId, address) {
|
|
|
122
143
|
|
|
123
144
|
// src/core/getQuote.ts
|
|
124
145
|
async function getQuote(params) {
|
|
146
|
+
const amount = BigInt(params.amount);
|
|
125
147
|
if (!params.tokenIn?.address || !params.tokenOut?.address) {
|
|
126
148
|
throw new Error("Both tokenIn and tokenOut must include an address.");
|
|
127
149
|
}
|
|
128
150
|
if (!params.sourceChainId || !params.destChainId) {
|
|
129
151
|
throw new Error("Both sourceChainId and destChainId are required.");
|
|
130
152
|
}
|
|
131
|
-
if (
|
|
153
|
+
if (amount <= 0n) {
|
|
132
154
|
throw new Error("Amount must be greater than 0.");
|
|
133
155
|
}
|
|
134
156
|
const normalizedTokenIn = normalizeNative(params.sourceChainId, params.tokenIn.address);
|
|
@@ -137,7 +159,7 @@ async function getQuote(params) {
|
|
|
137
159
|
destChainId: params.destChainId,
|
|
138
160
|
tokenIn: normalizedTokenIn,
|
|
139
161
|
tokenOut: params.tokenOut.address,
|
|
140
|
-
amount
|
|
162
|
+
amount
|
|
141
163
|
});
|
|
142
164
|
const slippagePercent = Math.min(Math.max(params.slippage ?? 0.5, 0), 50);
|
|
143
165
|
let warning;
|
|
@@ -168,7 +190,7 @@ async function getQuote(params) {
|
|
|
168
190
|
decimals: params.tokenOut.decimals ?? 18,
|
|
169
191
|
chainId: params.destChainId
|
|
170
192
|
},
|
|
171
|
-
amountIn: params.amount,
|
|
193
|
+
amountIn: BigInt(params.amount),
|
|
172
194
|
pricePerInputToken,
|
|
173
195
|
slippage: slippagePercent,
|
|
174
196
|
internal: {
|
|
@@ -192,7 +214,7 @@ function buildQuoteParams({
|
|
|
192
214
|
tokenOut,
|
|
193
215
|
sourceChainId,
|
|
194
216
|
destChainId,
|
|
195
|
-
amount: parseUnits(amount.toString(), tokenIn.decimals ?? 18),
|
|
217
|
+
amount: parseUnits(amount.toString(), tokenIn.decimals ?? 18).toString(),
|
|
196
218
|
slippage
|
|
197
219
|
};
|
|
198
220
|
}
|
|
@@ -239,20 +261,66 @@ async function getBalances(params, options) {
|
|
|
239
261
|
const evmItems = data.evm?.items ?? [];
|
|
240
262
|
const svmItems = data.svm?.items ?? [];
|
|
241
263
|
const combined = [...evmItems, ...svmItems];
|
|
264
|
+
const filtered = combined.filter(
|
|
265
|
+
(b) => CURRENT_SUPPORTED.includes(b.chainId)
|
|
266
|
+
);
|
|
242
267
|
return {
|
|
243
|
-
results:
|
|
268
|
+
results: filtered,
|
|
244
269
|
nextCursorEvm: data.evm?.cursor ?? null,
|
|
245
270
|
nextCursorSvm: data.svm?.cursor ?? null
|
|
246
271
|
};
|
|
247
272
|
}
|
|
248
273
|
|
|
249
|
-
// src/core/
|
|
250
|
-
import {
|
|
251
|
-
|
|
274
|
+
// src/core/token-list.ts
|
|
275
|
+
import { TOKEN_SEARCH_API_BASE_URL as TOKEN_SEARCH_API_BASE_URL2 } from "@shogun-sdk/intents-sdk";
|
|
276
|
+
async function getTokenList(params) {
|
|
277
|
+
const url = new URL(`${TOKEN_SEARCH_API_BASE_URL2}/tokens/search`);
|
|
278
|
+
if (params.q) url.searchParams.append("q", params.q);
|
|
279
|
+
if (params.networkId) url.searchParams.append("networkId", String(params.networkId));
|
|
280
|
+
if (params.page) url.searchParams.append("page", String(params.page));
|
|
281
|
+
if (params.limit) url.searchParams.append("limit", String(params.limit));
|
|
282
|
+
const res = await fetch(url.toString(), {
|
|
283
|
+
signal: params.signal
|
|
284
|
+
});
|
|
285
|
+
if (!res.ok) {
|
|
286
|
+
throw new Error(`Failed to fetch tokens: ${res.status} ${res.statusText}`);
|
|
287
|
+
}
|
|
288
|
+
const data = await res.json();
|
|
289
|
+
const filteredResults = data.results.filter(
|
|
290
|
+
(token) => CURRENT_SUPPORTED.includes(token.chainId)
|
|
291
|
+
);
|
|
292
|
+
return {
|
|
293
|
+
...data,
|
|
294
|
+
results: filteredResults,
|
|
295
|
+
count: filteredResults.length
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/core/token.ts
|
|
300
|
+
import { TOKEN_SEARCH_API_BASE_URL as TOKEN_SEARCH_API_BASE_URL3 } from "@shogun-sdk/intents-sdk";
|
|
301
|
+
async function getTokensData(addresses) {
|
|
302
|
+
if (!addresses?.length) return [];
|
|
303
|
+
const response = await fetch(`${TOKEN_SEARCH_API_BASE_URL3}/tokens/tokens`, {
|
|
304
|
+
method: "POST",
|
|
305
|
+
headers: {
|
|
306
|
+
"Content-Type": "application/json",
|
|
307
|
+
accept: "*/*"
|
|
308
|
+
},
|
|
309
|
+
body: JSON.stringify({ addresses })
|
|
310
|
+
});
|
|
311
|
+
if (!response.ok) {
|
|
312
|
+
throw new Error(`Failed to fetch token data: ${response.statusText}`);
|
|
313
|
+
}
|
|
314
|
+
const data = await response.json();
|
|
315
|
+
const filtered = data.filter((t) => CURRENT_SUPPORTED.includes(Number(t.chainId)));
|
|
316
|
+
return filtered;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/core/execute/execute.ts
|
|
320
|
+
import { ChainID as ChainID2, isEvmChain as isEvmChain3 } from "@shogun-sdk/intents-sdk";
|
|
321
|
+
import "viem";
|
|
252
322
|
|
|
253
323
|
// src/wallet-adapter/evm-wallet-adapter/adapter.ts
|
|
254
|
-
import { utils as ethersUtils } from "ethers/lib/ethers.js";
|
|
255
|
-
import { hexValue } from "ethers/lib/utils.js";
|
|
256
324
|
import {
|
|
257
325
|
custom,
|
|
258
326
|
publicActions
|
|
@@ -342,14 +410,14 @@ var adaptViemWallet = (wallet) => {
|
|
|
342
410
|
};
|
|
343
411
|
};
|
|
344
412
|
|
|
345
|
-
// src/core/
|
|
413
|
+
// src/core/execute/handleEvmExecution.ts
|
|
346
414
|
import {
|
|
347
415
|
getEVMSingleChainOrderTypedData,
|
|
348
416
|
getEVMCrossChainOrderTypedData
|
|
349
417
|
} from "@shogun-sdk/intents-sdk";
|
|
350
418
|
import { encodeFunctionData as encodeFunctionData2 } from "viem";
|
|
351
419
|
|
|
352
|
-
// src/core/
|
|
420
|
+
// src/core/execute/stageMessages.ts
|
|
353
421
|
var DEFAULT_STAGE_MESSAGES = {
|
|
354
422
|
processing: "Preparing transaction for execution",
|
|
355
423
|
approving: "Approving token allowance",
|
|
@@ -358,20 +426,44 @@ var DEFAULT_STAGE_MESSAGES = {
|
|
|
358
426
|
submitting: "Submitting transaction",
|
|
359
427
|
initiated: "Transaction initiated.",
|
|
360
428
|
success: "Transaction Executed successfully",
|
|
429
|
+
success_limit: "Limit order has been submitted successfully.",
|
|
361
430
|
shogun_processing: "Shogun is processing your transaction",
|
|
362
431
|
error: "Transaction failed during submission"
|
|
363
432
|
};
|
|
364
433
|
|
|
365
|
-
// src/core/
|
|
434
|
+
// src/core/execute/buildOrder.ts
|
|
366
435
|
import { CrossChainOrder, SingleChainOrder } from "@shogun-sdk/intents-sdk";
|
|
436
|
+
import { formatUnits, parseUnits as parseUnits2 } from "viem";
|
|
437
|
+
|
|
438
|
+
// src/utils/order.ts
|
|
439
|
+
var OrderExecutionType = /* @__PURE__ */ ((OrderExecutionType2) => {
|
|
440
|
+
OrderExecutionType2["LIMIT"] = "limit";
|
|
441
|
+
OrderExecutionType2["MARKET"] = "market";
|
|
442
|
+
return OrderExecutionType2;
|
|
443
|
+
})(OrderExecutionType || {});
|
|
444
|
+
|
|
445
|
+
// src/core/execute/buildOrder.ts
|
|
367
446
|
async function buildOrder({
|
|
368
447
|
quote,
|
|
369
448
|
accountAddress,
|
|
370
449
|
destination,
|
|
371
450
|
deadline,
|
|
372
|
-
isSingleChain
|
|
451
|
+
isSingleChain,
|
|
452
|
+
orderType,
|
|
453
|
+
options
|
|
373
454
|
}) {
|
|
374
455
|
const { tokenIn, tokenOut } = quote;
|
|
456
|
+
let amountOutMin = BigInt(quote.internal.estimatedAmountOutReduced);
|
|
457
|
+
if (orderType === "limit" /* LIMIT */ && options && "executionPrice" in options) {
|
|
458
|
+
const executionPrice = Number(options.executionPrice);
|
|
459
|
+
if (Number.isFinite(executionPrice) && executionPrice > 0) {
|
|
460
|
+
const decimalsIn = tokenIn.decimals ?? 18;
|
|
461
|
+
const decimalsOut = tokenOut.decimals ?? 18;
|
|
462
|
+
const formattedAmountIn = Number(formatUnits(BigInt(quote.amountIn.toString()), decimalsIn));
|
|
463
|
+
const rawAmountOut = formattedAmountIn * executionPrice;
|
|
464
|
+
amountOutMin = parseUnits2(rawAmountOut.toString(), decimalsOut);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
375
467
|
if (isSingleChain) {
|
|
376
468
|
return await SingleChainOrder.create({
|
|
377
469
|
user: accountAddress,
|
|
@@ -379,7 +471,7 @@ async function buildOrder({
|
|
|
379
471
|
tokenIn: tokenIn.address,
|
|
380
472
|
tokenOut: tokenOut.address,
|
|
381
473
|
amountIn: quote.amountIn,
|
|
382
|
-
amountOutMin
|
|
474
|
+
amountOutMin,
|
|
383
475
|
deadline,
|
|
384
476
|
destinationAddress: destination
|
|
385
477
|
});
|
|
@@ -393,7 +485,7 @@ async function buildOrder({
|
|
|
393
485
|
destinationTokenAddress: tokenOut.address,
|
|
394
486
|
destinationAddress: destination,
|
|
395
487
|
deadline,
|
|
396
|
-
destinationTokenMinAmount:
|
|
488
|
+
destinationTokenMinAmount: amountOutMin,
|
|
397
489
|
minStablecoinAmount: quote.minStablecoinsAmount
|
|
398
490
|
});
|
|
399
491
|
}
|
|
@@ -464,7 +556,7 @@ async function pollOrderStatus(address, orderId, options = {}) {
|
|
|
464
556
|
});
|
|
465
557
|
}
|
|
466
558
|
|
|
467
|
-
// src/core/
|
|
559
|
+
// src/core/execute/handleOrderPollingResult.ts
|
|
468
560
|
async function handleOrderPollingResult({
|
|
469
561
|
status,
|
|
470
562
|
orderId,
|
|
@@ -502,7 +594,7 @@ async function handleOrderPollingResult({
|
|
|
502
594
|
};
|
|
503
595
|
}
|
|
504
596
|
|
|
505
|
-
// src/core/
|
|
597
|
+
// src/core/execute/ensurePermit2Allowance.ts
|
|
506
598
|
import { encodeFunctionData, erc20Abi, maxUint256 } from "viem";
|
|
507
599
|
import { PERMIT2_ADDRESS } from "@shogun-sdk/intents-sdk";
|
|
508
600
|
async function ensurePermit2Allowance({
|
|
@@ -547,7 +639,7 @@ async function ensurePermit2Allowance({
|
|
|
547
639
|
);
|
|
548
640
|
}
|
|
549
641
|
|
|
550
|
-
// src/core/
|
|
642
|
+
// src/core/execute/handleEvmExecution.ts
|
|
551
643
|
async function handleEvmExecution({
|
|
552
644
|
recipientAddress,
|
|
553
645
|
quote,
|
|
@@ -555,15 +647,19 @@ async function handleEvmExecution({
|
|
|
555
647
|
accountAddress,
|
|
556
648
|
wallet,
|
|
557
649
|
isSingleChain,
|
|
558
|
-
|
|
559
|
-
|
|
650
|
+
update,
|
|
651
|
+
orderType,
|
|
652
|
+
options
|
|
560
653
|
}) {
|
|
561
|
-
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
654
|
+
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage] ?? "";
|
|
655
|
+
const deadline = options?.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
562
656
|
await wallet.switchChain(chainId);
|
|
563
657
|
const tokenIn = normalizeNative(chainId, quote.tokenIn.address);
|
|
658
|
+
quote.tokenOut.address = normalizeEvmTokenAddress(quote.tokenOut.address);
|
|
564
659
|
const shouldWrapNative = isNativeAddress(quote.tokenIn.address);
|
|
565
660
|
update("processing", shouldWrapNative ? `${messageFor("processing")} (wrapping native token)` : messageFor("processing"));
|
|
566
661
|
if (shouldWrapNative) {
|
|
662
|
+
quote.tokenIn.address === tokenIn;
|
|
567
663
|
await wallet.sendTransaction({
|
|
568
664
|
to: tokenIn,
|
|
569
665
|
data: encodeFunctionData2({
|
|
@@ -590,7 +686,9 @@ async function handleEvmExecution({
|
|
|
590
686
|
accountAddress,
|
|
591
687
|
destination,
|
|
592
688
|
deadline,
|
|
593
|
-
isSingleChain
|
|
689
|
+
isSingleChain,
|
|
690
|
+
orderType,
|
|
691
|
+
options
|
|
594
692
|
});
|
|
595
693
|
console.debug(`order`, order);
|
|
596
694
|
update("processing", messageFor("signing"));
|
|
@@ -614,17 +712,28 @@ async function handleEvmExecution({
|
|
|
614
712
|
update("initiated", messageFor("initiated"));
|
|
615
713
|
const { intentId: orderId } = res.data;
|
|
616
714
|
update("initiated", messageFor("shogun_processing"));
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
715
|
+
if (orderType === "limit" /* LIMIT */) {
|
|
716
|
+
update("success", messageFor("success_limit"));
|
|
717
|
+
return {
|
|
718
|
+
status: true,
|
|
719
|
+
orderId,
|
|
720
|
+
chainId,
|
|
721
|
+
finalStatus: "OrderPlaced",
|
|
722
|
+
stage: "success"
|
|
723
|
+
};
|
|
724
|
+
} else {
|
|
725
|
+
const status = await pollOrderStatus(accountAddress, orderId);
|
|
726
|
+
return await handleOrderPollingResult({
|
|
727
|
+
status,
|
|
728
|
+
orderId,
|
|
729
|
+
chainId,
|
|
730
|
+
update,
|
|
731
|
+
messageFor
|
|
732
|
+
});
|
|
733
|
+
}
|
|
625
734
|
}
|
|
626
735
|
|
|
627
|
-
// src/core/
|
|
736
|
+
// src/core/execute/handleSolanaExecution.ts
|
|
628
737
|
import {
|
|
629
738
|
getSolanaSingleChainOrderInstructions,
|
|
630
739
|
getSolanaCrossChainOrderInstructions
|
|
@@ -637,12 +746,14 @@ async function handleSolanaExecution({
|
|
|
637
746
|
isSingleChain,
|
|
638
747
|
update,
|
|
639
748
|
accountAddress,
|
|
640
|
-
|
|
749
|
+
orderType,
|
|
750
|
+
options
|
|
641
751
|
}) {
|
|
642
752
|
if (!wallet.rpcUrl) {
|
|
643
753
|
throw new Error("Solana wallet is missing rpcUrl");
|
|
644
754
|
}
|
|
645
|
-
const
|
|
755
|
+
const deadline = options?.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
756
|
+
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage] ?? "";
|
|
646
757
|
update("processing", messageFor("processing"));
|
|
647
758
|
const destination = recipientAddress ?? accountAddress;
|
|
648
759
|
const order = await buildOrder({
|
|
@@ -650,7 +761,9 @@ async function handleSolanaExecution({
|
|
|
650
761
|
accountAddress,
|
|
651
762
|
destination,
|
|
652
763
|
deadline,
|
|
653
|
-
isSingleChain
|
|
764
|
+
isSingleChain,
|
|
765
|
+
orderType,
|
|
766
|
+
options
|
|
654
767
|
});
|
|
655
768
|
const txData = await getSolanaOrderInstructions({
|
|
656
769
|
order,
|
|
@@ -672,14 +785,25 @@ async function handleSolanaExecution({
|
|
|
672
785
|
update("initiated", messageFor("initiated"));
|
|
673
786
|
const { jwt, intentId: orderId } = response.data;
|
|
674
787
|
update("initiated", messageFor("shogun_processing"));
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
788
|
+
if (orderType === "limit" /* LIMIT */) {
|
|
789
|
+
update("success", messageFor("success_limit"));
|
|
790
|
+
return {
|
|
791
|
+
status: true,
|
|
792
|
+
orderId,
|
|
793
|
+
chainId: SOLANA_CHAIN_ID,
|
|
794
|
+
finalStatus: "OrderPlaced",
|
|
795
|
+
stage: "success"
|
|
796
|
+
};
|
|
797
|
+
} else {
|
|
798
|
+
const status = await pollOrderStatus(jwt, orderId);
|
|
799
|
+
return await handleOrderPollingResult({
|
|
800
|
+
status,
|
|
801
|
+
orderId,
|
|
802
|
+
chainId: SOLANA_CHAIN_ID,
|
|
803
|
+
update,
|
|
804
|
+
messageFor
|
|
805
|
+
});
|
|
806
|
+
}
|
|
683
807
|
}
|
|
684
808
|
async function getSolanaOrderInstructions({
|
|
685
809
|
order,
|
|
@@ -712,13 +836,14 @@ async function submitToAuctioneer({
|
|
|
712
836
|
});
|
|
713
837
|
}
|
|
714
838
|
|
|
715
|
-
// src/core/
|
|
839
|
+
// src/core/execute/execute.ts
|
|
716
840
|
async function executeOrder({
|
|
717
841
|
quote,
|
|
718
842
|
accountAddress,
|
|
719
843
|
recipientAddress,
|
|
720
844
|
wallet,
|
|
721
845
|
onStatus,
|
|
846
|
+
orderType = "market" /* MARKET */,
|
|
722
847
|
options = {}
|
|
723
848
|
}) {
|
|
724
849
|
const isDev = process.env.NODE_ENV !== "production";
|
|
@@ -731,21 +856,31 @@ async function executeOrder({
|
|
|
731
856
|
onStatus?.(stage, message ?? messageFor(stage));
|
|
732
857
|
};
|
|
733
858
|
try {
|
|
734
|
-
const deadline = options.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
735
859
|
log("Starting execution:", {
|
|
736
860
|
accountAddress,
|
|
737
861
|
recipientAddress,
|
|
738
|
-
deadline,
|
|
739
862
|
tokenIn: quote?.tokenIn,
|
|
740
863
|
tokenOut: quote?.tokenOut
|
|
741
864
|
});
|
|
742
865
|
const adapter = normalizeWallet(wallet);
|
|
743
866
|
if (!adapter) throw new Error("No wallet provided");
|
|
744
867
|
const { tokenIn, tokenOut } = quote;
|
|
868
|
+
const srcChain = Number(tokenIn.chainId);
|
|
869
|
+
const destChain = Number(tokenOut.chainId);
|
|
870
|
+
if (!CURRENT_SUPPORTED.includes(srcChain) || !CURRENT_SUPPORTED.includes(destChain)) {
|
|
871
|
+
const unsupportedChains = [
|
|
872
|
+
!CURRENT_SUPPORTED.includes(srcChain) ? srcChain : null,
|
|
873
|
+
!CURRENT_SUPPORTED.includes(destChain) ? destChain : null
|
|
874
|
+
].filter(Boolean).join(", ");
|
|
875
|
+
const errorMsg = `Unsupported chain(s): ${unsupportedChains}`;
|
|
876
|
+
update("error", errorMsg);
|
|
877
|
+
log("Error:", errorMsg);
|
|
878
|
+
throw new Error(errorMsg);
|
|
879
|
+
}
|
|
745
880
|
const isSingleChain = tokenIn.chainId === tokenOut.chainId;
|
|
746
881
|
const chainId = Number(tokenIn.chainId);
|
|
747
882
|
update("processing");
|
|
748
|
-
if (
|
|
883
|
+
if (isEvmChain3(chainId)) {
|
|
749
884
|
log("Detected EVM chain:", chainId);
|
|
750
885
|
const result = await handleEvmExecution({
|
|
751
886
|
recipientAddress,
|
|
@@ -754,13 +889,14 @@ async function executeOrder({
|
|
|
754
889
|
accountAddress,
|
|
755
890
|
wallet: adapter,
|
|
756
891
|
isSingleChain,
|
|
757
|
-
|
|
758
|
-
|
|
892
|
+
update,
|
|
893
|
+
orderType,
|
|
894
|
+
options
|
|
759
895
|
});
|
|
760
896
|
log("EVM execution result:", result);
|
|
761
897
|
return result;
|
|
762
898
|
}
|
|
763
|
-
if (chainId ===
|
|
899
|
+
if (chainId === ChainID2.Solana) {
|
|
764
900
|
log("Detected Solana chain");
|
|
765
901
|
const result = await handleSolanaExecution({
|
|
766
902
|
recipientAddress,
|
|
@@ -768,8 +904,9 @@ async function executeOrder({
|
|
|
768
904
|
accountAddress,
|
|
769
905
|
wallet: adapter,
|
|
770
906
|
isSingleChain,
|
|
771
|
-
|
|
772
|
-
|
|
907
|
+
update,
|
|
908
|
+
orderType,
|
|
909
|
+
options
|
|
773
910
|
});
|
|
774
911
|
log("Solana execution result:", result);
|
|
775
912
|
return result;
|
|
@@ -779,8 +916,13 @@ async function executeOrder({
|
|
|
779
916
|
log("Error:", unsupported);
|
|
780
917
|
return { status: false, message: unsupported, stage: "error" };
|
|
781
918
|
} catch (error) {
|
|
782
|
-
|
|
783
|
-
|
|
919
|
+
let message = "An unknown error occurred";
|
|
920
|
+
if (error && typeof error === "object") {
|
|
921
|
+
const err = error;
|
|
922
|
+
message = err.details ?? err.message ?? message;
|
|
923
|
+
} else if (typeof error === "string") {
|
|
924
|
+
message = error;
|
|
925
|
+
}
|
|
784
926
|
update("error", message);
|
|
785
927
|
return { status: false, message, stage: "error" };
|
|
786
928
|
}
|
|
@@ -791,20 +933,147 @@ function normalizeWallet(wallet) {
|
|
|
791
933
|
return wallet;
|
|
792
934
|
}
|
|
793
935
|
|
|
794
|
-
// src/core/
|
|
795
|
-
|
|
936
|
+
// src/core/client.ts
|
|
937
|
+
var SwapSDK = class {
|
|
938
|
+
constructor(config) {
|
|
939
|
+
__publicField(this, "apiKey");
|
|
940
|
+
/**
|
|
941
|
+
* Fetches metadata for one or more tokens from the Shogun Token Search API.
|
|
942
|
+
*
|
|
943
|
+
* ---
|
|
944
|
+
* ### Overview
|
|
945
|
+
* `getTokensData` retrieves normalized token information — such as symbol, name,
|
|
946
|
+
* decimals, logo URI, and verified status — for a given list of token addresses.
|
|
947
|
+
*
|
|
948
|
+
* It supports both **EVM** and **SVM (Solana)** tokens, returning metadata from
|
|
949
|
+
* Shogun’s unified token registry.
|
|
950
|
+
*
|
|
951
|
+
* ---
|
|
952
|
+
* @example
|
|
953
|
+
* ```ts
|
|
954
|
+
* const tokens = await getTokensData([
|
|
955
|
+
* "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
|
|
956
|
+
* "So11111111111111111111111111111111111111112", // SOL
|
|
957
|
+
* ]);
|
|
958
|
+
*
|
|
959
|
+
* console.log(tokens);
|
|
960
|
+
* [
|
|
961
|
+
* { symbol: "USDC", name: "USD Coin", chainId: 1, decimals: 6, ... },
|
|
962
|
+
* { symbol: "SOL", name: "Solana", chainId: 101, decimals: 9, ... }
|
|
963
|
+
* ]
|
|
964
|
+
* ```
|
|
965
|
+
*
|
|
966
|
+
* @param addresses - An array of token addresses (EVM or SVM) to fetch metadata for.
|
|
967
|
+
* @returns A promise resolving to an array of {@link TokenInfo} objects.
|
|
968
|
+
*
|
|
969
|
+
* @throws Will throw an error if the network request fails or the API responds with a non-OK status.
|
|
970
|
+
*/
|
|
971
|
+
__publicField(this, "getTokensData", getTokensData.bind(this));
|
|
972
|
+
if (!config.apiKey) {
|
|
973
|
+
throw new Error("SwapSDK: Missing API key");
|
|
974
|
+
}
|
|
975
|
+
this.apiKey = config.apiKey;
|
|
976
|
+
if (this.apiKey) void this.apiKey;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Retrieves a swap quote for the given input and output tokens.
|
|
980
|
+
*
|
|
981
|
+
* @param params - Quote parameters including source/destination tokens and amount.
|
|
982
|
+
* @returns A normalized `SwapQuoteResponse` containing output amount, route, and metadata.
|
|
983
|
+
*/
|
|
984
|
+
async getQuote(params) {
|
|
985
|
+
return getQuote(params);
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Fetches token balances for the specified user wallet(s).
|
|
989
|
+
*
|
|
990
|
+
* Supports both EVM and SVM (Solana) wallet addresses.
|
|
991
|
+
*
|
|
992
|
+
* @param params - Wallet address and optional chain filters.
|
|
993
|
+
* @param options - Optional abort signal for cancellation.
|
|
994
|
+
* @returns A unified balance response with per-chain token details.
|
|
995
|
+
*/
|
|
996
|
+
async getBalances(params, options) {
|
|
997
|
+
return getBalances(params, options);
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Retrieves a list of verified tokens based on search query or chain filter.
|
|
1001
|
+
*
|
|
1002
|
+
* @param params - Search parameters (query, chain ID, pagination options).
|
|
1003
|
+
* @returns Paginated `TokenSearchResponse` containing token metadata.
|
|
1004
|
+
*/
|
|
1005
|
+
async getTokenList(params) {
|
|
1006
|
+
return getTokenList(params);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Executes a prepared swap quote using the provided wallet and configuration.
|
|
1010
|
+
*
|
|
1011
|
+
* Handles:
|
|
1012
|
+
* - Token approval (if required)
|
|
1013
|
+
* - Transaction signing and broadcasting
|
|
1014
|
+
* - Confirmation polling and stage-based status updates
|
|
1015
|
+
*
|
|
1016
|
+
* Supports both:
|
|
1017
|
+
* - Market orders (with optional deadline)
|
|
1018
|
+
* - Limit orders (requires executionPrice and deadline)
|
|
1019
|
+
*
|
|
1020
|
+
* @param quote - The swap quote to execute, containing route and metadata.
|
|
1021
|
+
* @param accountAddress - The user's wallet address executing the swap.
|
|
1022
|
+
* @param recipientAddress - Optional recipient address for the output tokens (defaults to sender).
|
|
1023
|
+
* @param wallet - Adapted wallet instance (EVM/Solana) or a standard Viem `WalletClient`.
|
|
1024
|
+
* @param onStatus - Optional callback for receiving execution stage updates and messages.
|
|
1025
|
+
* @param orderType - Defines whether this is a market or limit order.
|
|
1026
|
+
* @param options - Execution parameters (different per order type).
|
|
1027
|
+
*
|
|
1028
|
+
* @returns A finalized execution result containing transaction hash, status, and any returned data.
|
|
1029
|
+
*
|
|
1030
|
+
* @example
|
|
1031
|
+
* ```ts
|
|
1032
|
+
* * Market order
|
|
1033
|
+
* const result = await sdk.executeTransaction({
|
|
1034
|
+
* quote,
|
|
1035
|
+
* accountAddress: "0x123...",
|
|
1036
|
+
* wallet,
|
|
1037
|
+
* orderType: OrderExecutionType.MARKET,
|
|
1038
|
+
* options: { deadline: 1800 },
|
|
1039
|
+
* onStatus: (stage, msg) => console.log(stage, msg),
|
|
1040
|
+
* });
|
|
1041
|
+
*
|
|
1042
|
+
* * Limit order
|
|
1043
|
+
* const result = await sdk.executeTransaction({
|
|
1044
|
+
* quote,
|
|
1045
|
+
* accountAddress: "0x123...",
|
|
1046
|
+
* wallet,
|
|
1047
|
+
* orderType: OrderExecutionType.LIMIT,
|
|
1048
|
+
* options: { executionPrice: "0.0021", deadline: 3600 },
|
|
1049
|
+
* });
|
|
1050
|
+
* ```
|
|
1051
|
+
*/
|
|
1052
|
+
async executeTransaction({
|
|
1053
|
+
quote,
|
|
1054
|
+
accountAddress,
|
|
1055
|
+
recipientAddress,
|
|
1056
|
+
wallet,
|
|
1057
|
+
onStatus,
|
|
1058
|
+
orderType,
|
|
1059
|
+
options
|
|
1060
|
+
}) {
|
|
1061
|
+
return executeOrder({
|
|
1062
|
+
quote,
|
|
1063
|
+
wallet,
|
|
1064
|
+
accountAddress,
|
|
1065
|
+
recipientAddress,
|
|
1066
|
+
onStatus,
|
|
1067
|
+
orderType,
|
|
1068
|
+
options
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
796
1072
|
export {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
SOLANA_CHAIN_ID,
|
|
1073
|
+
ChainId,
|
|
1074
|
+
OrderExecutionType,
|
|
800
1075
|
SupportedChains,
|
|
1076
|
+
SwapSDK,
|
|
801
1077
|
buildQuoteParams,
|
|
802
|
-
|
|
803
|
-
getBalances,
|
|
804
|
-
getQuote,
|
|
805
|
-
getTokenList,
|
|
806
|
-
isEvmChain3 as isEvmChain,
|
|
807
|
-
isNativeAddress,
|
|
808
|
-
isViemWalletClient,
|
|
809
|
-
serializeBigIntsToStrings
|
|
1078
|
+
isEvmChain
|
|
810
1079
|
};
|