@shogun-sdk/swap 0.0.2-test.2 → 0.0.2-test.20
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 +222 -62
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +214 -55
- package/dist/{execute-HX1fQ7wG.d.ts → execute-CKTsf_tD.d.ts} +14 -16
- package/dist/{execute-FaLLPp1i.d.cts → execute-DOv1i2Su.d.cts} +14 -16
- package/dist/index.cjs +255 -108
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +248 -102
- package/dist/react.cjs +262 -115
- package/dist/react.d.cts +6 -40
- package/dist/react.d.ts +6 -40
- package/dist/react.js +250 -104
- package/dist/wallet-adapter.cjs +20 -9
- package/dist/wallet-adapter.js +20 -9
- package/package.json +2 -2
package/dist/react.cjs
CHANGED
|
@@ -20,8 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/react/index.ts
|
|
21
21
|
var react_exports = {};
|
|
22
22
|
__export(react_exports, {
|
|
23
|
-
ChainID: () =>
|
|
24
|
-
isEvmChain: () =>
|
|
23
|
+
ChainID: () => import_intents_sdk11.ChainID,
|
|
24
|
+
isEvmChain: () => import_intents_sdk11.isEvmChain,
|
|
25
25
|
useBalances: () => useBalances,
|
|
26
26
|
useExecuteOrder: () => useExecuteOrder,
|
|
27
27
|
useQuote: () => useQuote,
|
|
@@ -112,7 +112,7 @@ function useTokenList(params) {
|
|
|
112
112
|
var import_react2 = require("react");
|
|
113
113
|
|
|
114
114
|
// src/core/executeOrder/execute.ts
|
|
115
|
-
var
|
|
115
|
+
var import_intents_sdk8 = require("@shogun-sdk/intents-sdk");
|
|
116
116
|
var import_viem3 = require("viem");
|
|
117
117
|
|
|
118
118
|
// src/utils/address.ts
|
|
@@ -234,15 +234,26 @@ var adaptViemWallet = (wallet) => {
|
|
|
234
234
|
if (!isEVMTransaction(transaction)) {
|
|
235
235
|
throw new Error("Expected EVMTransaction but got SolanaTransaction");
|
|
236
236
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
237
|
+
if (wallet.transport.type === "http") {
|
|
238
|
+
const request = await wallet.prepareTransactionRequest({
|
|
239
|
+
to: transaction.to,
|
|
240
|
+
data: transaction.data,
|
|
241
|
+
value: transaction.value,
|
|
242
|
+
chain: wallet.chain
|
|
243
|
+
});
|
|
244
|
+
const serializedTransaction = await wallet.signTransaction(request);
|
|
245
|
+
const tx = await wallet.sendRawTransaction({ serializedTransaction });
|
|
246
|
+
return tx;
|
|
247
|
+
} else {
|
|
248
|
+
const hash = await wallet.sendTransaction({
|
|
249
|
+
to: transaction.to,
|
|
250
|
+
data: transaction.data,
|
|
251
|
+
value: transaction.value,
|
|
252
|
+
chain: wallet.chain,
|
|
253
|
+
account: wallet.account
|
|
254
|
+
});
|
|
255
|
+
return hash;
|
|
256
|
+
}
|
|
246
257
|
};
|
|
247
258
|
const switchChain = async (chainId) => {
|
|
248
259
|
try {
|
|
@@ -277,7 +288,7 @@ var adaptViemWallet = (wallet) => {
|
|
|
277
288
|
};
|
|
278
289
|
|
|
279
290
|
// src/core/executeOrder/handleEvmExecution.ts
|
|
280
|
-
var
|
|
291
|
+
var import_intents_sdk6 = require("@shogun-sdk/intents-sdk");
|
|
281
292
|
var import_viem2 = require("viem");
|
|
282
293
|
|
|
283
294
|
// src/core/executeOrder/normalizeNative.ts
|
|
@@ -297,10 +308,12 @@ var DEFAULT_STAGE_MESSAGES = {
|
|
|
297
308
|
processing: "Preparing transaction for execution",
|
|
298
309
|
approving: "Approving token allowance",
|
|
299
310
|
approved: "Token approved successfully",
|
|
300
|
-
signing: "Signing
|
|
301
|
-
submitting: "Submitting
|
|
302
|
-
|
|
303
|
-
|
|
311
|
+
signing: "Signing transaction for submission",
|
|
312
|
+
submitting: "Submitting transaction",
|
|
313
|
+
initiated: "Transaction initiated.",
|
|
314
|
+
success: "Transaction Executed successfully",
|
|
315
|
+
shogun_processing: "Shogun is processing your transaction",
|
|
316
|
+
error: "Transaction failed during submission"
|
|
304
317
|
};
|
|
305
318
|
|
|
306
319
|
// src/core/executeOrder/buildOrder.ts
|
|
@@ -339,6 +352,106 @@ async function buildOrder({
|
|
|
339
352
|
});
|
|
340
353
|
}
|
|
341
354
|
|
|
355
|
+
// src/utils/pollOrderStatus.ts
|
|
356
|
+
var import_intents_sdk5 = require("@shogun-sdk/intents-sdk");
|
|
357
|
+
async function pollOrderStatus(address, orderId, options = {}) {
|
|
358
|
+
const { intervalMs = 2e3, timeoutMs = 3e5 } = options;
|
|
359
|
+
const startTime = Date.now();
|
|
360
|
+
const isEvmAddress = /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
361
|
+
const isSuiAddress = /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
362
|
+
const isSolanaAddress = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
|
|
363
|
+
let queryParam;
|
|
364
|
+
if (isEvmAddress) {
|
|
365
|
+
queryParam = `evmWallets=${address}`;
|
|
366
|
+
} else if (isSuiAddress) {
|
|
367
|
+
queryParam = `suiWallets=${address}`;
|
|
368
|
+
} else if (isSolanaAddress) {
|
|
369
|
+
queryParam = `solanaWallets=${address}`;
|
|
370
|
+
} else {
|
|
371
|
+
throw new Error(`Unrecognized wallet address format: ${address}`);
|
|
372
|
+
}
|
|
373
|
+
const queryUrl = `${import_intents_sdk5.AUCTIONEER_URL}/user_intent?${queryParam}`;
|
|
374
|
+
return new Promise((resolve, reject) => {
|
|
375
|
+
const pollInterval = setInterval(async () => {
|
|
376
|
+
try {
|
|
377
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
378
|
+
clearInterval(pollInterval);
|
|
379
|
+
return resolve("Timeout");
|
|
380
|
+
}
|
|
381
|
+
const res = await fetch(queryUrl, {
|
|
382
|
+
method: "GET",
|
|
383
|
+
headers: { "Content-Type": "application/json" }
|
|
384
|
+
});
|
|
385
|
+
if (!res.ok) {
|
|
386
|
+
clearInterval(pollInterval);
|
|
387
|
+
return reject(
|
|
388
|
+
new Error(`Failed to fetch orders: ${res.status} ${res.statusText}`)
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
const json = await res.json();
|
|
392
|
+
const data = json?.data ?? {};
|
|
393
|
+
const allOrders = [
|
|
394
|
+
...data.crossChainDcaOrders ?? [],
|
|
395
|
+
...data.crossChainLimitOrders ?? [],
|
|
396
|
+
...data.singleChainDcaOrders ?? [],
|
|
397
|
+
...data.singleChainLimitOrders ?? []
|
|
398
|
+
];
|
|
399
|
+
const targetOrder = allOrders.find((o) => o.orderId === orderId);
|
|
400
|
+
if (!targetOrder) {
|
|
401
|
+
clearInterval(pollInterval);
|
|
402
|
+
return resolve("NotFound");
|
|
403
|
+
}
|
|
404
|
+
const { orderStatus } = targetOrder;
|
|
405
|
+
if (["Fulfilled", "Cancelled", "Outdated"].includes(orderStatus)) {
|
|
406
|
+
clearInterval(pollInterval);
|
|
407
|
+
return resolve(orderStatus);
|
|
408
|
+
}
|
|
409
|
+
} catch (error) {
|
|
410
|
+
clearInterval(pollInterval);
|
|
411
|
+
return reject(error);
|
|
412
|
+
}
|
|
413
|
+
}, intervalMs);
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// src/core/executeOrder/handleOrderPollingResult.ts
|
|
418
|
+
async function handleOrderPollingResult({
|
|
419
|
+
status,
|
|
420
|
+
orderId,
|
|
421
|
+
chainId,
|
|
422
|
+
update,
|
|
423
|
+
messageFor
|
|
424
|
+
}) {
|
|
425
|
+
switch (status) {
|
|
426
|
+
case "Fulfilled":
|
|
427
|
+
update("success", messageFor("success"));
|
|
428
|
+
return {
|
|
429
|
+
status: true,
|
|
430
|
+
orderId,
|
|
431
|
+
chainId,
|
|
432
|
+
finalStatus: status,
|
|
433
|
+
stage: "success"
|
|
434
|
+
};
|
|
435
|
+
case "Cancelled":
|
|
436
|
+
update("error", "Order was cancelled before fulfillment");
|
|
437
|
+
break;
|
|
438
|
+
case "Timeout":
|
|
439
|
+
update("error", "Order polling timed out");
|
|
440
|
+
break;
|
|
441
|
+
case "NotFound":
|
|
442
|
+
default:
|
|
443
|
+
update("error", "Order not found");
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
status: false,
|
|
448
|
+
orderId,
|
|
449
|
+
chainId,
|
|
450
|
+
finalStatus: status,
|
|
451
|
+
stage: "error"
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
342
455
|
// src/core/executeOrder/handleEvmExecution.ts
|
|
343
456
|
async function handleEvmExecution({
|
|
344
457
|
recipientAddress,
|
|
@@ -367,18 +480,18 @@ async function handleEvmExecution({
|
|
|
367
480
|
from: accountAddress
|
|
368
481
|
});
|
|
369
482
|
}
|
|
370
|
-
update("
|
|
483
|
+
update("processing", messageFor("approving"));
|
|
371
484
|
await wallet.sendTransaction({
|
|
372
485
|
to: tokenIn,
|
|
373
486
|
data: (0, import_viem2.encodeFunctionData)({
|
|
374
487
|
abi: import_viem2.erc20Abi,
|
|
375
488
|
functionName: "approve",
|
|
376
|
-
args: [
|
|
489
|
+
args: [import_intents_sdk6.PERMIT2_ADDRESS[chainId], BigInt(quote.amountIn)]
|
|
377
490
|
}),
|
|
378
491
|
value: 0n,
|
|
379
492
|
from: accountAddress
|
|
380
493
|
});
|
|
381
|
-
update("
|
|
494
|
+
update("processing", messageFor("approved"));
|
|
382
495
|
const destination = recipientAddress ?? accountAddress;
|
|
383
496
|
const order = await buildOrder({
|
|
384
497
|
quote,
|
|
@@ -387,23 +500,39 @@ async function handleEvmExecution({
|
|
|
387
500
|
deadline,
|
|
388
501
|
isSingleChain
|
|
389
502
|
});
|
|
390
|
-
update("
|
|
391
|
-
const { orderTypedData, nonce } = isSingleChain ? await (0,
|
|
503
|
+
update("processing", messageFor("signing"));
|
|
504
|
+
const { orderTypedData, nonce } = isSingleChain ? await (0, import_intents_sdk6.getEVMSingleChainOrderTypedData)(order) : await (0, import_intents_sdk6.getEVMCrossChainOrderTypedData)(order);
|
|
505
|
+
const typedData = serializeBigIntsToStrings(orderTypedData);
|
|
392
506
|
if (!wallet.signTypedData) {
|
|
393
507
|
throw new Error("Wallet does not support EIP-712 signing");
|
|
394
508
|
}
|
|
395
|
-
const signature = await wallet.signTypedData(
|
|
396
|
-
|
|
509
|
+
const signature = await wallet.signTypedData({
|
|
510
|
+
domain: typedData.domain,
|
|
511
|
+
types: typedData.types,
|
|
512
|
+
primaryType: typedData.primaryType,
|
|
513
|
+
value: typedData.message,
|
|
514
|
+
message: typedData.message
|
|
515
|
+
});
|
|
516
|
+
update("processing", messageFor("submitting"));
|
|
397
517
|
const res = await order.sendToAuctioneer({ signature, nonce: nonce.toString() });
|
|
398
518
|
if (!res.success) {
|
|
399
519
|
throw new Error("Auctioneer submission failed");
|
|
400
520
|
}
|
|
401
|
-
update("
|
|
402
|
-
|
|
521
|
+
update("initiated", messageFor("initiated"));
|
|
522
|
+
const { intentId: orderId } = res.data;
|
|
523
|
+
update("initiated", messageFor("shogun_processing"));
|
|
524
|
+
const status = await pollOrderStatus(accountAddress, orderId);
|
|
525
|
+
return await handleOrderPollingResult({
|
|
526
|
+
status,
|
|
527
|
+
orderId,
|
|
528
|
+
chainId,
|
|
529
|
+
update,
|
|
530
|
+
messageFor
|
|
531
|
+
});
|
|
403
532
|
}
|
|
404
533
|
|
|
405
534
|
// src/core/executeOrder/handleSolanaExecution.ts
|
|
406
|
-
var
|
|
535
|
+
var import_intents_sdk7 = require("@shogun-sdk/intents-sdk");
|
|
407
536
|
var import_web3 = require("@solana/web3.js");
|
|
408
537
|
async function handleSolanaExecution({
|
|
409
538
|
recipientAddress,
|
|
@@ -433,10 +562,9 @@ async function handleSolanaExecution({
|
|
|
433
562
|
rpcUrl: wallet.rpcUrl
|
|
434
563
|
});
|
|
435
564
|
const transaction = import_web3.VersionedTransaction.deserialize(Uint8Array.from(txData.txBytes));
|
|
436
|
-
update("
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
update("submitting", messageFor("submitting"));
|
|
565
|
+
update("processing", messageFor("signing"));
|
|
566
|
+
await wallet.sendTransaction(transaction);
|
|
567
|
+
update("processing", messageFor("submitting"));
|
|
440
568
|
const response = await submitToAuctioneer({
|
|
441
569
|
order,
|
|
442
570
|
isSingleChain,
|
|
@@ -445,13 +573,17 @@ async function handleSolanaExecution({
|
|
|
445
573
|
if (!response.success) {
|
|
446
574
|
throw new Error("Auctioneer submission failed");
|
|
447
575
|
}
|
|
448
|
-
update("
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
576
|
+
update("initiated", messageFor("initiated"));
|
|
577
|
+
const { jwt, intentId: orderId } = response.data;
|
|
578
|
+
update("initiated", messageFor("shogun_processing"));
|
|
579
|
+
const status = await pollOrderStatus(jwt, orderId);
|
|
580
|
+
return await handleOrderPollingResult({
|
|
581
|
+
status,
|
|
582
|
+
orderId,
|
|
583
|
+
chainId: SOLANA_CHAIN_ID,
|
|
584
|
+
update,
|
|
585
|
+
messageFor
|
|
586
|
+
});
|
|
455
587
|
}
|
|
456
588
|
async function getSolanaOrderInstructions({
|
|
457
589
|
order,
|
|
@@ -459,11 +591,11 @@ async function getSolanaOrderInstructions({
|
|
|
459
591
|
rpcUrl
|
|
460
592
|
}) {
|
|
461
593
|
if (isSingleChain) {
|
|
462
|
-
return await (0,
|
|
594
|
+
return await (0, import_intents_sdk7.getSolanaSingleChainOrderInstructions)(order, {
|
|
463
595
|
rpcUrl
|
|
464
596
|
});
|
|
465
597
|
}
|
|
466
|
-
return await (0,
|
|
598
|
+
return await (0, import_intents_sdk7.getSolanaCrossChainOrderInstructions)(order, {
|
|
467
599
|
rpcUrl
|
|
468
600
|
});
|
|
469
601
|
}
|
|
@@ -493,18 +625,33 @@ async function executeOrder({
|
|
|
493
625
|
onStatus,
|
|
494
626
|
options = {}
|
|
495
627
|
}) {
|
|
496
|
-
const
|
|
628
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
629
|
+
const log = (...args) => {
|
|
630
|
+
if (isDev) console.log("[OneShot::executeOrder]", ...args);
|
|
631
|
+
};
|
|
497
632
|
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
498
|
-
const update = (stage, message) =>
|
|
633
|
+
const update = (stage, message) => {
|
|
634
|
+
log("Stage:", stage, "| Message:", message ?? messageFor(stage));
|
|
635
|
+
onStatus?.(stage, message ?? messageFor(stage));
|
|
636
|
+
};
|
|
499
637
|
try {
|
|
638
|
+
const deadline = options.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
639
|
+
log("Starting execution:", {
|
|
640
|
+
accountAddress,
|
|
641
|
+
recipientAddress,
|
|
642
|
+
deadline,
|
|
643
|
+
tokenIn: quote?.tokenIn,
|
|
644
|
+
tokenOut: quote?.tokenOut
|
|
645
|
+
});
|
|
500
646
|
const adapter = normalizeWallet(wallet);
|
|
501
647
|
if (!adapter) throw new Error("No wallet provided");
|
|
502
648
|
const { tokenIn, tokenOut } = quote;
|
|
503
649
|
const isSingleChain = tokenIn.chainId === tokenOut.chainId;
|
|
504
650
|
const chainId = Number(tokenIn.chainId);
|
|
505
|
-
update("processing"
|
|
506
|
-
if ((0,
|
|
507
|
-
|
|
651
|
+
update("processing");
|
|
652
|
+
if ((0, import_intents_sdk8.isEvmChain)(chainId)) {
|
|
653
|
+
log("Detected EVM chain:", chainId);
|
|
654
|
+
const result = await handleEvmExecution({
|
|
508
655
|
recipientAddress,
|
|
509
656
|
quote,
|
|
510
657
|
chainId,
|
|
@@ -514,9 +661,12 @@ async function executeOrder({
|
|
|
514
661
|
deadline,
|
|
515
662
|
update
|
|
516
663
|
});
|
|
664
|
+
log("EVM execution result:", result);
|
|
665
|
+
return result;
|
|
517
666
|
}
|
|
518
|
-
if (chainId ===
|
|
519
|
-
|
|
667
|
+
if (chainId === import_intents_sdk8.ChainID.Solana) {
|
|
668
|
+
log("Detected Solana chain");
|
|
669
|
+
const result = await handleSolanaExecution({
|
|
520
670
|
recipientAddress,
|
|
521
671
|
quote,
|
|
522
672
|
accountAddress,
|
|
@@ -525,11 +675,16 @@ async function executeOrder({
|
|
|
525
675
|
deadline,
|
|
526
676
|
update
|
|
527
677
|
});
|
|
678
|
+
log("Solana execution result:", result);
|
|
679
|
+
return result;
|
|
528
680
|
}
|
|
529
|
-
|
|
530
|
-
|
|
681
|
+
const unsupported = `Unsupported chain: ${chainId}`;
|
|
682
|
+
update("error", unsupported);
|
|
683
|
+
log("Error:", unsupported);
|
|
684
|
+
return { status: false, message: unsupported, stage: "error" };
|
|
531
685
|
} catch (error) {
|
|
532
686
|
const message = error instanceof import_viem3.BaseError ? error.shortMessage : error instanceof Error ? error.message : String(error);
|
|
687
|
+
log("Execution failed:", { message, error });
|
|
533
688
|
update("error", message);
|
|
534
689
|
return { status: false, message, stage: "error" };
|
|
535
690
|
}
|
|
@@ -631,7 +786,7 @@ function useExecuteOrder() {
|
|
|
631
786
|
var import_react3 = require("react");
|
|
632
787
|
|
|
633
788
|
// src/core/getQuote.ts
|
|
634
|
-
var
|
|
789
|
+
var import_intents_sdk9 = require("@shogun-sdk/intents-sdk");
|
|
635
790
|
var import_viem4 = require("viem");
|
|
636
791
|
async function getQuote(params) {
|
|
637
792
|
if (!params.tokenIn?.address || !params.tokenOut?.address) {
|
|
@@ -644,29 +799,33 @@ async function getQuote(params) {
|
|
|
644
799
|
throw new Error("Amount must be greater than 0.");
|
|
645
800
|
}
|
|
646
801
|
const normalizedTokenIn = normalizeNative(params.sourceChainId, params.tokenIn.address);
|
|
647
|
-
const data = await
|
|
802
|
+
const data = await import_intents_sdk9.QuoteProvider.getQuote({
|
|
648
803
|
sourceChainId: params.sourceChainId,
|
|
649
804
|
destChainId: params.destChainId,
|
|
650
805
|
tokenIn: normalizedTokenIn,
|
|
651
806
|
tokenOut: params.tokenOut.address,
|
|
652
807
|
amount: params.amount
|
|
653
808
|
});
|
|
654
|
-
|
|
655
|
-
const
|
|
656
|
-
const slippage = Math.min(Math.max(slippageDecimal, 0), 0.5);
|
|
809
|
+
console.log({ data });
|
|
810
|
+
const slippagePercent = Math.min(Math.max(params.slippage ?? 0.5, 0), 50);
|
|
657
811
|
let warning;
|
|
658
|
-
if (
|
|
659
|
-
warning = `\u26A0\uFE0F High slippage tolerance (${
|
|
812
|
+
if (slippagePercent > 10) {
|
|
813
|
+
warning = `\u26A0\uFE0F High slippage tolerance (${slippagePercent.toFixed(2)}%) \u2014 price may vary significantly.`;
|
|
660
814
|
}
|
|
661
|
-
const estimatedAmountOut = BigInt(data.
|
|
662
|
-
const slippageBps = BigInt(Math.round(
|
|
815
|
+
const estimatedAmountOut = BigInt(data.estimatedAmountOut);
|
|
816
|
+
const slippageBps = BigInt(Math.round(slippagePercent * 100));
|
|
663
817
|
const estimatedAmountOutAfterSlippage = estimatedAmountOut * (10000n - slippageBps) / 10000n;
|
|
818
|
+
const pricePerTokenOutInUsd = data.estimatedAmountOutUsd / Number(data.estimatedAmountOut);
|
|
819
|
+
const amountOutUsdAfterSlippage = Number(estimatedAmountOutAfterSlippage) * pricePerTokenOutInUsd;
|
|
820
|
+
const minStablecoinsAmountValue = BigInt(data.estimatedAmountInAsMinStablecoinAmount);
|
|
821
|
+
const minStablecoinsAmountAfterSlippage = minStablecoinsAmountValue * (10000n - slippageBps) / 10000n;
|
|
664
822
|
const pricePerInputToken = estimatedAmountOut * 10n ** BigInt(params.tokenIn.decimals ?? 18) / BigInt(params.amount);
|
|
665
823
|
return {
|
|
666
|
-
amountOut:
|
|
667
|
-
amountOutUsd:
|
|
824
|
+
amountOut: estimatedAmountOutAfterSlippage,
|
|
825
|
+
amountOutUsd: amountOutUsdAfterSlippage,
|
|
668
826
|
amountInUsd: data.amountInUsd,
|
|
669
|
-
|
|
827
|
+
// Input USD stays the same
|
|
828
|
+
minStablecoinsAmount: minStablecoinsAmountAfterSlippage,
|
|
670
829
|
tokenIn: {
|
|
671
830
|
address: params.tokenIn.address,
|
|
672
831
|
decimals: params.tokenIn.decimals ?? 18,
|
|
@@ -679,10 +838,11 @@ async function getQuote(params) {
|
|
|
679
838
|
},
|
|
680
839
|
amountIn: params.amount,
|
|
681
840
|
pricePerInputToken,
|
|
682
|
-
slippage,
|
|
841
|
+
slippage: slippagePercent,
|
|
683
842
|
internal: {
|
|
684
843
|
...data,
|
|
685
|
-
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage
|
|
844
|
+
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage,
|
|
845
|
+
estimatedAmountOutUsdReduced: amountOutUsdAfterSlippage
|
|
686
846
|
},
|
|
687
847
|
warning
|
|
688
848
|
};
|
|
@@ -698,77 +858,64 @@ function useQuote(params, options) {
|
|
|
698
858
|
const autoRefreshMs = options?.autoRefreshMs;
|
|
699
859
|
const abortRef = (0, import_react3.useRef)(null);
|
|
700
860
|
const debounceRef = (0, import_react3.useRef)(null);
|
|
701
|
-
const
|
|
861
|
+
const mounted = (0, import_react3.useRef)(false);
|
|
862
|
+
const paramsKey = (0, import_react3.useMemo)(
|
|
863
|
+
() => params ? JSON.stringify(serializeBigIntsToStrings(params)) : null,
|
|
864
|
+
[params]
|
|
865
|
+
);
|
|
702
866
|
(0, import_react3.useEffect)(() => {
|
|
867
|
+
mounted.current = true;
|
|
703
868
|
return () => {
|
|
704
|
-
|
|
869
|
+
mounted.current = false;
|
|
705
870
|
abortRef.current?.abort();
|
|
706
871
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
707
872
|
};
|
|
708
873
|
}, []);
|
|
709
|
-
const fetchQuote = (0, import_react3.useCallback)(
|
|
710
|
-
async (signal) => {
|
|
711
|
-
if (!params) return;
|
|
712
|
-
try {
|
|
713
|
-
setLoading(true);
|
|
714
|
-
setWarning(null);
|
|
715
|
-
const result = await getQuote({ ...params, signal });
|
|
716
|
-
if (!mountedRef.current) return;
|
|
717
|
-
setData((prev) => {
|
|
718
|
-
if (JSON.stringify(prev) === JSON.stringify(result)) return prev;
|
|
719
|
-
return result;
|
|
720
|
-
});
|
|
721
|
-
setWarning(result.warning ?? null);
|
|
722
|
-
setError(null);
|
|
723
|
-
} catch (err) {
|
|
724
|
-
if (err.name === "AbortError") return;
|
|
725
|
-
const e = err instanceof Error ? err : new Error(String(err));
|
|
726
|
-
if (mountedRef.current) setError(e);
|
|
727
|
-
} finally {
|
|
728
|
-
if (mountedRef.current) setLoading(false);
|
|
729
|
-
}
|
|
730
|
-
},
|
|
731
|
-
[params]
|
|
732
|
-
);
|
|
733
|
-
(0, import_react3.useEffect)(() => {
|
|
874
|
+
const fetchQuote = (0, import_react3.useCallback)(async () => {
|
|
734
875
|
if (!params) return;
|
|
876
|
+
try {
|
|
877
|
+
setLoading(true);
|
|
878
|
+
setWarning(null);
|
|
879
|
+
const result = await getQuote(params);
|
|
880
|
+
const serializeResult = serializeBigIntsToStrings(result);
|
|
881
|
+
if (!mounted.current) return;
|
|
882
|
+
setData((prev) => {
|
|
883
|
+
if (JSON.stringify(prev) === JSON.stringify(serializeResult)) return prev;
|
|
884
|
+
return serializeResult;
|
|
885
|
+
});
|
|
886
|
+
setWarning(result.warning ?? null);
|
|
887
|
+
setError(null);
|
|
888
|
+
} catch (err) {
|
|
889
|
+
if (err.name === "AbortError") return;
|
|
890
|
+
console.error("[useQuote] fetch error:", err);
|
|
891
|
+
if (mounted.current) setError(err instanceof Error ? err : new Error(String(err)));
|
|
892
|
+
} finally {
|
|
893
|
+
if (mounted.current) setLoading(false);
|
|
894
|
+
}
|
|
895
|
+
}, [paramsKey]);
|
|
896
|
+
(0, import_react3.useEffect)(() => {
|
|
897
|
+
if (!paramsKey) return;
|
|
735
898
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
736
|
-
abortRef.current?.abort();
|
|
737
|
-
const controller = new AbortController();
|
|
738
|
-
abortRef.current = controller;
|
|
739
899
|
debounceRef.current = setTimeout(() => {
|
|
740
|
-
fetchQuote(
|
|
900
|
+
fetchQuote();
|
|
741
901
|
}, debounceMs);
|
|
742
902
|
return () => {
|
|
743
|
-
controller.abort();
|
|
744
903
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
904
|
+
abortRef.current?.abort();
|
|
745
905
|
};
|
|
746
|
-
}, [
|
|
747
|
-
params?.tokenIn?.address,
|
|
748
|
-
params?.tokenOut?.address,
|
|
749
|
-
params?.sourceChainId,
|
|
750
|
-
params?.destChainId,
|
|
751
|
-
params?.amount,
|
|
752
|
-
debounceMs,
|
|
753
|
-
fetchQuote
|
|
754
|
-
]);
|
|
906
|
+
}, [paramsKey, debounceMs, fetchQuote]);
|
|
755
907
|
(0, import_react3.useEffect)(() => {
|
|
756
|
-
if (!autoRefreshMs || !
|
|
908
|
+
if (!autoRefreshMs || !paramsKey) return;
|
|
757
909
|
const interval = setInterval(() => fetchQuote(), autoRefreshMs);
|
|
758
910
|
return () => clearInterval(interval);
|
|
759
|
-
}, [autoRefreshMs,
|
|
911
|
+
}, [autoRefreshMs, paramsKey, fetchQuote]);
|
|
760
912
|
return (0, import_react3.useMemo)(
|
|
761
913
|
() => ({
|
|
762
|
-
/** Latest quote data */
|
|
763
914
|
data,
|
|
764
|
-
/** Whether a fetch is ongoing */
|
|
765
915
|
loading,
|
|
766
|
-
/** Error (if any) */
|
|
767
916
|
error,
|
|
768
|
-
/** Warning (e.g. high slippage alert) */
|
|
769
917
|
warning,
|
|
770
|
-
|
|
771
|
-
refetch: () => fetchQuote()
|
|
918
|
+
refetch: fetchQuote
|
|
772
919
|
}),
|
|
773
920
|
[data, loading, error, warning, fetchQuote]
|
|
774
921
|
);
|
|
@@ -778,7 +925,7 @@ function useQuote(params, options) {
|
|
|
778
925
|
var import_react4 = require("react");
|
|
779
926
|
|
|
780
927
|
// src/core/getBalances.ts
|
|
781
|
-
var
|
|
928
|
+
var import_intents_sdk10 = require("@shogun-sdk/intents-sdk");
|
|
782
929
|
async function getBalances(params, options) {
|
|
783
930
|
const { addresses, cursorEvm, cursorSvm } = params;
|
|
784
931
|
const { signal } = options ?? {};
|
|
@@ -791,7 +938,7 @@ async function getBalances(params, options) {
|
|
|
791
938
|
cursorSvm
|
|
792
939
|
});
|
|
793
940
|
const start = performance.now();
|
|
794
|
-
const response = await fetch(`${
|
|
941
|
+
const response = await fetch(`${import_intents_sdk10.TOKEN_SEARCH_API_BASE_URL}/tokens/balances`, {
|
|
795
942
|
method: "POST",
|
|
796
943
|
headers: {
|
|
797
944
|
accept: "application/json",
|
|
@@ -890,7 +1037,7 @@ function useBalances(params) {
|
|
|
890
1037
|
}
|
|
891
1038
|
|
|
892
1039
|
// src/react/index.ts
|
|
893
|
-
var
|
|
1040
|
+
var import_intents_sdk11 = require("@shogun-sdk/intents-sdk");
|
|
894
1041
|
// Annotate the CommonJS export names for ESM import in node:
|
|
895
1042
|
0 && (module.exports = {
|
|
896
1043
|
ChainID,
|
package/dist/react.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TokenSearchParams, TokenSearchResponse } from '@shogun-sdk/intents-sdk';
|
|
2
2
|
export { ChainID, isEvmChain } from '@shogun-sdk/intents-sdk';
|
|
3
|
-
import { a as SwapQuoteResponse, e as executeOrder, b as Stage, S as SwapQuoteParams, B as BalanceRequestParams, c as BalanceResponse } from './execute-
|
|
4
|
-
export { P as PlaceOrderResult, Q as QuoteTokenInfo, T as TokenBalance, f as TokenInfo, d as TokenSearchResponse } from './execute-
|
|
3
|
+
import { a as SwapQuoteResponse, e as executeOrder, b as Stage, g as PollResult, S as SwapQuoteParams, B as BalanceRequestParams, c as BalanceResponse } from './execute-DOv1i2Su.cjs';
|
|
4
|
+
export { P as PlaceOrderResult, Q as QuoteTokenInfo, T as TokenBalance, f as TokenInfo, d as TokenSearchResponse } from './execute-DOv1i2Su.cjs';
|
|
5
5
|
import { A as AdaptedWallet } from './wallet-MmUIz8GE.cjs';
|
|
6
6
|
import { WalletClient } from 'viem';
|
|
7
7
|
import '@mysten/sui/transactions';
|
|
@@ -29,13 +29,6 @@ type ExecuteOrderResult = Awaited<ReturnType<typeof executeOrder>>;
|
|
|
29
29
|
* built-in stage tracking, loading states, and error handling.
|
|
30
30
|
*
|
|
31
31
|
* ---
|
|
32
|
-
* ## Features
|
|
33
|
-
* - Live stage updates (processing, approving, signing, submitting, etc.)
|
|
34
|
-
* - Built-in 20-min deadline by default (current timestamp + 1200s)
|
|
35
|
-
* - Safe state handling with unmount guards
|
|
36
|
-
* - Works for both EVM and Solana wallets
|
|
37
|
-
*
|
|
38
|
-
* ---
|
|
39
32
|
* ## Example
|
|
40
33
|
* ```tsx
|
|
41
34
|
* import { useExecuteOrder } from "@shogun-sdk/swap/react"
|
|
@@ -79,9 +72,10 @@ declare function useExecuteOrder(): {
|
|
|
79
72
|
/** Raw SDK response data. */
|
|
80
73
|
data: {
|
|
81
74
|
status: boolean;
|
|
82
|
-
|
|
75
|
+
orderId: string;
|
|
83
76
|
chainId: number;
|
|
84
|
-
|
|
77
|
+
finalStatus: PollResult;
|
|
78
|
+
stage: Stage;
|
|
85
79
|
} | {
|
|
86
80
|
status: boolean;
|
|
87
81
|
message: string;
|
|
@@ -92,44 +86,16 @@ declare function useExecuteOrder(): {
|
|
|
92
86
|
};
|
|
93
87
|
|
|
94
88
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* @example
|
|
98
|
-
* ```tsx
|
|
99
|
-
* import { useQuote } from "@shogun-sdk/swap/react"
|
|
100
|
-
*
|
|
101
|
-
* export function SwapQuote({ params }) {
|
|
102
|
-
* const { data, loading, error, warning, refetch } = useQuote(params, { debounceMs: 300 })
|
|
103
|
-
*
|
|
104
|
-
* if (loading) return <p>Fetching quote...</p>
|
|
105
|
-
* if (error) return <p style={{ color: "red" }}>{error.message}</p>
|
|
106
|
-
* if (warning) return <p style={{ color: "orange" }}>{warning}</p>
|
|
107
|
-
*
|
|
108
|
-
* return (
|
|
109
|
-
* <div>
|
|
110
|
-
* <p>Output: {data?.amountOut.toString()}</p>
|
|
111
|
-
* <p>Reduced (after slippage): {data?.internal?.estimatedAmountOutReduced?.toString()}</p>
|
|
112
|
-
* <button onClick={refetch}>Refresh</button>
|
|
113
|
-
* </div>
|
|
114
|
-
* )
|
|
115
|
-
* }
|
|
116
|
-
* ```
|
|
89
|
+
* useQuote — React hook for fetching live swap quotes.
|
|
117
90
|
*/
|
|
118
91
|
declare function useQuote(params: SwapQuoteParams | null, options?: {
|
|
119
|
-
/** Debounce duration (ms) for reactive fetches. Default: 250 */
|
|
120
92
|
debounceMs?: number;
|
|
121
|
-
/** Optional polling interval (ms) for auto refresh */
|
|
122
93
|
autoRefreshMs?: number;
|
|
123
94
|
}): {
|
|
124
|
-
/** Latest quote data */
|
|
125
95
|
data: SwapQuoteResponse | null;
|
|
126
|
-
/** Whether a fetch is ongoing */
|
|
127
96
|
loading: boolean;
|
|
128
|
-
/** Error (if any) */
|
|
129
97
|
error: Error | null;
|
|
130
|
-
/** Warning (e.g. high slippage alert) */
|
|
131
98
|
warning: string | null;
|
|
132
|
-
/** Manual refetch */
|
|
133
99
|
refetch: () => Promise<void>;
|
|
134
100
|
};
|
|
135
101
|
|