@shogun-sdk/swap 0.0.2-test
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/README.md +274 -0
- package/dist/core.cjs +619 -0
- package/dist/core.d.cts +137 -0
- package/dist/core.d.ts +137 -0
- package/dist/core.js +590 -0
- package/dist/execute-FaLLPp1i.d.cts +147 -0
- package/dist/execute-HX1fQ7wG.d.ts +147 -0
- package/dist/index.cjs +2477 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +2458 -0
- package/dist/react.cjs +2364 -0
- package/dist/react.d.cts +158 -0
- package/dist/react.d.ts +158 -0
- package/dist/react.js +2355 -0
- package/dist/wallet-MmUIz8GE.d.cts +29 -0
- package/dist/wallet-MmUIz8GE.d.ts +29 -0
- package/dist/wallet-adapter.cjs +175 -0
- package/dist/wallet-adapter.d.cts +34 -0
- package/dist/wallet-adapter.d.ts +34 -0
- package/dist/wallet-adapter.js +150 -0
- package/package.json +68 -0
package/dist/core.cjs
ADDED
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/core/index.ts
|
|
21
|
+
var core_exports = {};
|
|
22
|
+
__export(core_exports, {
|
|
23
|
+
ChainID: () => import_intents_sdk10.ChainID,
|
|
24
|
+
NATIVE_TOKEN: () => NATIVE_TOKEN,
|
|
25
|
+
SOLANA_CHAIN_ID: () => SOLANA_CHAIN_ID,
|
|
26
|
+
SupportedChains: () => SupportedChains,
|
|
27
|
+
buildQuoteParams: () => buildQuoteParams,
|
|
28
|
+
executeOrder: () => executeOrder,
|
|
29
|
+
getBalances: () => getBalances,
|
|
30
|
+
getQuote: () => getQuote,
|
|
31
|
+
getTokenList: () => getTokenList,
|
|
32
|
+
isEvmChain: () => import_intents_sdk10.isEvmChain,
|
|
33
|
+
isNativeAddress: () => isNativeAddress,
|
|
34
|
+
isViemWalletClient: () => isViemWalletClient,
|
|
35
|
+
serializeBigIntsToStrings: () => serializeBigIntsToStrings
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(core_exports);
|
|
38
|
+
|
|
39
|
+
// src/core/token-list.ts
|
|
40
|
+
var import_intents_sdk = require("@shogun-sdk/intents-sdk");
|
|
41
|
+
async function getTokenList(params) {
|
|
42
|
+
return (0, import_intents_sdk.getTokenList)(params);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/core/getQuote.ts
|
|
46
|
+
var import_intents_sdk4 = require("@shogun-sdk/intents-sdk");
|
|
47
|
+
var import_viem = require("viem");
|
|
48
|
+
|
|
49
|
+
// src/core/executeOrder/normalizeNative.ts
|
|
50
|
+
var import_intents_sdk3 = require("@shogun-sdk/intents-sdk");
|
|
51
|
+
|
|
52
|
+
// src/utils/address.ts
|
|
53
|
+
var NATIVE_TOKEN = {
|
|
54
|
+
ETH: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
|
|
55
|
+
SOL: "So11111111111111111111111111111111111111111",
|
|
56
|
+
SUI: "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI"
|
|
57
|
+
};
|
|
58
|
+
var isNativeAddress = (tokenAddress) => {
|
|
59
|
+
const NATIVE_ADDRESSES = Object.values(SupportedChains).map((chain) => chain.tokenAddress.toLowerCase());
|
|
60
|
+
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
|
61
|
+
return !!tokenAddress && NATIVE_ADDRESSES.includes(normalizedTokenAddress);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// src/utils/chain.ts
|
|
65
|
+
var import_intents_sdk2 = require("@shogun-sdk/intents-sdk");
|
|
66
|
+
var SOLANA_CHAIN_ID = import_intents_sdk2.ChainID.Solana;
|
|
67
|
+
var SupportedChains = [
|
|
68
|
+
{
|
|
69
|
+
id: import_intents_sdk2.ChainID.Arbitrum,
|
|
70
|
+
name: "Arbitrum",
|
|
71
|
+
isEVM: true,
|
|
72
|
+
wrapped: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
73
|
+
symbol: "ETH",
|
|
74
|
+
decimals: 18,
|
|
75
|
+
tokenAddress: NATIVE_TOKEN.ETH
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: import_intents_sdk2.ChainID.Optimism,
|
|
79
|
+
name: "Optimism",
|
|
80
|
+
isEVM: true,
|
|
81
|
+
wrapped: "0x4200000000000000000000000000000000000006",
|
|
82
|
+
symbol: "ETH",
|
|
83
|
+
decimals: 18,
|
|
84
|
+
tokenAddress: NATIVE_TOKEN.ETH
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: import_intents_sdk2.ChainID.Base,
|
|
88
|
+
name: "Base",
|
|
89
|
+
isEVM: true,
|
|
90
|
+
wrapped: "0x4200000000000000000000000000000000000006",
|
|
91
|
+
symbol: "ETH",
|
|
92
|
+
decimals: 18,
|
|
93
|
+
tokenAddress: NATIVE_TOKEN.ETH
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: import_intents_sdk2.ChainID.Hyperliquid,
|
|
97
|
+
name: "Hyperliquid",
|
|
98
|
+
isEVM: true,
|
|
99
|
+
wrapped: "0x5555555555555555555555555555555555555555",
|
|
100
|
+
symbol: "ETH",
|
|
101
|
+
decimals: 18,
|
|
102
|
+
tokenAddress: NATIVE_TOKEN.ETH
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: import_intents_sdk2.ChainID.BSC,
|
|
106
|
+
name: "BSC",
|
|
107
|
+
isEVM: true,
|
|
108
|
+
wrapped: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
|
|
109
|
+
symbol: "BNB",
|
|
110
|
+
decimals: 18,
|
|
111
|
+
tokenAddress: NATIVE_TOKEN.ETH
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: SOLANA_CHAIN_ID,
|
|
115
|
+
name: "Solana",
|
|
116
|
+
isEVM: false,
|
|
117
|
+
wrapped: "So11111111111111111111111111111111111111112",
|
|
118
|
+
symbol: "SOL",
|
|
119
|
+
decimals: 9,
|
|
120
|
+
tokenAddress: NATIVE_TOKEN.SOL
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// src/utils/viem.ts
|
|
125
|
+
function isViemWalletClient(wallet) {
|
|
126
|
+
return wallet.extend !== void 0 && wallet.getPermissions !== void 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/utils/number.ts
|
|
130
|
+
function serializeBigIntsToStrings(obj) {
|
|
131
|
+
if (typeof obj === "bigint") {
|
|
132
|
+
return obj.toString();
|
|
133
|
+
}
|
|
134
|
+
if (typeof obj === "string" && /^\d+n$/.test(obj)) {
|
|
135
|
+
return obj.slice(0, -1);
|
|
136
|
+
}
|
|
137
|
+
if (Array.isArray(obj)) {
|
|
138
|
+
return obj.map((item) => serializeBigIntsToStrings(item));
|
|
139
|
+
}
|
|
140
|
+
if (obj && typeof obj === "object") {
|
|
141
|
+
const result = {};
|
|
142
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
143
|
+
result[key] = serializeBigIntsToStrings(value);
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
return obj;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/core/executeOrder/normalizeNative.ts
|
|
151
|
+
function normalizeNative(chainId, address) {
|
|
152
|
+
if ((0, import_intents_sdk3.isEvmChain)(chainId) && isNativeAddress(address)) {
|
|
153
|
+
const chain = SupportedChains.find((c) => c.id === chainId);
|
|
154
|
+
if (!chain?.wrapped)
|
|
155
|
+
throw new Error(`Wrapped token not found for chainId ${chainId}`);
|
|
156
|
+
return chain.wrapped;
|
|
157
|
+
}
|
|
158
|
+
return address;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/core/getQuote.ts
|
|
162
|
+
async function getQuote(params) {
|
|
163
|
+
if (!params.tokenIn?.address || !params.tokenOut?.address) {
|
|
164
|
+
throw new Error("Both tokenIn and tokenOut must include an address.");
|
|
165
|
+
}
|
|
166
|
+
if (!params.sourceChainId || !params.destChainId) {
|
|
167
|
+
throw new Error("Both sourceChainId and destChainId are required.");
|
|
168
|
+
}
|
|
169
|
+
if (params.amount <= 0n) {
|
|
170
|
+
throw new Error("Amount must be greater than 0.");
|
|
171
|
+
}
|
|
172
|
+
const normalizedTokenIn = normalizeNative(params.sourceChainId, params.tokenIn.address);
|
|
173
|
+
const data = await import_intents_sdk4.QuoteProvider.getQuote({
|
|
174
|
+
sourceChainId: params.sourceChainId,
|
|
175
|
+
destChainId: params.destChainId,
|
|
176
|
+
tokenIn: normalizedTokenIn,
|
|
177
|
+
tokenOut: params.tokenOut.address,
|
|
178
|
+
amount: params.amount
|
|
179
|
+
});
|
|
180
|
+
const inputSlippage = params.slippage ?? 5;
|
|
181
|
+
const slippageDecimal = inputSlippage / 100;
|
|
182
|
+
const slippage = Math.min(Math.max(slippageDecimal, 0), 0.5);
|
|
183
|
+
let warning;
|
|
184
|
+
if (slippage > 0.1) {
|
|
185
|
+
warning = `\u26A0\uFE0F High slippage tolerance (${(slippage * 100).toFixed(2)}%) \u2014 price may vary significantly.`;
|
|
186
|
+
}
|
|
187
|
+
const estimatedAmountOut = BigInt(data.estimatedAmountOutReduced);
|
|
188
|
+
const slippageBps = BigInt(Math.round(slippage * 1e4));
|
|
189
|
+
const estimatedAmountOutAfterSlippage = estimatedAmountOut * (10000n - slippageBps) / 10000n;
|
|
190
|
+
const pricePerInputToken = estimatedAmountOut * 10n ** BigInt(params.tokenIn.decimals ?? 18) / BigInt(params.amount);
|
|
191
|
+
return {
|
|
192
|
+
amountOut: estimatedAmountOut,
|
|
193
|
+
amountOutUsd: data.estimatedAmountOutUsd,
|
|
194
|
+
amountInUsd: data.amountInUsd,
|
|
195
|
+
minStablecoinsAmount: data.estimatedAmountInAsMinStablecoinAmount,
|
|
196
|
+
tokenIn: {
|
|
197
|
+
address: params.tokenIn.address,
|
|
198
|
+
decimals: params.tokenIn.decimals ?? 18,
|
|
199
|
+
chainId: params.sourceChainId
|
|
200
|
+
},
|
|
201
|
+
tokenOut: {
|
|
202
|
+
address: params.tokenOut.address,
|
|
203
|
+
decimals: params.tokenOut.decimals ?? 18,
|
|
204
|
+
chainId: params.destChainId
|
|
205
|
+
},
|
|
206
|
+
amountIn: params.amount,
|
|
207
|
+
pricePerInputToken,
|
|
208
|
+
slippage,
|
|
209
|
+
internal: {
|
|
210
|
+
...data,
|
|
211
|
+
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage
|
|
212
|
+
},
|
|
213
|
+
warning
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function buildQuoteParams({
|
|
217
|
+
tokenIn,
|
|
218
|
+
tokenOut,
|
|
219
|
+
sourceChainId,
|
|
220
|
+
destChainId,
|
|
221
|
+
amount,
|
|
222
|
+
slippage
|
|
223
|
+
}) {
|
|
224
|
+
return {
|
|
225
|
+
tokenIn,
|
|
226
|
+
tokenOut,
|
|
227
|
+
sourceChainId,
|
|
228
|
+
destChainId,
|
|
229
|
+
amount: (0, import_viem.parseUnits)(amount.toString(), tokenIn.decimals ?? 18),
|
|
230
|
+
slippage
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/core/getBalances.ts
|
|
235
|
+
var import_intents_sdk5 = require("@shogun-sdk/intents-sdk");
|
|
236
|
+
async function getBalances(params, options) {
|
|
237
|
+
const { addresses, cursorEvm, cursorSvm } = params;
|
|
238
|
+
const { signal } = options ?? {};
|
|
239
|
+
if (!addresses?.evm && !addresses?.svm) {
|
|
240
|
+
throw new Error("At least one address (EVM or SVM) must be provided.");
|
|
241
|
+
}
|
|
242
|
+
const payload = JSON.stringify({
|
|
243
|
+
addresses,
|
|
244
|
+
cursorEvm,
|
|
245
|
+
cursorSvm
|
|
246
|
+
});
|
|
247
|
+
const start = performance.now();
|
|
248
|
+
const response = await fetch(`${import_intents_sdk5.TOKEN_SEARCH_API_BASE_URL}/tokens/balances`, {
|
|
249
|
+
method: "POST",
|
|
250
|
+
headers: {
|
|
251
|
+
accept: "application/json",
|
|
252
|
+
"Content-Type": "application/json"
|
|
253
|
+
},
|
|
254
|
+
body: payload,
|
|
255
|
+
signal
|
|
256
|
+
}).catch((err) => {
|
|
257
|
+
if (err.name === "AbortError") {
|
|
258
|
+
throw new Error("Balance request was cancelled.");
|
|
259
|
+
}
|
|
260
|
+
throw err;
|
|
261
|
+
});
|
|
262
|
+
if (!response.ok) {
|
|
263
|
+
const text = await response.text().catch(() => "");
|
|
264
|
+
throw new Error(`Failed to fetch balances: ${response.status} ${text}`);
|
|
265
|
+
}
|
|
266
|
+
const data = await response.json().catch(() => {
|
|
267
|
+
throw new Error("Invalid JSON response from balances API.");
|
|
268
|
+
});
|
|
269
|
+
const duration = (performance.now() - start).toFixed(1);
|
|
270
|
+
if (process.env.NODE_ENV !== "production") {
|
|
271
|
+
console.debug(`[Shogun SDK] Fetched balances in ${duration}ms`);
|
|
272
|
+
}
|
|
273
|
+
const evmItems = data.evm?.items ?? [];
|
|
274
|
+
const svmItems = data.svm?.items ?? [];
|
|
275
|
+
const combined = [...evmItems, ...svmItems];
|
|
276
|
+
return {
|
|
277
|
+
results: combined,
|
|
278
|
+
nextCursorEvm: data.evm?.cursor ?? null,
|
|
279
|
+
nextCursorSvm: data.svm?.cursor ?? null
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// src/core/executeOrder/execute.ts
|
|
284
|
+
var import_intents_sdk9 = require("@shogun-sdk/intents-sdk");
|
|
285
|
+
var import_viem4 = require("viem");
|
|
286
|
+
|
|
287
|
+
// src/wallet-adapter/evm-wallet-adapter/adapter.ts
|
|
288
|
+
var import_ethers = require("ethers/lib/ethers.js");
|
|
289
|
+
var import_utils2 = require("ethers/lib/utils.js");
|
|
290
|
+
var import_viem2 = require("viem");
|
|
291
|
+
function isEVMTransaction(tx) {
|
|
292
|
+
return typeof tx.from === "string";
|
|
293
|
+
}
|
|
294
|
+
var adaptViemWallet = (wallet) => {
|
|
295
|
+
const signTypedData = async (signData) => {
|
|
296
|
+
return await wallet.signTypedData({
|
|
297
|
+
account: wallet.account,
|
|
298
|
+
domain: signData.domain,
|
|
299
|
+
types: signData.types,
|
|
300
|
+
primaryType: signData.primaryType ?? "Order",
|
|
301
|
+
message: signData.value
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
const sendTransaction = async (transaction) => {
|
|
305
|
+
if (!isEVMTransaction(transaction)) {
|
|
306
|
+
throw new Error("Expected EVMTransaction but got SolanaTransaction");
|
|
307
|
+
}
|
|
308
|
+
const tx = await wallet.sendTransaction({
|
|
309
|
+
from: transaction.from,
|
|
310
|
+
to: transaction.to,
|
|
311
|
+
data: transaction.data,
|
|
312
|
+
value: transaction.value,
|
|
313
|
+
account: wallet.account?.address,
|
|
314
|
+
chain: wallet.chain
|
|
315
|
+
});
|
|
316
|
+
return tx;
|
|
317
|
+
};
|
|
318
|
+
const switchChain = async (chainId) => {
|
|
319
|
+
try {
|
|
320
|
+
await wallet.switchChain({ id: chainId });
|
|
321
|
+
} catch (e) {
|
|
322
|
+
const msg = e?.message || "";
|
|
323
|
+
if (msg.includes("does not support the requested chain")) {
|
|
324
|
+
throw new Error("Wallet does not support this chain");
|
|
325
|
+
}
|
|
326
|
+
if (msg.includes("rejected")) throw e;
|
|
327
|
+
if (msg.includes("already pending")) return;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
const address = async () => {
|
|
331
|
+
let addr = wallet.account?.address;
|
|
332
|
+
if (!addr) {
|
|
333
|
+
const addresses = await wallet.getAddresses();
|
|
334
|
+
addr = addresses[0];
|
|
335
|
+
}
|
|
336
|
+
if (!addr) throw new Error("No address found");
|
|
337
|
+
return addr;
|
|
338
|
+
};
|
|
339
|
+
return {
|
|
340
|
+
vmType: "EVM" /* EVM */,
|
|
341
|
+
transport: (0, import_viem2.custom)(wallet.transport),
|
|
342
|
+
getChainId: async () => wallet.getChainId(),
|
|
343
|
+
address,
|
|
344
|
+
sendTransaction,
|
|
345
|
+
signTypedData,
|
|
346
|
+
switchChain
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// src/core/executeOrder/handleEvmExecution.ts
|
|
351
|
+
var import_intents_sdk7 = require("@shogun-sdk/intents-sdk");
|
|
352
|
+
var import_viem3 = require("viem");
|
|
353
|
+
|
|
354
|
+
// src/core/executeOrder/stageMessages.ts
|
|
355
|
+
var DEFAULT_STAGE_MESSAGES = {
|
|
356
|
+
processing: "Preparing transaction for execution",
|
|
357
|
+
approving: "Approving token allowance",
|
|
358
|
+
approved: "Token approved successfully",
|
|
359
|
+
signing: "Signing order for submission",
|
|
360
|
+
submitting: "Submitting order to Auctioneer",
|
|
361
|
+
success: "Order executed successfully",
|
|
362
|
+
error: "Order execution failed"
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// src/core/executeOrder/buildOrder.ts
|
|
366
|
+
var import_intents_sdk6 = require("@shogun-sdk/intents-sdk");
|
|
367
|
+
async function buildOrder({
|
|
368
|
+
quote,
|
|
369
|
+
accountAddress,
|
|
370
|
+
destination,
|
|
371
|
+
deadline,
|
|
372
|
+
isSingleChain
|
|
373
|
+
}) {
|
|
374
|
+
const { tokenIn, tokenOut } = quote;
|
|
375
|
+
if (isSingleChain) {
|
|
376
|
+
return await import_intents_sdk6.SingleChainOrder.create({
|
|
377
|
+
user: accountAddress,
|
|
378
|
+
chainId: tokenIn.chainId,
|
|
379
|
+
tokenIn: tokenIn.address,
|
|
380
|
+
tokenOut: tokenOut.address,
|
|
381
|
+
amountIn: quote.amountIn,
|
|
382
|
+
amountOutMin: quote.internal.estimatedAmountOutReduced,
|
|
383
|
+
deadline,
|
|
384
|
+
destinationAddress: destination
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return await import_intents_sdk6.CrossChainOrder.create({
|
|
388
|
+
user: accountAddress,
|
|
389
|
+
sourceChainId: tokenIn.chainId,
|
|
390
|
+
sourceTokenAddress: tokenIn.address,
|
|
391
|
+
sourceTokenAmount: quote.amountIn,
|
|
392
|
+
destinationChainId: tokenOut.chainId,
|
|
393
|
+
destinationTokenAddress: tokenOut.address,
|
|
394
|
+
destinationAddress: destination,
|
|
395
|
+
deadline,
|
|
396
|
+
destinationTokenMinAmount: quote.internal.estimatedAmountOutReduced,
|
|
397
|
+
minStablecoinAmount: quote.minStablecoinsAmount
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// src/core/executeOrder/handleEvmExecution.ts
|
|
402
|
+
async function handleEvmExecution({
|
|
403
|
+
recipientAddress,
|
|
404
|
+
quote,
|
|
405
|
+
chainId,
|
|
406
|
+
accountAddress,
|
|
407
|
+
wallet,
|
|
408
|
+
isSingleChain,
|
|
409
|
+
deadline,
|
|
410
|
+
update
|
|
411
|
+
}) {
|
|
412
|
+
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
413
|
+
await wallet.switchChain(chainId);
|
|
414
|
+
const tokenIn = normalizeNative(chainId, quote.tokenIn.address);
|
|
415
|
+
const shouldWrapNative = isNativeAddress(quote.tokenIn.address);
|
|
416
|
+
update("processing", shouldWrapNative ? `${messageFor("processing")} (wrapping native token)` : messageFor("processing"));
|
|
417
|
+
if (shouldWrapNative) {
|
|
418
|
+
await wallet.sendTransaction({
|
|
419
|
+
to: tokenIn,
|
|
420
|
+
data: (0, import_viem3.encodeFunctionData)({
|
|
421
|
+
abi: [{ type: "function", name: "deposit", stateMutability: "payable", inputs: [], outputs: [] }],
|
|
422
|
+
functionName: "deposit",
|
|
423
|
+
args: []
|
|
424
|
+
}),
|
|
425
|
+
value: BigInt(quote.amountIn),
|
|
426
|
+
from: accountAddress
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
update("approving", messageFor("approving"));
|
|
430
|
+
await wallet.sendTransaction({
|
|
431
|
+
to: tokenIn,
|
|
432
|
+
data: (0, import_viem3.encodeFunctionData)({
|
|
433
|
+
abi: import_viem3.erc20Abi,
|
|
434
|
+
functionName: "approve",
|
|
435
|
+
args: [import_intents_sdk7.PERMIT2_ADDRESS[chainId], BigInt(quote.amountIn)]
|
|
436
|
+
}),
|
|
437
|
+
value: 0n,
|
|
438
|
+
from: accountAddress
|
|
439
|
+
});
|
|
440
|
+
update("approved", messageFor("approved"));
|
|
441
|
+
const destination = recipientAddress ?? accountAddress;
|
|
442
|
+
const order = await buildOrder({
|
|
443
|
+
quote,
|
|
444
|
+
accountAddress,
|
|
445
|
+
destination,
|
|
446
|
+
deadline,
|
|
447
|
+
isSingleChain
|
|
448
|
+
});
|
|
449
|
+
update("signing", messageFor("signing"));
|
|
450
|
+
const { orderTypedData, nonce } = isSingleChain ? await (0, import_intents_sdk7.getEVMSingleChainOrderTypedData)(order) : await (0, import_intents_sdk7.getEVMCrossChainOrderTypedData)(order);
|
|
451
|
+
if (!wallet.signTypedData) {
|
|
452
|
+
throw new Error("Wallet does not support EIP-712 signing");
|
|
453
|
+
}
|
|
454
|
+
const signature = await wallet.signTypedData(serializeBigIntsToStrings(orderTypedData));
|
|
455
|
+
update("submitting", messageFor("submitting"));
|
|
456
|
+
const res = await order.sendToAuctioneer({ signature, nonce: nonce.toString() });
|
|
457
|
+
if (!res.success) {
|
|
458
|
+
throw new Error("Auctioneer submission failed");
|
|
459
|
+
}
|
|
460
|
+
update("success", messageFor("success"));
|
|
461
|
+
return { status: true, txHash: res.data, chainId, stage: "success" };
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// src/core/executeOrder/handleSolanaExecution.ts
|
|
465
|
+
var import_intents_sdk8 = require("@shogun-sdk/intents-sdk");
|
|
466
|
+
var import_web3 = require("@solana/web3.js");
|
|
467
|
+
async function handleSolanaExecution({
|
|
468
|
+
recipientAddress,
|
|
469
|
+
quote,
|
|
470
|
+
wallet,
|
|
471
|
+
isSingleChain,
|
|
472
|
+
update,
|
|
473
|
+
accountAddress,
|
|
474
|
+
deadline
|
|
475
|
+
}) {
|
|
476
|
+
if (!wallet.rpcUrl) {
|
|
477
|
+
throw new Error("Solana wallet is missing rpcUrl");
|
|
478
|
+
}
|
|
479
|
+
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
480
|
+
update("processing", messageFor("processing"));
|
|
481
|
+
const destination = recipientAddress ?? accountAddress;
|
|
482
|
+
const order = await buildOrder({
|
|
483
|
+
quote,
|
|
484
|
+
accountAddress,
|
|
485
|
+
destination,
|
|
486
|
+
deadline,
|
|
487
|
+
isSingleChain
|
|
488
|
+
});
|
|
489
|
+
const txData = await getSolanaOrderInstructions({
|
|
490
|
+
order,
|
|
491
|
+
isSingleChain,
|
|
492
|
+
rpcUrl: wallet.rpcUrl
|
|
493
|
+
});
|
|
494
|
+
const transaction = import_web3.VersionedTransaction.deserialize(Uint8Array.from(txData.txBytes));
|
|
495
|
+
update("signing", messageFor("signing"));
|
|
496
|
+
console.log({ order });
|
|
497
|
+
const txSignature = await wallet.sendTransaction(transaction);
|
|
498
|
+
update("submitting", messageFor("submitting"));
|
|
499
|
+
const response = await submitToAuctioneer({
|
|
500
|
+
order,
|
|
501
|
+
isSingleChain,
|
|
502
|
+
txData
|
|
503
|
+
});
|
|
504
|
+
if (!response.success) {
|
|
505
|
+
throw new Error("Auctioneer submission failed");
|
|
506
|
+
}
|
|
507
|
+
update("success", messageFor("success"));
|
|
508
|
+
return {
|
|
509
|
+
status: true,
|
|
510
|
+
txHash: txSignature,
|
|
511
|
+
chainId: import_intents_sdk8.ChainID.Solana,
|
|
512
|
+
stage: "success"
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
async function getSolanaOrderInstructions({
|
|
516
|
+
order,
|
|
517
|
+
isSingleChain,
|
|
518
|
+
rpcUrl
|
|
519
|
+
}) {
|
|
520
|
+
if (isSingleChain) {
|
|
521
|
+
return await (0, import_intents_sdk8.getSolanaSingleChainOrderInstructions)(order, {
|
|
522
|
+
rpcUrl
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
return await (0, import_intents_sdk8.getSolanaCrossChainOrderInstructions)(order, {
|
|
526
|
+
rpcUrl
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
async function submitToAuctioneer({
|
|
530
|
+
order,
|
|
531
|
+
isSingleChain,
|
|
532
|
+
txData
|
|
533
|
+
}) {
|
|
534
|
+
if (isSingleChain) {
|
|
535
|
+
const { orderAddress, secretNumber } = txData;
|
|
536
|
+
return await order.sendToAuctioneer({
|
|
537
|
+
orderPubkey: orderAddress,
|
|
538
|
+
secretNumber
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
return await order.sendToAuctioneer({
|
|
542
|
+
orderPubkey: txData.orderAddress
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// src/core/executeOrder/execute.ts
|
|
547
|
+
async function executeOrder({
|
|
548
|
+
quote,
|
|
549
|
+
accountAddress,
|
|
550
|
+
recipientAddress,
|
|
551
|
+
wallet,
|
|
552
|
+
onStatus,
|
|
553
|
+
options = {}
|
|
554
|
+
}) {
|
|
555
|
+
const deadline = options.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
556
|
+
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
557
|
+
const update = (stage, message) => onStatus?.(stage, message ?? messageFor(stage));
|
|
558
|
+
try {
|
|
559
|
+
const adapter = normalizeWallet(wallet);
|
|
560
|
+
if (!adapter) throw new Error("No wallet provided");
|
|
561
|
+
const { tokenIn, tokenOut } = quote;
|
|
562
|
+
const isSingleChain = tokenIn.chainId === tokenOut.chainId;
|
|
563
|
+
const chainId = Number(tokenIn.chainId);
|
|
564
|
+
update("processing", messageFor("processing"));
|
|
565
|
+
if ((0, import_intents_sdk9.isEvmChain)(chainId)) {
|
|
566
|
+
return await handleEvmExecution({
|
|
567
|
+
recipientAddress,
|
|
568
|
+
quote,
|
|
569
|
+
chainId,
|
|
570
|
+
accountAddress,
|
|
571
|
+
wallet: adapter,
|
|
572
|
+
isSingleChain,
|
|
573
|
+
deadline,
|
|
574
|
+
update
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
if (chainId === import_intents_sdk9.ChainID.Solana) {
|
|
578
|
+
return await handleSolanaExecution({
|
|
579
|
+
recipientAddress,
|
|
580
|
+
quote,
|
|
581
|
+
accountAddress,
|
|
582
|
+
wallet: adapter,
|
|
583
|
+
isSingleChain,
|
|
584
|
+
deadline,
|
|
585
|
+
update
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
update("error", "Unsupported chain");
|
|
589
|
+
return { status: false, message: "Unsupported chain", stage: "error" };
|
|
590
|
+
} catch (error) {
|
|
591
|
+
const message = error instanceof import_viem4.BaseError ? error.shortMessage : error instanceof Error ? error.message : String(error);
|
|
592
|
+
update("error", message);
|
|
593
|
+
return { status: false, message, stage: "error" };
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
function normalizeWallet(wallet) {
|
|
597
|
+
if (!wallet) return void 0;
|
|
598
|
+
if (isViemWalletClient(wallet)) return adaptViemWallet(wallet);
|
|
599
|
+
return wallet;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// src/core/index.ts
|
|
603
|
+
var import_intents_sdk10 = require("@shogun-sdk/intents-sdk");
|
|
604
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
605
|
+
0 && (module.exports = {
|
|
606
|
+
ChainID,
|
|
607
|
+
NATIVE_TOKEN,
|
|
608
|
+
SOLANA_CHAIN_ID,
|
|
609
|
+
SupportedChains,
|
|
610
|
+
buildQuoteParams,
|
|
611
|
+
executeOrder,
|
|
612
|
+
getBalances,
|
|
613
|
+
getQuote,
|
|
614
|
+
getTokenList,
|
|
615
|
+
isEvmChain,
|
|
616
|
+
isNativeAddress,
|
|
617
|
+
isViemWalletClient,
|
|
618
|
+
serializeBigIntsToStrings
|
|
619
|
+
});
|