@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/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,110 @@ 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 isDebug = process.env.NODE_ENV !== "production";
|
|
361
|
+
const isEvmAddress = /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
362
|
+
const isSuiAddress = /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
363
|
+
const isSolanaAddress = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
|
|
364
|
+
let queryParam;
|
|
365
|
+
if (isEvmAddress) queryParam = `evmWallets=${address}`;
|
|
366
|
+
else if (isSuiAddress) queryParam = `suiWallets=${address}`;
|
|
367
|
+
else if (isSolanaAddress) queryParam = `solanaWallets=${address}`;
|
|
368
|
+
else throw new Error(`Unrecognized wallet address format: ${address}`);
|
|
369
|
+
const queryUrl = `${import_intents_sdk5.AUCTIONEER_URL}/user_intent?${queryParam}`;
|
|
370
|
+
return new Promise((resolve, reject) => {
|
|
371
|
+
const pollInterval = setInterval(async () => {
|
|
372
|
+
try {
|
|
373
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
374
|
+
clearInterval(pollInterval);
|
|
375
|
+
return resolve("Timeout");
|
|
376
|
+
}
|
|
377
|
+
const res = await fetch(queryUrl, {
|
|
378
|
+
method: "GET",
|
|
379
|
+
headers: { "Content-Type": "application/json" }
|
|
380
|
+
});
|
|
381
|
+
if (!res.ok) {
|
|
382
|
+
clearInterval(pollInterval);
|
|
383
|
+
return reject(
|
|
384
|
+
new Error(`Failed to fetch orders: ${res.status} ${res.statusText}`)
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
const json = await res.json();
|
|
388
|
+
const data = json?.data ?? {};
|
|
389
|
+
const allOrders = [
|
|
390
|
+
...data.crossChainDcaOrders ?? [],
|
|
391
|
+
...data.crossChainLimitOrders ?? [],
|
|
392
|
+
...data.singleChainDcaOrders ?? [],
|
|
393
|
+
...data.singleChainLimitOrders ?? []
|
|
394
|
+
];
|
|
395
|
+
const targetOrder = allOrders.find((o) => o.orderId === orderId);
|
|
396
|
+
if (!targetOrder) {
|
|
397
|
+
if (isDebug)
|
|
398
|
+
console.debug(`[pollOrderStatus] [${orderId}] Not found yet`);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
const { orderStatus } = targetOrder;
|
|
402
|
+
if (isDebug) {
|
|
403
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
404
|
+
console.debug(`targetOrder`, targetOrder);
|
|
405
|
+
console.debug(
|
|
406
|
+
`[pollOrderStatus] [${orderId}] status=${orderStatus} (elapsed ${elapsed}s)`
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
if (["Fulfilled", "Cancelled", "Outdated"].includes(orderStatus)) {
|
|
410
|
+
clearInterval(pollInterval);
|
|
411
|
+
return resolve(orderStatus);
|
|
412
|
+
}
|
|
413
|
+
} catch (error) {
|
|
414
|
+
clearInterval(pollInterval);
|
|
415
|
+
return reject(error);
|
|
416
|
+
}
|
|
417
|
+
}, intervalMs);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// src/core/executeOrder/handleOrderPollingResult.ts
|
|
422
|
+
async function handleOrderPollingResult({
|
|
423
|
+
status,
|
|
424
|
+
orderId,
|
|
425
|
+
chainId,
|
|
426
|
+
update,
|
|
427
|
+
messageFor
|
|
428
|
+
}) {
|
|
429
|
+
switch (status) {
|
|
430
|
+
case "Fulfilled":
|
|
431
|
+
update("success", messageFor("success"));
|
|
432
|
+
return {
|
|
433
|
+
status: true,
|
|
434
|
+
orderId,
|
|
435
|
+
chainId,
|
|
436
|
+
finalStatus: status,
|
|
437
|
+
stage: "success"
|
|
438
|
+
};
|
|
439
|
+
case "Cancelled":
|
|
440
|
+
update("error", "Order was cancelled before fulfillment");
|
|
441
|
+
break;
|
|
442
|
+
case "Timeout":
|
|
443
|
+
update("error", "Order polling timed out");
|
|
444
|
+
break;
|
|
445
|
+
case "NotFound":
|
|
446
|
+
default:
|
|
447
|
+
update("error", "Order not found");
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
return {
|
|
451
|
+
status: false,
|
|
452
|
+
orderId,
|
|
453
|
+
chainId,
|
|
454
|
+
finalStatus: status,
|
|
455
|
+
stage: "error"
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
342
459
|
// src/core/executeOrder/handleEvmExecution.ts
|
|
343
460
|
async function handleEvmExecution({
|
|
344
461
|
recipientAddress,
|
|
@@ -367,18 +484,18 @@ async function handleEvmExecution({
|
|
|
367
484
|
from: accountAddress
|
|
368
485
|
});
|
|
369
486
|
}
|
|
370
|
-
update("
|
|
487
|
+
update("processing", messageFor("approving"));
|
|
371
488
|
await wallet.sendTransaction({
|
|
372
489
|
to: tokenIn,
|
|
373
490
|
data: (0, import_viem2.encodeFunctionData)({
|
|
374
491
|
abi: import_viem2.erc20Abi,
|
|
375
492
|
functionName: "approve",
|
|
376
|
-
args: [
|
|
493
|
+
args: [import_intents_sdk6.PERMIT2_ADDRESS[chainId], quote.amountIn]
|
|
377
494
|
}),
|
|
378
495
|
value: 0n,
|
|
379
496
|
from: accountAddress
|
|
380
497
|
});
|
|
381
|
-
update("
|
|
498
|
+
update("processing", messageFor("approved"));
|
|
382
499
|
const destination = recipientAddress ?? accountAddress;
|
|
383
500
|
const order = await buildOrder({
|
|
384
501
|
quote,
|
|
@@ -387,23 +504,40 @@ async function handleEvmExecution({
|
|
|
387
504
|
deadline,
|
|
388
505
|
isSingleChain
|
|
389
506
|
});
|
|
390
|
-
|
|
391
|
-
|
|
507
|
+
console.debug(`order`, order);
|
|
508
|
+
update("processing", messageFor("signing"));
|
|
509
|
+
const { orderTypedData, nonce } = isSingleChain ? await (0, import_intents_sdk6.getEVMSingleChainOrderTypedData)(order) : await (0, import_intents_sdk6.getEVMCrossChainOrderTypedData)(order);
|
|
510
|
+
const typedData = serializeBigIntsToStrings(orderTypedData);
|
|
392
511
|
if (!wallet.signTypedData) {
|
|
393
512
|
throw new Error("Wallet does not support EIP-712 signing");
|
|
394
513
|
}
|
|
395
|
-
const signature = await wallet.signTypedData(
|
|
396
|
-
|
|
514
|
+
const signature = await wallet.signTypedData({
|
|
515
|
+
domain: typedData.domain,
|
|
516
|
+
types: typedData.types,
|
|
517
|
+
primaryType: typedData.primaryType,
|
|
518
|
+
value: typedData.message,
|
|
519
|
+
message: typedData.message
|
|
520
|
+
});
|
|
521
|
+
update("processing", messageFor("submitting"));
|
|
397
522
|
const res = await order.sendToAuctioneer({ signature, nonce: nonce.toString() });
|
|
398
523
|
if (!res.success) {
|
|
399
524
|
throw new Error("Auctioneer submission failed");
|
|
400
525
|
}
|
|
401
|
-
update("
|
|
402
|
-
|
|
526
|
+
update("initiated", messageFor("initiated"));
|
|
527
|
+
const { intentId: orderId } = res.data;
|
|
528
|
+
update("initiated", messageFor("shogun_processing"));
|
|
529
|
+
const status = await pollOrderStatus(accountAddress, orderId);
|
|
530
|
+
return await handleOrderPollingResult({
|
|
531
|
+
status,
|
|
532
|
+
orderId,
|
|
533
|
+
chainId,
|
|
534
|
+
update,
|
|
535
|
+
messageFor
|
|
536
|
+
});
|
|
403
537
|
}
|
|
404
538
|
|
|
405
539
|
// src/core/executeOrder/handleSolanaExecution.ts
|
|
406
|
-
var
|
|
540
|
+
var import_intents_sdk7 = require("@shogun-sdk/intents-sdk");
|
|
407
541
|
var import_web3 = require("@solana/web3.js");
|
|
408
542
|
async function handleSolanaExecution({
|
|
409
543
|
recipientAddress,
|
|
@@ -433,10 +567,9 @@ async function handleSolanaExecution({
|
|
|
433
567
|
rpcUrl: wallet.rpcUrl
|
|
434
568
|
});
|
|
435
569
|
const transaction = import_web3.VersionedTransaction.deserialize(Uint8Array.from(txData.txBytes));
|
|
436
|
-
update("
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
update("submitting", messageFor("submitting"));
|
|
570
|
+
update("processing", messageFor("signing"));
|
|
571
|
+
await wallet.sendTransaction(transaction);
|
|
572
|
+
update("processing", messageFor("submitting"));
|
|
440
573
|
const response = await submitToAuctioneer({
|
|
441
574
|
order,
|
|
442
575
|
isSingleChain,
|
|
@@ -445,13 +578,17 @@ async function handleSolanaExecution({
|
|
|
445
578
|
if (!response.success) {
|
|
446
579
|
throw new Error("Auctioneer submission failed");
|
|
447
580
|
}
|
|
448
|
-
update("
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
581
|
+
update("initiated", messageFor("initiated"));
|
|
582
|
+
const { jwt, intentId: orderId } = response.data;
|
|
583
|
+
update("initiated", messageFor("shogun_processing"));
|
|
584
|
+
const status = await pollOrderStatus(jwt, orderId);
|
|
585
|
+
return await handleOrderPollingResult({
|
|
586
|
+
status,
|
|
587
|
+
orderId,
|
|
588
|
+
chainId: SOLANA_CHAIN_ID,
|
|
589
|
+
update,
|
|
590
|
+
messageFor
|
|
591
|
+
});
|
|
455
592
|
}
|
|
456
593
|
async function getSolanaOrderInstructions({
|
|
457
594
|
order,
|
|
@@ -459,11 +596,11 @@ async function getSolanaOrderInstructions({
|
|
|
459
596
|
rpcUrl
|
|
460
597
|
}) {
|
|
461
598
|
if (isSingleChain) {
|
|
462
|
-
return await (0,
|
|
599
|
+
return await (0, import_intents_sdk7.getSolanaSingleChainOrderInstructions)(order, {
|
|
463
600
|
rpcUrl
|
|
464
601
|
});
|
|
465
602
|
}
|
|
466
|
-
return await (0,
|
|
603
|
+
return await (0, import_intents_sdk7.getSolanaCrossChainOrderInstructions)(order, {
|
|
467
604
|
rpcUrl
|
|
468
605
|
});
|
|
469
606
|
}
|
|
@@ -493,18 +630,33 @@ async function executeOrder({
|
|
|
493
630
|
onStatus,
|
|
494
631
|
options = {}
|
|
495
632
|
}) {
|
|
496
|
-
const
|
|
633
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
634
|
+
const log = (...args) => {
|
|
635
|
+
if (isDev) console.debug("[OneShot::executeOrder]", ...args);
|
|
636
|
+
};
|
|
497
637
|
const messageFor = (stage) => DEFAULT_STAGE_MESSAGES[stage];
|
|
498
|
-
const update = (stage, message) =>
|
|
638
|
+
const update = (stage, message) => {
|
|
639
|
+
log("Stage:", stage, "| Message:", message ?? messageFor(stage));
|
|
640
|
+
onStatus?.(stage, message ?? messageFor(stage));
|
|
641
|
+
};
|
|
499
642
|
try {
|
|
643
|
+
const deadline = options.deadline ?? Math.floor(Date.now() / 1e3) + 20 * 60;
|
|
644
|
+
log("Starting execution:", {
|
|
645
|
+
accountAddress,
|
|
646
|
+
recipientAddress,
|
|
647
|
+
deadline,
|
|
648
|
+
tokenIn: quote?.tokenIn,
|
|
649
|
+
tokenOut: quote?.tokenOut
|
|
650
|
+
});
|
|
500
651
|
const adapter = normalizeWallet(wallet);
|
|
501
652
|
if (!adapter) throw new Error("No wallet provided");
|
|
502
653
|
const { tokenIn, tokenOut } = quote;
|
|
503
654
|
const isSingleChain = tokenIn.chainId === tokenOut.chainId;
|
|
504
655
|
const chainId = Number(tokenIn.chainId);
|
|
505
|
-
update("processing"
|
|
506
|
-
if ((0,
|
|
507
|
-
|
|
656
|
+
update("processing");
|
|
657
|
+
if ((0, import_intents_sdk8.isEvmChain)(chainId)) {
|
|
658
|
+
log("Detected EVM chain:", chainId);
|
|
659
|
+
const result = await handleEvmExecution({
|
|
508
660
|
recipientAddress,
|
|
509
661
|
quote,
|
|
510
662
|
chainId,
|
|
@@ -514,9 +666,12 @@ async function executeOrder({
|
|
|
514
666
|
deadline,
|
|
515
667
|
update
|
|
516
668
|
});
|
|
669
|
+
log("EVM execution result:", result);
|
|
670
|
+
return result;
|
|
517
671
|
}
|
|
518
|
-
if (chainId ===
|
|
519
|
-
|
|
672
|
+
if (chainId === import_intents_sdk8.ChainID.Solana) {
|
|
673
|
+
log("Detected Solana chain");
|
|
674
|
+
const result = await handleSolanaExecution({
|
|
520
675
|
recipientAddress,
|
|
521
676
|
quote,
|
|
522
677
|
accountAddress,
|
|
@@ -525,11 +680,16 @@ async function executeOrder({
|
|
|
525
680
|
deadline,
|
|
526
681
|
update
|
|
527
682
|
});
|
|
683
|
+
log("Solana execution result:", result);
|
|
684
|
+
return result;
|
|
528
685
|
}
|
|
529
|
-
|
|
530
|
-
|
|
686
|
+
const unsupported = `Unsupported chain: ${chainId}`;
|
|
687
|
+
update("error", unsupported);
|
|
688
|
+
log("Error:", unsupported);
|
|
689
|
+
return { status: false, message: unsupported, stage: "error" };
|
|
531
690
|
} catch (error) {
|
|
532
691
|
const message = error instanceof import_viem3.BaseError ? error.shortMessage : error instanceof Error ? error.message : String(error);
|
|
692
|
+
log("Execution failed:", { message, error });
|
|
533
693
|
update("error", message);
|
|
534
694
|
return { status: false, message, stage: "error" };
|
|
535
695
|
}
|
|
@@ -631,7 +791,7 @@ function useExecuteOrder() {
|
|
|
631
791
|
var import_react3 = require("react");
|
|
632
792
|
|
|
633
793
|
// src/core/getQuote.ts
|
|
634
|
-
var
|
|
794
|
+
var import_intents_sdk9 = require("@shogun-sdk/intents-sdk");
|
|
635
795
|
var import_viem4 = require("viem");
|
|
636
796
|
async function getQuote(params) {
|
|
637
797
|
if (!params.tokenIn?.address || !params.tokenOut?.address) {
|
|
@@ -644,29 +804,32 @@ async function getQuote(params) {
|
|
|
644
804
|
throw new Error("Amount must be greater than 0.");
|
|
645
805
|
}
|
|
646
806
|
const normalizedTokenIn = normalizeNative(params.sourceChainId, params.tokenIn.address);
|
|
647
|
-
const data = await
|
|
807
|
+
const data = await import_intents_sdk9.QuoteProvider.getQuote({
|
|
648
808
|
sourceChainId: params.sourceChainId,
|
|
649
809
|
destChainId: params.destChainId,
|
|
650
810
|
tokenIn: normalizedTokenIn,
|
|
651
811
|
tokenOut: params.tokenOut.address,
|
|
652
812
|
amount: params.amount
|
|
653
813
|
});
|
|
654
|
-
const
|
|
655
|
-
const slippageDecimal = inputSlippage / 100;
|
|
656
|
-
const slippage = Math.min(Math.max(slippageDecimal, 0), 0.5);
|
|
814
|
+
const slippagePercent = Math.min(Math.max(params.slippage ?? 0.5, 0), 50);
|
|
657
815
|
let warning;
|
|
658
|
-
if (
|
|
659
|
-
warning = `\u26A0\uFE0F High slippage tolerance (${
|
|
816
|
+
if (slippagePercent > 10) {
|
|
817
|
+
warning = `\u26A0\uFE0F High slippage tolerance (${slippagePercent.toFixed(2)}%) \u2014 price may vary significantly.`;
|
|
660
818
|
}
|
|
661
|
-
const estimatedAmountOut = BigInt(data.
|
|
662
|
-
const slippageBps = BigInt(Math.round(
|
|
819
|
+
const estimatedAmountOut = BigInt(data.estimatedAmountOut);
|
|
820
|
+
const slippageBps = BigInt(Math.round(slippagePercent * 100));
|
|
663
821
|
const estimatedAmountOutAfterSlippage = estimatedAmountOut * (10000n - slippageBps) / 10000n;
|
|
822
|
+
const pricePerTokenOutInUsd = data.estimatedAmountOutUsd / Number(data.estimatedAmountOut);
|
|
823
|
+
const amountOutUsdAfterSlippage = Number(estimatedAmountOutAfterSlippage) * pricePerTokenOutInUsd;
|
|
824
|
+
const minStablecoinsAmountValue = BigInt(data.estimatedAmountInAsMinStablecoinAmount);
|
|
825
|
+
const minStablecoinsAmountAfterSlippage = minStablecoinsAmountValue * (10000n - slippageBps) / 10000n;
|
|
664
826
|
const pricePerInputToken = estimatedAmountOut * 10n ** BigInt(params.tokenIn.decimals ?? 18) / BigInt(params.amount);
|
|
665
827
|
return {
|
|
666
|
-
amountOut:
|
|
667
|
-
amountOutUsd:
|
|
828
|
+
amountOut: estimatedAmountOutAfterSlippage,
|
|
829
|
+
amountOutUsd: amountOutUsdAfterSlippage,
|
|
668
830
|
amountInUsd: data.amountInUsd,
|
|
669
|
-
|
|
831
|
+
// Input USD stays the same
|
|
832
|
+
minStablecoinsAmount: minStablecoinsAmountAfterSlippage,
|
|
670
833
|
tokenIn: {
|
|
671
834
|
address: params.tokenIn.address,
|
|
672
835
|
decimals: params.tokenIn.decimals ?? 18,
|
|
@@ -679,10 +842,11 @@ async function getQuote(params) {
|
|
|
679
842
|
},
|
|
680
843
|
amountIn: params.amount,
|
|
681
844
|
pricePerInputToken,
|
|
682
|
-
slippage,
|
|
845
|
+
slippage: slippagePercent,
|
|
683
846
|
internal: {
|
|
684
847
|
...data,
|
|
685
|
-
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage
|
|
848
|
+
estimatedAmountOutReduced: estimatedAmountOutAfterSlippage,
|
|
849
|
+
estimatedAmountOutUsdReduced: amountOutUsdAfterSlippage
|
|
686
850
|
},
|
|
687
851
|
warning
|
|
688
852
|
};
|
|
@@ -698,77 +862,64 @@ function useQuote(params, options) {
|
|
|
698
862
|
const autoRefreshMs = options?.autoRefreshMs;
|
|
699
863
|
const abortRef = (0, import_react3.useRef)(null);
|
|
700
864
|
const debounceRef = (0, import_react3.useRef)(null);
|
|
701
|
-
const
|
|
865
|
+
const mounted = (0, import_react3.useRef)(false);
|
|
866
|
+
const paramsKey = (0, import_react3.useMemo)(
|
|
867
|
+
() => params ? JSON.stringify(serializeBigIntsToStrings(params)) : null,
|
|
868
|
+
[params]
|
|
869
|
+
);
|
|
702
870
|
(0, import_react3.useEffect)(() => {
|
|
871
|
+
mounted.current = true;
|
|
703
872
|
return () => {
|
|
704
|
-
|
|
873
|
+
mounted.current = false;
|
|
705
874
|
abortRef.current?.abort();
|
|
706
875
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
707
876
|
};
|
|
708
877
|
}, []);
|
|
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)(() => {
|
|
878
|
+
const fetchQuote = (0, import_react3.useCallback)(async () => {
|
|
734
879
|
if (!params) return;
|
|
880
|
+
try {
|
|
881
|
+
setLoading(true);
|
|
882
|
+
setWarning(null);
|
|
883
|
+
const result = await getQuote(params);
|
|
884
|
+
const serializeResult = serializeBigIntsToStrings(result);
|
|
885
|
+
if (!mounted.current) return;
|
|
886
|
+
setData((prev) => {
|
|
887
|
+
if (JSON.stringify(prev) === JSON.stringify(serializeResult)) return prev;
|
|
888
|
+
return serializeResult;
|
|
889
|
+
});
|
|
890
|
+
setWarning(result.warning ?? null);
|
|
891
|
+
setError(null);
|
|
892
|
+
} catch (err) {
|
|
893
|
+
if (err.name === "AbortError") return;
|
|
894
|
+
console.error("[useQuote] fetch error:", err);
|
|
895
|
+
if (mounted.current) setError(err instanceof Error ? err : new Error(String(err)));
|
|
896
|
+
} finally {
|
|
897
|
+
if (mounted.current) setLoading(false);
|
|
898
|
+
}
|
|
899
|
+
}, [paramsKey]);
|
|
900
|
+
(0, import_react3.useEffect)(() => {
|
|
901
|
+
if (!paramsKey) return;
|
|
735
902
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
736
|
-
abortRef.current?.abort();
|
|
737
|
-
const controller = new AbortController();
|
|
738
|
-
abortRef.current = controller;
|
|
739
903
|
debounceRef.current = setTimeout(() => {
|
|
740
|
-
fetchQuote(
|
|
904
|
+
fetchQuote();
|
|
741
905
|
}, debounceMs);
|
|
742
906
|
return () => {
|
|
743
|
-
controller.abort();
|
|
744
907
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
908
|
+
abortRef.current?.abort();
|
|
745
909
|
};
|
|
746
|
-
}, [
|
|
747
|
-
params?.tokenIn?.address,
|
|
748
|
-
params?.tokenOut?.address,
|
|
749
|
-
params?.sourceChainId,
|
|
750
|
-
params?.destChainId,
|
|
751
|
-
params?.amount,
|
|
752
|
-
debounceMs,
|
|
753
|
-
fetchQuote
|
|
754
|
-
]);
|
|
910
|
+
}, [paramsKey, debounceMs, fetchQuote]);
|
|
755
911
|
(0, import_react3.useEffect)(() => {
|
|
756
|
-
if (!autoRefreshMs || !
|
|
912
|
+
if (!autoRefreshMs || !paramsKey) return;
|
|
757
913
|
const interval = setInterval(() => fetchQuote(), autoRefreshMs);
|
|
758
914
|
return () => clearInterval(interval);
|
|
759
|
-
}, [autoRefreshMs,
|
|
915
|
+
}, [autoRefreshMs, paramsKey, fetchQuote]);
|
|
760
916
|
return (0, import_react3.useMemo)(
|
|
761
917
|
() => ({
|
|
762
|
-
/** Latest quote data */
|
|
763
918
|
data,
|
|
764
|
-
/** Whether a fetch is ongoing */
|
|
765
919
|
loading,
|
|
766
|
-
/** Error (if any) */
|
|
767
920
|
error,
|
|
768
|
-
/** Warning (e.g. high slippage alert) */
|
|
769
921
|
warning,
|
|
770
|
-
|
|
771
|
-
refetch: () => fetchQuote()
|
|
922
|
+
refetch: fetchQuote
|
|
772
923
|
}),
|
|
773
924
|
[data, loading, error, warning, fetchQuote]
|
|
774
925
|
);
|
|
@@ -778,7 +929,7 @@ function useQuote(params, options) {
|
|
|
778
929
|
var import_react4 = require("react");
|
|
779
930
|
|
|
780
931
|
// src/core/getBalances.ts
|
|
781
|
-
var
|
|
932
|
+
var import_intents_sdk10 = require("@shogun-sdk/intents-sdk");
|
|
782
933
|
async function getBalances(params, options) {
|
|
783
934
|
const { addresses, cursorEvm, cursorSvm } = params;
|
|
784
935
|
const { signal } = options ?? {};
|
|
@@ -791,7 +942,7 @@ async function getBalances(params, options) {
|
|
|
791
942
|
cursorSvm
|
|
792
943
|
});
|
|
793
944
|
const start = performance.now();
|
|
794
|
-
const response = await fetch(`${
|
|
945
|
+
const response = await fetch(`${import_intents_sdk10.TOKEN_SEARCH_API_BASE_URL}/tokens/balances`, {
|
|
795
946
|
method: "POST",
|
|
796
947
|
headers: {
|
|
797
948
|
accept: "application/json",
|
|
@@ -890,7 +1041,7 @@ function useBalances(params) {
|
|
|
890
1041
|
}
|
|
891
1042
|
|
|
892
1043
|
// src/react/index.ts
|
|
893
|
-
var
|
|
1044
|
+
var import_intents_sdk11 = require("@shogun-sdk/intents-sdk");
|
|
894
1045
|
// Annotate the CommonJS export names for ESM import in node:
|
|
895
1046
|
0 && (module.exports = {
|
|
896
1047
|
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
|
|