@xswap-link/sdk 0.13.0 → 0.13.1
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/CHANGELOG.md +8 -0
- package/dist/index.global.js +67 -67
- package/dist/index.js +79 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +79 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +2 -2
- package/src/context/SwapProvider.tsx +94 -67
package/package.json
CHANGED
|
@@ -222,7 +222,7 @@ export const TxOverview = ({ onCloseClick }: Props) => {
|
|
|
222
222
|
handlers: {
|
|
223
223
|
onSuccess: (data) => {
|
|
224
224
|
setTxStatus(TxStatus.COMPLETED);
|
|
225
|
-
refreshBalance();
|
|
225
|
+
refreshBalance({ forceRpc: true });
|
|
226
226
|
trackTransaction(data);
|
|
227
227
|
if (
|
|
228
228
|
srcChain?.chainId &&
|
|
@@ -400,7 +400,7 @@ export const TxOverview = ({ onCloseClick }: Props) => {
|
|
|
400
400
|
handlers: {
|
|
401
401
|
onSuccess: () => {
|
|
402
402
|
setTxStatus(TxStatus.COMPLETED);
|
|
403
|
-
refreshBalance();
|
|
403
|
+
refreshBalance({ forceRpc: true });
|
|
404
404
|
},
|
|
405
405
|
},
|
|
406
406
|
network: Ecosystem.SOLANA,
|
|
@@ -117,7 +117,7 @@ type SwapContext = {
|
|
|
117
117
|
isFetchingBalances: boolean;
|
|
118
118
|
isExpressDeliveryActive: boolean;
|
|
119
119
|
quoteRoute: () => Promise<void>;
|
|
120
|
-
refreshBalance: () => void;
|
|
120
|
+
refreshBalance: (options?: { forceRpc?: boolean }) => void;
|
|
121
121
|
findTokenDataByAddressAndChain: (
|
|
122
122
|
tokenAddress: string,
|
|
123
123
|
chainId: string,
|
|
@@ -279,6 +279,7 @@ export const SwapProvider = ({
|
|
|
279
279
|
|
|
280
280
|
const routeAbortController = useRef<AbortController | null>(null);
|
|
281
281
|
const refreshSelectedTokenBalanceNonce = useRef(crypto.randomUUID());
|
|
282
|
+
const prevWalletAddresses = useRef<string | undefined>(undefined);
|
|
282
283
|
|
|
283
284
|
// =============================================================================
|
|
284
285
|
// Memoized Values
|
|
@@ -668,77 +669,96 @@ export const SwapProvider = ({
|
|
|
668
669
|
srcValueWei,
|
|
669
670
|
]);
|
|
670
671
|
// refreshes and updates the balance of the source token using its RPC URL.
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
refreshSelectedTokenBalanceNonce.current = nonce;
|
|
683
|
-
setIsFetchingBalance(true);
|
|
684
|
-
let balance = "0";
|
|
685
|
-
if (srcChain?.ecosystem === Ecosystem.EVM && evmAddress) {
|
|
686
|
-
const balanceFromBackend =
|
|
687
|
-
tokenBalances[srcChain?.chainId]?.[srcToken.address];
|
|
688
|
-
if (balanceFromBackend === undefined) {
|
|
689
|
-
const balanceUI = await getBalanceOf(
|
|
690
|
-
evmAddress,
|
|
691
|
-
srcToken.address,
|
|
692
|
-
srcChain?.publicRpcUrls[0],
|
|
693
|
-
);
|
|
694
|
-
balance = humanReadableToWei({
|
|
695
|
-
amount: balanceUI,
|
|
696
|
-
decimals: srcToken.decimals,
|
|
697
|
-
});
|
|
698
|
-
} else {
|
|
699
|
-
balance = balanceFromBackend;
|
|
672
|
+
// pass { forceRpc: true } to skip the backend balances cache (e.g. right
|
|
673
|
+
// after a transaction, when the cached value is already stale).
|
|
674
|
+
const refreshBalance = useCallback(
|
|
675
|
+
async (options?: { forceRpc?: boolean }) => {
|
|
676
|
+
if (
|
|
677
|
+
(!evmAddress && !solanaAddress) ||
|
|
678
|
+
!srcChain?.publicRpcUrls[0] ||
|
|
679
|
+
!srcToken ||
|
|
680
|
+
!srcToken?.address
|
|
681
|
+
) {
|
|
682
|
+
return;
|
|
700
683
|
}
|
|
701
|
-
|
|
702
|
-
const
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
684
|
+
|
|
685
|
+
const nonce = crypto.randomUUID();
|
|
686
|
+
refreshSelectedTokenBalanceNonce.current = nonce;
|
|
687
|
+
setIsFetchingBalance(true);
|
|
688
|
+
let balance = "0";
|
|
689
|
+
if (srcChain?.ecosystem === Ecosystem.EVM && evmAddress) {
|
|
690
|
+
const balanceFromBackend =
|
|
691
|
+
tokenBalances[srcChain?.chainId]?.[srcToken.address];
|
|
692
|
+
if (options?.forceRpc || balanceFromBackend === undefined) {
|
|
693
|
+
const balanceUI = await getBalanceOf(
|
|
694
|
+
evmAddress,
|
|
695
|
+
srcToken.address,
|
|
696
|
+
srcChain?.publicRpcUrls[0],
|
|
697
|
+
);
|
|
698
|
+
balance = humanReadableToWei({
|
|
699
|
+
amount: balanceUI,
|
|
700
|
+
decimals: srcToken.decimals,
|
|
718
701
|
});
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
702
|
+
if (options?.forceRpc && balanceFromBackend !== undefined) {
|
|
703
|
+
// keep the backend cache in sync so token pickers and future
|
|
704
|
+
// non-forced refreshes see the fresh value
|
|
705
|
+
const chainId = srcChain.chainId;
|
|
706
|
+
const tokenAddress = srcToken.address;
|
|
707
|
+
const freshBalance = balance;
|
|
708
|
+
setTokenBalances((prev) => ({
|
|
709
|
+
...prev,
|
|
710
|
+
[chainId]: {
|
|
711
|
+
...prev[chainId],
|
|
712
|
+
[tokenAddress]: freshBalance,
|
|
713
|
+
},
|
|
714
|
+
}));
|
|
715
|
+
}
|
|
729
716
|
} else {
|
|
730
|
-
balance =
|
|
717
|
+
balance = balanceFromBackend;
|
|
718
|
+
}
|
|
719
|
+
} else if (srcChain?.ecosystem === Ecosystem.SOLANA && solanaAddress) {
|
|
720
|
+
const solanaPublicKey = new PublicKey(solanaAddress);
|
|
721
|
+
const connection = new Connection(srcChain.publicRpcUrls[0]!);
|
|
722
|
+
if (srcToken.address === SOLANA_NATIVE_TOKEN_ADDRESS.toBase58()) {
|
|
723
|
+
balance = new BigNumberJS(
|
|
724
|
+
await connection.getBalance(solanaPublicKey),
|
|
725
|
+
).toString();
|
|
726
|
+
} else {
|
|
727
|
+
const tokenAccounts = await connection.getParsedTokenAccountsByOwner(
|
|
728
|
+
solanaPublicKey,
|
|
729
|
+
{
|
|
730
|
+
programId: SOLANA_TOKEN_PROGRAM_ID,
|
|
731
|
+
},
|
|
732
|
+
);
|
|
733
|
+
const token2022Accounts =
|
|
734
|
+
await connection.getParsedTokenAccountsByOwner(solanaPublicKey, {
|
|
735
|
+
programId: SOLANA_TOKEN_2022_PROGRAM_ID,
|
|
736
|
+
});
|
|
737
|
+
const allTokenAccount = [
|
|
738
|
+
...tokenAccounts.value,
|
|
739
|
+
...token2022Accounts.value,
|
|
740
|
+
];
|
|
741
|
+
const tokenAccount = allTokenAccount.find(
|
|
742
|
+
(account) =>
|
|
743
|
+
account.account.data.parsed.info.mint === srcToken.address,
|
|
744
|
+
);
|
|
745
|
+
if (!tokenAccount) {
|
|
746
|
+
balance = "0";
|
|
747
|
+
} else {
|
|
748
|
+
balance = tokenAccount.account.data.parsed.info.tokenAmount.amount;
|
|
749
|
+
}
|
|
731
750
|
}
|
|
732
751
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
}
|
|
752
|
+
if (nonce !== refreshSelectedTokenBalanceNonce.current) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
737
755
|
|
|
738
|
-
|
|
756
|
+
setSrcTokenBalanceWei(balance);
|
|
739
757
|
|
|
740
|
-
|
|
741
|
-
|
|
758
|
+
setIsFetchingBalance(false);
|
|
759
|
+
},
|
|
760
|
+
[evmAddress, solanaAddress, srcChain, srcToken, tokenBalances],
|
|
761
|
+
);
|
|
742
762
|
// retrieves token details for a given token address and chain from supported tokens mapping. (including imported tokens)
|
|
743
763
|
const findTokenDataByAddressAndChain = useCallback(
|
|
744
764
|
(tokenAddress: string, chainId: string): Token | undefined => {
|
|
@@ -801,9 +821,16 @@ export const SwapProvider = ({
|
|
|
801
821
|
quoteRoute();
|
|
802
822
|
}, [quoteRoute]);
|
|
803
823
|
// calls refreshBalance to update source token balance on mount or when refreshBalance changes.
|
|
824
|
+
// when the connected wallet changed, force an RPC read — the cached backend
|
|
825
|
+
// balances still belong to the previous wallet until getBalances resolves.
|
|
804
826
|
useEffect(() => {
|
|
805
|
-
|
|
806
|
-
|
|
827
|
+
const walletAddresses = `${evmAddress ?? ""}:${solanaAddress ?? ""}`;
|
|
828
|
+
const walletChanged =
|
|
829
|
+
prevWalletAddresses.current !== undefined &&
|
|
830
|
+
prevWalletAddresses.current !== walletAddresses;
|
|
831
|
+
prevWalletAddresses.current = walletAddresses;
|
|
832
|
+
refreshBalance(walletChanged ? { forceRpc: true } : undefined);
|
|
833
|
+
}, [refreshBalance, evmAddress, solanaAddress]);
|
|
807
834
|
// fetches user all token balances when a wallet address is available and supported chains are loaded.
|
|
808
835
|
useEffect(() => {
|
|
809
836
|
let isCancelled = false;
|