@shogun-sdk/swap 0.0.2-test.2 → 0.0.2-test.21
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 +226 -62
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +219 -56
- 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 +260 -109
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +254 -104
- package/dist/react.cjs +266 -115
- package/dist/react.d.cts +6 -40
- package/dist/react.d.ts +6 -40
- package/dist/react.js +255 -105
- package/dist/wallet-adapter.cjs +21 -10
- package/dist/wallet-adapter.js +21 -10
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -182,22 +182,25 @@ async function getQuote(params) {
|
|
|
182
182
|
tokenOut: params.tokenOut.address,
|
|
183
183
|
amount: params.amount
|
|
184
184
|
});
|
|
185
|
-
const
|
|
186
|
-
const slippageDecimal = inputSlippage / 100;
|
|
187
|
-
const slippage = Math.min(Math.max(slippageDecimal, 0), 0.5);
|
|
185
|
+
const slippagePercent = Math.min(Math.max(params.slippage ?? 0.5, 0), 50);
|
|
188
186
|
let warning;
|
|
189
|
-
if (
|
|
190
|
-
warning = `\u26A0\uFE0F High slippage tolerance (${
|
|
187
|
+
if (slippagePercent > 10) {
|
|
188
|
+
warning = `\u26A0\uFE0F High slippage tolerance (${slippagePercent.toFixed(2)}%) \u2014 price may vary significantly.`;
|
|
191
189
|
}
|
|
192
|
-
const estimatedAmountOut = BigInt(data.
|
|
193
|
-
const slippageBps = BigInt(Math.round(
|
|
190
|
+
const estimatedAmountOut = BigInt(data.estimatedAmountOut);
|
|
191
|
+
const slippageBps = BigInt(Math.round(slippagePercent * 100));
|
|
194
192
|
const estimatedAmountOutAfterSlippage = estimatedAmountOut * (10000n - slippageBps) / 10000n;
|
|
193
|
+
const pricePerTokenOutInUsd = data.estimatedAmountOutUsd / Number(data.estimatedAmountOut);
|
|
194
|
+
const amountOutUsdAfterSlippage = Number(estimatedAmountOutAfterSlippage) * pricePerTokenOutInUsd;
|
|
195
|
+
const minStablecoinsAmountValue = BigInt(data.estimatedAmountInAsMinStablecoinAmount);
|
|
196
|
+
const minStablecoinsAmountAfterSlippage = minStablecoinsAmountValue * (10000n - slippageBps) / 10000n;
|
|
195
197
|
const pricePerInputToken = estimatedAmountOut * 10n ** BigInt(params.tokenIn.decimals ?? 18) / BigInt(params.amount);
|
|
196
198
|
return {
|
|
197
|
-
amountOut:
|
|
198
|
-
amountOutUsd:
|
|
199
|
+
amountOut: estimatedAmountOutAfterSlippage,
|
|
200
|
+
amountOutUsd: amountOutUsdAfterSlippage,
|
|
199
201
|
amountInUsd: data.amountInUsd,
|
|
200
|
-
|
|
202
|
+
// Input USD stays the same
|
|
203
|
+
minStablecoinsAmount: minStablecoinsAmountAfterSlippage,
|
|
201
204
|
tokenIn: {
|
|
202
205
|
address: params.tokenIn.address,
|
|
203
206
|
decimals: params.tokenIn.decimals ?? 18,
|
|
@@ -210,10 +213,11 @@ async function getQuote(params) {
|
|
|
210
213
|
},
|
|
211
214
|
amountIn: params.amount,
|
|
212
215
|
pricePerInputToken,
|
|
213
|
-
slippage,
|
|
216
|
+
slippage: slippagePercent,
|
|
214
217
|
internal: {
|
|
215
218
|
...data,
|
|
216
|
-
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage
|
|
219
|
+
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage,
|
|
220
|
+
estimatedAmountOutUsdReduced: amountOutUsdAfterSlippage
|
|
217
221
|
},
|
|
218
222
|
warning
|
|
219
223
|
};
|
|
@@ -286,7 +290,7 @@ async function getBalances(params, options) {
|
|
|
286
290
|
}
|
|
287
291
|
|
|
288
292
|
// src/core/executeOrder/execute.ts
|
|
289
|
-
var
|
|
293
|
+
var import_intents_sdk10 = require("@shogun-sdk/intents-sdk");
|
|
290
294
|
var import_viem4 = require("viem");
|
|
291
295
|
|
|
292
296
|
// src/wallet-adapter/svm-wallet-adapter/adapter.ts
|
|
@@ -297,7 +301,7 @@ var adaptSolanaWallet = (walletAddress, chainId, rpcUrl, signAndSendTransaction)
|
|
|
297
301
|
const getChainId = async () => _chainId;
|
|
298
302
|
const sendTransaction = async (transaction) => {
|
|
299
303
|
const txHash = await signAndSendTransaction(transaction);
|
|
300
|
-
console.
|
|
304
|
+
console.debug(`\u{1F6F0} Sent transaction: ${txHash}`);
|
|
301
305
|
const maxRetries = 20;
|
|
302
306
|
const delayMs = 2e3;
|
|
303
307
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
@@ -389,15 +393,26 @@ var adaptViemWallet = (wallet) => {
|
|
|
389
393
|
if (!isEVMTransaction(transaction)) {
|
|
390
394
|
throw new Error("Expected EVMTransaction but got SolanaTransaction");
|
|
391
395
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
396
|
+
if (wallet.transport.type === "http") {
|
|
397
|
+
const request = await wallet.prepareTransactionRequest({
|
|
398
|
+
to: transaction.to,
|
|
399
|
+
data: transaction.data,
|
|
400
|
+
value: transaction.value,
|
|
401
|
+
chain: wallet.chain
|
|
402
|
+
});
|
|
403
|
+
const serializedTransaction = await wallet.signTransaction(request);
|
|
404
|
+
const tx = await wallet.sendRawTransaction({ serializedTransaction });
|
|
405
|
+
return tx;
|
|
406
|
+
} else {
|
|
407
|
+
const hash = await wallet.sendTransaction({
|
|
408
|
+
to: transaction.to,
|
|
409
|
+
data: transaction.data,
|
|
410
|
+
value: transaction.value,
|
|
411
|
+
chain: wallet.chain,
|
|
412
|
+
account: wallet.account
|
|
413
|
+
});
|
|
414
|
+
return hash;
|
|
415
|
+
}
|
|
401
416
|
};
|
|
402
417
|
const switchChain = async (chainId) => {
|
|
403
418
|
try {
|
|
@@ -432,7 +447,7 @@ var adaptViemWallet = (wallet) => {
|
|
|
432
447
|
};
|
|
433
448
|
|
|
434
449
|
// src/core/executeOrder/handleEvmExecution.ts
|
|
435
|
-
var
|
|
450
|
+
var import_intents_sdk8 = require("@shogun-sdk/intents-sdk");
|
|
436
451
|
var import_viem3 = require("viem");
|
|
437
452
|
|
|
438
453
|
// src/core/executeOrder/stageMessages.ts
|
|
@@ -440,10 +455,12 @@ var DEFAULT_STAGE_MESSAGES = {
|
|
|
440
455
|
processing: "Preparing transaction for execution",
|
|
441
456
|
approving: "Approving token allowance",
|
|
442
457
|
approved: "Token approved successfully",
|
|
443
|
-
signing: "Signing
|
|
444
|
-
submitting: "Submitting
|
|
445
|
-
|
|
446
|
-
|
|
458
|
+
signing: "Signing transaction for submission",
|
|
459
|
+
submitting: "Submitting transaction",
|
|
460
|
+
initiated: "Transaction initiated.",
|
|
461
|
+
success: "Transaction Executed successfully",
|
|
462
|
+
shogun_processing: "Shogun is processing your transaction",
|
|
463
|
+
error: "Transaction failed during submission"
|
|
447
464
|
};
|
|
448
465
|
|
|
449
466
|
// src/core/executeOrder/buildOrder.ts
|
|
@@ -482,6 +499,110 @@ async function buildOrder({
|
|
|
482
499
|
});
|
|
483
500
|
}
|
|
484
501
|
|
|
502
|
+
// src/utils/pollOrderStatus.ts
|
|
503
|
+
var import_intents_sdk7 = require("@shogun-sdk/intents-sdk");
|
|
504
|
+
async function pollOrderStatus(address, orderId, options = {}) {
|
|
505
|
+
const { intervalMs = 2e3, timeoutMs = 3e5 } = options;
|
|
506
|
+
const startTime = Date.now();
|
|
507
|
+
const isDebug = process.env.NODE_ENV !== "production";
|
|
508
|
+
const isEvmAddress = /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
509
|
+
const isSuiAddress = /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
510
|
+
const isSolanaAddress = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
|
|
511
|
+
let queryParam;
|
|
512
|
+
if (isEvmAddress) queryParam = `evmWallets=${address}`;
|
|
513
|
+
else if (isSuiAddress) queryParam = `suiWallets=${address}`;
|
|
514
|
+
else if (isSolanaAddress) queryParam = `solanaWallets=${address}`;
|
|
515
|
+
else throw new Error(`Unrecognized wallet address format: ${address}`);
|
|
516
|
+
const queryUrl = `${import_intents_sdk7.AUCTIONEER_URL}/user_intent?${queryParam}`;
|
|
517
|
+
return new Promise((resolve, reject) => {
|
|
518
|
+
const pollInterval = setInterval(async () => {
|
|
519
|
+
try {
|
|
520
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
521
|
+
clearInterval(pollInterval);
|
|
522
|
+
return resolve("Timeout");
|
|
523
|
+
}
|
|
524
|
+
const res = await fetch(queryUrl, {
|
|
525
|
+
method: "GET",
|
|
526
|
+
headers: { "Content-Type": "application/json" }
|
|
527
|
+
});
|
|
528
|
+
if (!res.ok) {
|
|
529
|
+
clearInterval(pollInterval);
|
|
530
|
+
return reject(
|
|
531
|
+
new Error(`Failed to fetch orders: ${res.status} ${res.statusText}`)
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
const json = await res.json();
|
|
535
|
+
const data = json?.data ?? {};
|
|
536
|
+
const allOrders = [
|
|
537
|
+
...data.crossChainDcaOrders ?? [],
|
|
538
|
+
...data.crossChainLimitOrders ?? [],
|
|
539
|
+
...data.singleChainDcaOrders ?? [],
|
|
540
|
+
...data.singleChainLimitOrders ?? []
|
|
541
|
+
];
|
|
542
|
+
const targetOrder = allOrders.find((o) => o.orderId === orderId);
|
|
543
|
+
if (!targetOrder) {
|
|
544
|
+
if (isDebug)
|
|
545
|
+
console.debug(`[pollOrderStatus] [${orderId}] Not found yet`);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
const { orderStatus } = targetOrder;
|
|
549
|
+
if (isDebug) {
|
|
550
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
551
|
+
console.debug(`targetOrder`, targetOrder);
|
|
552
|
+
console.debug(
|
|
553
|
+
`[pollOrderStatus] [${orderId}] status=${orderStatus} (elapsed ${elapsed}s)`
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
if (["Fulfilled", "Cancelled", "Outdated"].includes(orderStatus)) {
|
|
557
|
+
clearInterval(pollInterval);
|
|
558
|
+
return resolve(orderStatus);
|
|
559
|
+
}
|
|
560
|
+
} catch (error) {
|
|
561
|
+
clearInterval(pollInterval);
|
|
562
|
+
return reject(error);
|
|
563
|
+
}
|
|
564
|
+
}, intervalMs);
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// src/core/executeOrder/handleOrderPollingResult.ts
|
|
569
|
+
async function handleOrderPollingResult({
|
|
570
|
+
status,
|
|
571
|
+
orderId,
|
|
572
|
+
chainId,
|
|
573
|
+
update,
|
|
574
|
+
messageFor
|
|
575
|
+
}) {
|
|
576
|
+
switch (status) {
|
|
577
|
+
case "Fulfilled":
|
|
578
|
+
update("success", messageFor("success"));
|
|
579
|
+
return {
|
|
580
|
+
status: true,
|
|
581
|
+
orderId,
|
|
582
|
+
chainId,
|
|
583
|
+
finalStatus: status,
|
|
584
|
+
stage: "success"
|
|
585
|
+
};
|
|
586
|
+
case "Cancelled":
|
|
587
|
+
update("error", "Order was cancelled before fulfillment");
|
|
588
|
+
break;
|
|
589
|
+
case "Timeout":
|
|
590
|
+
update("error", "Order polling timed out");
|
|
591
|
+
break;
|
|
592
|
+
case "NotFound":
|
|
593
|
+
default:
|
|
594
|
+
update("error", "Order not found");
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
return {
|
|
598
|
+
status: false,
|
|
599
|
+
orderId,
|
|
600
|
+
chainId,
|
|
601
|
+
finalStatus: status,
|
|
602
|
+
stage: "error"
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
|
|
485
606
|
// src/core/executeOrder/handleEvmExecution.ts
|
|
486
607
|
async function handleEvmExecution({
|
|
487
608
|
recipientAddress,
|
|
@@ -510,18 +631,18 @@ async function handleEvmExecution({
|
|
|
510
631
|
from: accountAddress
|
|
511
632
|
});
|
|
512
633
|
}
|
|
513
|
-
update("
|
|
634
|
+
update("processing", messageFor("approving"));
|
|
514
635
|
await wallet.sendTransaction({
|
|
515
636
|
to: tokenIn,
|
|
516
637
|
data: (0, import_viem3.encodeFunctionData)({
|
|
517
638
|
abi: import_viem3.erc20Abi,
|
|
518
639
|
functionName: "approve",
|
|
519
|
-
args: [
|
|
640
|
+
args: [import_intents_sdk8.PERMIT2_ADDRESS[chainId], quote.amountIn]
|
|
520
641
|
}),
|
|
521
642
|
value: 0n,
|
|
522
643
|
from: accountAddress
|
|
523
644
|
});
|
|
524
|
-
update("
|
|
645
|
+
update("processing", messageFor("approved"));
|
|
525
646
|
const destination = recipientAddress ?? accountAddress;
|
|
526
647
|
const order = await buildOrder({
|
|
527
648
|
quote,
|
|
@@ -530,23 +651,40 @@ async function handleEvmExecution({
|
|
|
530
651
|
deadline,
|
|
531
652
|
isSingleChain
|
|
532
653
|
});
|
|
533
|
-
|
|
534
|
-
|
|
654
|
+
console.debug(`order`, order);
|
|
655
|
+
update("processing", messageFor("signing"));
|
|
656
|
+
const { orderTypedData, nonce } = isSingleChain ? await (0, import_intents_sdk8.getEVMSingleChainOrderTypedData)(order) : await (0, import_intents_sdk8.getEVMCrossChainOrderTypedData)(order);
|
|
657
|
+
const typedData = serializeBigIntsToStrings(orderTypedData);
|
|
535
658
|
if (!wallet.signTypedData) {
|
|
536
659
|
throw new Error("Wallet does not support EIP-712 signing");
|
|
537
660
|
}
|
|
538
|
-
const signature = await wallet.signTypedData(
|
|
539
|
-
|
|
661
|
+
const signature = await wallet.signTypedData({
|
|
662
|
+
domain: typedData.domain,
|
|
663
|
+
types: typedData.types,
|
|
664
|
+
primaryType: typedData.primaryType,
|
|
665
|
+
value: typedData.message,
|
|
666
|
+
message: typedData.message
|
|
667
|
+
});
|
|
668
|
+
update("processing", messageFor("submitting"));
|
|
540
669
|
const res = await order.sendToAuctioneer({ signature, nonce: nonce.toString() });
|
|
541
670
|
if (!res.success) {
|
|
542
671
|
throw new Error("Auctioneer submission failed");
|
|
543
672
|
}
|
|
544
|
-
update("
|
|
545
|
-
|
|
673
|
+
update("initiated", messageFor("initiated"));
|
|
674
|
+
const { intentId: orderId } = res.data;
|
|
675
|
+
update("initiated", messageFor("shogun_processing"));
|
|
676
|
+
const status = await pollOrderStatus(accountAddress, orderId);
|
|
677
|
+
return await handleOrderPollingResult({
|
|
678
|
+
status,
|
|
679
|
+
orderId,
|
|
680
|
+
chainId,
|
|
681
|
+
update,
|
|
682
|
+
messageFor
|
|
683
|
+
});
|
|
546
684
|
}
|
|
547
685
|
|
|
548
686
|
// src/core/executeOrder/handleSolanaExecution.ts
|
|
549
|
-
var
|
|
687
|
+
var import_intents_sdk9 = require("@shogun-sdk/intents-sdk");
|
|
550
688
|
var import_web32 = require("@solana/web3.js");
|
|
551
689
|
async function handleSolanaExecution({
|
|
552
690
|
recipientAddress,
|
|
@@ -576,10 +714,9 @@ async function handleSolanaExecution({
|
|
|
576
714
|
rpcUrl: wallet.rpcUrl
|
|
577
715
|
});
|
|
578
716
|
const transaction = import_web32.VersionedTransaction.deserialize(Uint8Array.from(txData.txBytes));
|
|
579
|
-
update("
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
update("submitting", messageFor("submitting"));
|
|
717
|
+
update("processing", messageFor("signing"));
|
|
718
|
+
await wallet.sendTransaction(transaction);
|
|
719
|
+
update("processing", messageFor("submitting"));
|
|
583
720
|
const response = await submitToAuctioneer({
|
|
584
721
|
order,
|
|
585
722
|
isSingleChain,
|
|
@@ -588,13 +725,17 @@ async function handleSolanaExecution({
|
|
|
588
725
|
if (!response.success) {
|
|
589
726
|
throw new Error("Auctioneer submission failed");
|
|
590
727
|
}
|
|
591
|
-
update("
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
728
|
+
update("initiated", messageFor("initiated"));
|
|
729
|
+
const { jwt, intentId: orderId } = response.data;
|
|
730
|
+
update("initiated", messageFor("shogun_processing"));
|
|
731
|
+
const status = await pollOrderStatus(jwt, orderId);
|
|
732
|
+
return await handleOrderPollingResult({
|
|
733
|
+
status,
|
|
734
|
+
orderId,
|
|
735
|
+
chainId: SOLANA_CHAIN_ID,
|
|
736
|
+
update,
|
|
737
|
+
messageFor
|
|
738
|
+
});
|
|
598
739
|
}
|
|
599
740
|
async function getSolanaOrderInstructions({
|
|
600
741
|
order,
|
|
@@ -602,11 +743,11 @@ async function getSolanaOrderInstructions({
|
|
|
602
743
|
rpcUrl
|
|
603
744
|
}) {
|
|
604
745
|
if (isSingleChain) {
|
|
605
|
-
return await (0,
|
|
746
|
+
return await (0, import_intents_sdk9.getSolanaSingleChainOrderInstructions)(order, {
|
|
606
747
|
rpcUrl
|
|
607
748
|
});
|
|
608
749
|
}
|
|
609
|
-
return await (0,
|
|
750
|
+
return await (0, import_intents_sdk9.getSolanaCrossChainOrderInstructions)(order, {
|
|
610
751
|
rpcUrl
|
|
611
752
|
});
|
|
612
753
|
}
|
|
@@ -636,18 +777,33 @@ async function executeOrder({
|
|
|
636
777
|
onStatus,
|
|
637
778
|
options = {}
|
|
638
779
|
}) {
|
|
639
|
-
const
|
|
780
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
781
|
+
const log = (...args) => {
|
|
782
|
+
if (isDev) console.debug("[OneShot::executeOrder]", ...args);
|
|
783
|
+
};
|
|
640
784
|
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
641
|
-
const update = (stage, message) =>
|
|
785
|
+
const update = (stage, message) => {
|
|
786
|
+
log("Stage:", stage, "| Message:", message ?? messageFor(stage));
|
|
787
|
+
onStatus?.(stage, message ?? messageFor(stage));
|
|
788
|
+
};
|
|
642
789
|
try {
|
|
790
|
+
const deadline = options.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
791
|
+
log("Starting execution:", {
|
|
792
|
+
accountAddress,
|
|
793
|
+
recipientAddress,
|
|
794
|
+
deadline,
|
|
795
|
+
tokenIn: quote?.tokenIn,
|
|
796
|
+
tokenOut: quote?.tokenOut
|
|
797
|
+
});
|
|
643
798
|
const adapter = normalizeWallet(wallet);
|
|
644
799
|
if (!adapter) throw new Error("No wallet provided");
|
|
645
800
|
const { tokenIn, tokenOut } = quote;
|
|
646
801
|
const isSingleChain = tokenIn.chainId === tokenOut.chainId;
|
|
647
802
|
const chainId = Number(tokenIn.chainId);
|
|
648
|
-
update("processing"
|
|
649
|
-
if ((0,
|
|
650
|
-
|
|
803
|
+
update("processing");
|
|
804
|
+
if ((0, import_intents_sdk10.isEvmChain)(chainId)) {
|
|
805
|
+
log("Detected EVM chain:", chainId);
|
|
806
|
+
const result = await handleEvmExecution({
|
|
651
807
|
recipientAddress,
|
|
652
808
|
quote,
|
|
653
809
|
chainId,
|
|
@@ -657,9 +813,12 @@ async function executeOrder({
|
|
|
657
813
|
deadline,
|
|
658
814
|
update
|
|
659
815
|
});
|
|
816
|
+
log("EVM execution result:", result);
|
|
817
|
+
return result;
|
|
660
818
|
}
|
|
661
|
-
if (chainId ===
|
|
662
|
-
|
|
819
|
+
if (chainId === import_intents_sdk10.ChainID.Solana) {
|
|
820
|
+
log("Detected Solana chain");
|
|
821
|
+
const result = await handleSolanaExecution({
|
|
663
822
|
recipientAddress,
|
|
664
823
|
quote,
|
|
665
824
|
accountAddress,
|
|
@@ -668,11 +827,16 @@ async function executeOrder({
|
|
|
668
827
|
deadline,
|
|
669
828
|
update
|
|
670
829
|
});
|
|
830
|
+
log("Solana execution result:", result);
|
|
831
|
+
return result;
|
|
671
832
|
}
|
|
672
|
-
|
|
673
|
-
|
|
833
|
+
const unsupported = `Unsupported chain: ${chainId}`;
|
|
834
|
+
update("error", unsupported);
|
|
835
|
+
log("Error:", unsupported);
|
|
836
|
+
return { status: false, message: unsupported, stage: "error" };
|
|
674
837
|
} catch (error) {
|
|
675
838
|
const message = error instanceof import_viem4.BaseError ? error.shortMessage : error instanceof Error ? error.message : String(error);
|
|
839
|
+
log("Execution failed:", { message, error });
|
|
676
840
|
update("error", message);
|
|
677
841
|
return { status: false, message, stage: "error" };
|
|
678
842
|
}
|
|
@@ -853,77 +1017,64 @@ function useQuote(params, options) {
|
|
|
853
1017
|
const autoRefreshMs = options?.autoRefreshMs;
|
|
854
1018
|
const abortRef = (0, import_react3.useRef)(null);
|
|
855
1019
|
const debounceRef = (0, import_react3.useRef)(null);
|
|
856
|
-
const
|
|
1020
|
+
const mounted = (0, import_react3.useRef)(false);
|
|
1021
|
+
const paramsKey = (0, import_react3.useMemo)(
|
|
1022
|
+
() => params ? JSON.stringify(serializeBigIntsToStrings(params)) : null,
|
|
1023
|
+
[params]
|
|
1024
|
+
);
|
|
857
1025
|
(0, import_react3.useEffect)(() => {
|
|
1026
|
+
mounted.current = true;
|
|
858
1027
|
return () => {
|
|
859
|
-
|
|
1028
|
+
mounted.current = false;
|
|
860
1029
|
abortRef.current?.abort();
|
|
861
1030
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
862
1031
|
};
|
|
863
1032
|
}, []);
|
|
864
|
-
const fetchQuote = (0, import_react3.useCallback)(
|
|
865
|
-
async (signal) => {
|
|
866
|
-
if (!params) return;
|
|
867
|
-
try {
|
|
868
|
-
setLoading(true);
|
|
869
|
-
setWarning(null);
|
|
870
|
-
const result = await getQuote({ ...params, signal });
|
|
871
|
-
if (!mountedRef.current) return;
|
|
872
|
-
setData((prev) => {
|
|
873
|
-
if (JSON.stringify(prev) === JSON.stringify(result)) return prev;
|
|
874
|
-
return result;
|
|
875
|
-
});
|
|
876
|
-
setWarning(result.warning ?? null);
|
|
877
|
-
setError(null);
|
|
878
|
-
} catch (err) {
|
|
879
|
-
if (err.name === "AbortError") return;
|
|
880
|
-
const e = err instanceof Error ? err : new Error(String(err));
|
|
881
|
-
if (mountedRef.current) setError(e);
|
|
882
|
-
} finally {
|
|
883
|
-
if (mountedRef.current) setLoading(false);
|
|
884
|
-
}
|
|
885
|
-
},
|
|
886
|
-
[params]
|
|
887
|
-
);
|
|
888
|
-
(0, import_react3.useEffect)(() => {
|
|
1033
|
+
const fetchQuote = (0, import_react3.useCallback)(async () => {
|
|
889
1034
|
if (!params) return;
|
|
1035
|
+
try {
|
|
1036
|
+
setLoading(true);
|
|
1037
|
+
setWarning(null);
|
|
1038
|
+
const result = await getQuote(params);
|
|
1039
|
+
const serializeResult = serializeBigIntsToStrings(result);
|
|
1040
|
+
if (!mounted.current) return;
|
|
1041
|
+
setData((prev) => {
|
|
1042
|
+
if (JSON.stringify(prev) === JSON.stringify(serializeResult)) return prev;
|
|
1043
|
+
return serializeResult;
|
|
1044
|
+
});
|
|
1045
|
+
setWarning(result.warning ?? null);
|
|
1046
|
+
setError(null);
|
|
1047
|
+
} catch (err) {
|
|
1048
|
+
if (err.name === "AbortError") return;
|
|
1049
|
+
console.error("[useQuote] fetch error:", err);
|
|
1050
|
+
if (mounted.current) setError(err instanceof Error ? err : new Error(String(err)));
|
|
1051
|
+
} finally {
|
|
1052
|
+
if (mounted.current) setLoading(false);
|
|
1053
|
+
}
|
|
1054
|
+
}, [paramsKey]);
|
|
1055
|
+
(0, import_react3.useEffect)(() => {
|
|
1056
|
+
if (!paramsKey) return;
|
|
890
1057
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
891
|
-
abortRef.current?.abort();
|
|
892
|
-
const controller = new AbortController();
|
|
893
|
-
abortRef.current = controller;
|
|
894
1058
|
debounceRef.current = setTimeout(() => {
|
|
895
|
-
fetchQuote(
|
|
1059
|
+
fetchQuote();
|
|
896
1060
|
}, debounceMs);
|
|
897
1061
|
return () => {
|
|
898
|
-
controller.abort();
|
|
899
1062
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
1063
|
+
abortRef.current?.abort();
|
|
900
1064
|
};
|
|
901
|
-
}, [
|
|
902
|
-
params?.tokenIn?.address,
|
|
903
|
-
params?.tokenOut?.address,
|
|
904
|
-
params?.sourceChainId,
|
|
905
|
-
params?.destChainId,
|
|
906
|
-
params?.amount,
|
|
907
|
-
debounceMs,
|
|
908
|
-
fetchQuote
|
|
909
|
-
]);
|
|
1065
|
+
}, [paramsKey, debounceMs, fetchQuote]);
|
|
910
1066
|
(0, import_react3.useEffect)(() => {
|
|
911
|
-
if (!autoRefreshMs || !
|
|
1067
|
+
if (!autoRefreshMs || !paramsKey) return;
|
|
912
1068
|
const interval = setInterval(() => fetchQuote(), autoRefreshMs);
|
|
913
1069
|
return () => clearInterval(interval);
|
|
914
|
-
}, [autoRefreshMs,
|
|
1070
|
+
}, [autoRefreshMs, paramsKey, fetchQuote]);
|
|
915
1071
|
return (0, import_react3.useMemo)(
|
|
916
1072
|
() => ({
|
|
917
|
-
/** Latest quote data */
|
|
918
1073
|
data,
|
|
919
|
-
/** Whether a fetch is ongoing */
|
|
920
1074
|
loading,
|
|
921
|
-
/** Error (if any) */
|
|
922
1075
|
error,
|
|
923
|
-
/** Warning (e.g. high slippage alert) */
|
|
924
1076
|
warning,
|
|
925
|
-
|
|
926
|
-
refetch: () => fetchQuote()
|
|
1077
|
+
refetch: fetchQuote
|
|
927
1078
|
}),
|
|
928
1079
|
[data, loading, error, warning, fetchQuote]
|
|
929
1080
|
);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { NATIVE_TOKEN, SOLANA_CHAIN_ID, SupportedChains, buildQuoteParams, getBalances, getQuote, getTokenList, isNativeAddress, isViemWalletClient, serializeBigIntsToStrings } from './core.cjs';
|
|
2
|
-
export { B as BalanceRequestParams, c as BalanceResponse, P as PlaceOrderResult, Q as QuoteTokenInfo, b as Stage, S as SwapQuoteParams, a as SwapQuoteResponse, T as TokenBalance, f as TokenInfo, d as TokenSearchResponse, e as executeOrder } from './execute-
|
|
2
|
+
export { B as BalanceRequestParams, c as BalanceResponse, P as PlaceOrderResult, Q as QuoteTokenInfo, b as Stage, S as SwapQuoteParams, a as SwapQuoteResponse, T as TokenBalance, f as TokenInfo, d as TokenSearchResponse, e as executeOrder } from './execute-DOv1i2Su.cjs';
|
|
3
3
|
export { ChainID, isEvmChain } from '@shogun-sdk/intents-sdk';
|
|
4
4
|
export { useBalances, useExecuteOrder, useQuote, useTokenList } from './react.cjs';
|
|
5
5
|
export { adaptEthersSigner, adaptSolanaWallet, adaptViemWallet } from './wallet-adapter.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { NATIVE_TOKEN, SOLANA_CHAIN_ID, SupportedChains, buildQuoteParams, getBalances, getQuote, getTokenList, isNativeAddress, isViemWalletClient, serializeBigIntsToStrings } from './core.js';
|
|
2
|
-
export { B as BalanceRequestParams, c as BalanceResponse, P as PlaceOrderResult, Q as QuoteTokenInfo, b as Stage, S as SwapQuoteParams, a as SwapQuoteResponse, T as TokenBalance, f as TokenInfo, d as TokenSearchResponse, e as executeOrder } from './execute-
|
|
2
|
+
export { B as BalanceRequestParams, c as BalanceResponse, P as PlaceOrderResult, Q as QuoteTokenInfo, b as Stage, S as SwapQuoteParams, a as SwapQuoteResponse, T as TokenBalance, f as TokenInfo, d as TokenSearchResponse, e as executeOrder } from './execute-CKTsf_tD.js';
|
|
3
3
|
export { ChainID, isEvmChain } from '@shogun-sdk/intents-sdk';
|
|
4
4
|
export { useBalances, useExecuteOrder, useQuote, useTokenList } from './react.js';
|
|
5
5
|
export { adaptEthersSigner, adaptSolanaWallet, adaptViemWallet } from './wallet-adapter.js';
|