@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/core.cjs +1050 -165
- package/dist/core.d.cts +4 -136
- package/dist/core.d.ts +4 -136
- package/dist/core.js +1050 -138
- package/dist/index-BGHbFEV3.d.cts +401 -0
- package/dist/index-DB1gT72l.d.ts +401 -0
- package/dist/index.cjs +1038 -535
- package/dist/index.d.cts +4 -9
- package/dist/index.d.ts +4 -9
- package/dist/index.js +1038 -505
- package/dist/react.cjs +1588 -487
- package/dist/react.d.cts +285 -88
- package/dist/react.d.ts +285 -88
- package/dist/react.js +1580 -469
- package/dist/{wallet-MmUIz8GE.d.cts → wallet-B9bKceyN.d.cts} +3 -3
- package/dist/{wallet-MmUIz8GE.d.ts → wallet-B9bKceyN.d.ts} +3 -3
- package/dist/wallet-adapter.cjs +25659 -27
- package/dist/wallet-adapter.d.cts +1 -2
- package/dist/wallet-adapter.d.ts +1 -2
- package/dist/wallet-adapter.js +25679 -16
- package/package.json +44 -14
- package/dist/execute-FaLLPp1i.d.cts +0 -147
- package/dist/execute-HX1fQ7wG.d.ts +0 -147
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
|
-
|
|
24
|
-
|
|
25
|
+
ChainId: () => ChainId,
|
|
26
|
+
OrderExecutionType: () => OrderExecutionType,
|
|
25
27
|
SupportedChains: () => SupportedChains,
|
|
26
|
-
|
|
27
|
-
adaptSolanaWallet: () => adaptSolanaWallet,
|
|
28
|
-
adaptViemWallet: () => adaptViemWallet,
|
|
28
|
+
SwapSDK: () => SwapSDK,
|
|
29
29
|
buildQuoteParams: () => buildQuoteParams,
|
|
30
|
-
|
|
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
|
|
71
|
-
var SOLANA_CHAIN_ID =
|
|
72
|
-
var
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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/
|
|
172
|
+
// src/core/execute/normalizeNative.ts
|
|
156
173
|
function normalizeNative(chainId, address) {
|
|
157
|
-
if ((0,
|
|
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 (
|
|
192
|
+
if (amount <= 0n) {
|
|
175
193
|
throw new Error("Amount must be greater than 0.");
|
|
176
194
|
}
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
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 (
|
|
190
|
-
warning = `\u26A0\uFE0F High slippage tolerance (${
|
|
199
|
+
if (slippagePercent > 10) {
|
|
200
|
+
warning = `\u26A0\uFE0F High slippage tolerance (${slippagePercent.toFixed(2)}%) \u2014 price may vary significantly.`;
|
|
191
201
|
}
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
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
|
|
198
|
-
amountOutUsd
|
|
247
|
+
amountOut,
|
|
248
|
+
amountOutUsd,
|
|
199
249
|
amountInUsd: data.amountInUsd,
|
|
200
|
-
minStablecoinsAmount
|
|
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:
|
|
261
|
+
amountIn: amount,
|
|
212
262
|
pricePerInputToken,
|
|
213
|
-
slippage,
|
|
263
|
+
slippage: slippagePercent,
|
|
214
264
|
internal: {
|
|
215
265
|
...data,
|
|
216
|
-
estimatedAmountOutReduced:
|
|
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,
|
|
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
|
|
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(`${
|
|
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:
|
|
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/
|
|
289
|
-
var
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
|
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
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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,
|
|
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/
|
|
435
|
-
var
|
|
436
|
-
var
|
|
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/
|
|
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
|
|
444
|
-
submitting: "Submitting
|
|
445
|
-
|
|
446
|
-
|
|
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/
|
|
450
|
-
var
|
|
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
|
|
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
|
|
536
|
+
amountOutMin,
|
|
467
537
|
deadline,
|
|
468
538
|
destinationAddress: destination
|
|
469
539
|
});
|
|
470
540
|
}
|
|
471
|
-
return await
|
|
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:
|
|
550
|
+
destinationTokenMinAmount: amountOutMin,
|
|
481
551
|
minStablecoinAmount: quote.minStablecoinsAmount
|
|
482
552
|
});
|
|
483
553
|
}
|
|
484
554
|
|
|
485
|
-
// src/
|
|
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
|
-
|
|
494
|
-
|
|
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,
|
|
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("
|
|
514
|
-
await
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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("
|
|
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
|
-
|
|
534
|
-
|
|
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(
|
|
539
|
-
|
|
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("
|
|
545
|
-
|
|
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/
|
|
549
|
-
var
|
|
550
|
-
var
|
|
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
|
-
|
|
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
|
|
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 =
|
|
579
|
-
update("
|
|
580
|
-
|
|
581
|
-
|
|
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("
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
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,
|
|
878
|
+
return await (0, import_intents_sdk11.getSolanaSingleChainOrderInstructions)(order, {
|
|
606
879
|
rpcUrl
|
|
607
880
|
});
|
|
608
881
|
}
|
|
609
|
-
return await (0,
|
|
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/
|
|
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
|
|
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) =>
|
|
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"
|
|
649
|
-
if ((0,
|
|
650
|
-
|
|
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
|
-
|
|
658
|
-
|
|
956
|
+
update,
|
|
957
|
+
orderType,
|
|
958
|
+
options
|
|
659
959
|
});
|
|
960
|
+
log("EVM execution result:", result);
|
|
961
|
+
return result;
|
|
660
962
|
}
|
|
661
|
-
if (chainId ===
|
|
662
|
-
|
|
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
|
-
|
|
669
|
-
|
|
971
|
+
update,
|
|
972
|
+
orderType,
|
|
973
|
+
options
|
|
670
974
|
});
|
|
975
|
+
log("Solana execution result:", result);
|
|
976
|
+
return result;
|
|
671
977
|
}
|
|
672
|
-
|
|
673
|
-
|
|
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
|
-
|
|
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/
|
|
687
|
-
var
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
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
|
-
|
|
727
|
-
|
|
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
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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/
|
|
846
|
-
var
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const
|
|
852
|
-
const
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
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
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
const
|
|
924
|
-
const
|
|
925
|
-
|
|
926
|
-
if (!
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
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
|
-
}
|
|
960
|
-
|
|
961
|
-
|
|
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
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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
|
-
|
|
979
|
-
|
|
1320
|
+
value: 0n,
|
|
1321
|
+
from: order.user
|
|
1322
|
+
});
|
|
980
1323
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
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
|
+
};
|