@orderly.network/ui-transfer 3.1.7 → 3.1.8

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/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import { i18n, useTranslation, Trans } from '@orderly.network/i18n';
2
2
  import { registerSimpleDialog, registerSimpleSheet, Tabs, TabPanel, ArrowDownSquareFillIcon, ArrowUpSquareFillIcon, ExtensionSlot, ExtensionPositionEnum, toast, Box, textVariants, Flex, Text, cn, Button, useDocumentDirection, Spinner, Select, Input, inputFormatter, useScreen, modal, Tooltip, Tips, AlertDialog, EditIcon, ArrowLeftRightIcon, WalletIcon, DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuPortal, DropdownMenuContent, ScrollArea, ChainIcon, Badge, CaretUpIcon, CaretDownIcon, SimpleDialog, CloseRoundFillIcon, ExclamationFillIcon, TokenIcon, WarningIcon, SelectItem, ChevronRightIcon, Checkbox, CloseIcon } from '@orderly.network/ui';
3
3
  import { forwardRef, useState, isValidElement, useMemo, useEffect, useCallback, useRef } from 'react';
4
- import { useConfig, useWalletConnector, useLocalStorage, useConvert, useOdosQuote, useComputedLTV, useAccount, useAppStore, useTransfer, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useMainTokenStore, useEventEmitter, usePositionStream, useIndexPricesStream, useOrderlyContext, useDeposit, useAssetsHistory, useChains, useMemoizedFn, useWithdraw, useWalletTopic, useQuery, useSWR, useTokenInfo, useTokensInfo, useHoldingStream, useInternalTransfer, useDebouncedCallback, usePrivateQuery, useTransferHistory, useBalanceTopic } from '@orderly.network/hooks';
4
+ import { useConfig, useWalletConnector, useLocalStorage, useConvert, useSwapQuote as useSwapQuote$1, useComputedLTV, useAccount, useAppStore, useTransfer, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useMainTokenStore, useEventEmitter, usePositionStream, useIndexPricesStream, useOrderlyContext, useDeposit, useAssetsHistory, useChains, useMemoizedFn, useWithdraw, useWalletTopic, useQuery, useSWR, useTokenInfo, useTokensInfo, useHoldingStream, useInternalTransfer, useDebouncedCallback, usePrivateQuery, useTransferHistory, useBalanceTopic } from '@orderly.network/hooks';
5
5
  import { Decimal, zero, praseChainIdToNumber, int2hex, toNonExponential, formatWithPrecision, isSolana } from '@orderly.network/utils';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { AccountStatusEnum, ChainNamespace, AssetHistoryStatusEnum, AssetHistorySideEnum, EMPTY_OBJECT, isNativeTokenChecker, ABSTRACT_CHAIN_ID_MAP, Arbitrum, nativeTokenAddress } from '@orderly.network/types';
7
+ import { AccountStatusEnum, ChainNamespace, AssetHistoryStatusEnum, AssetHistorySideEnum, EMPTY_OBJECT, isNativeTokenChecker, ABSTRACT_CHAIN_ID_MAP, nativeTokenAddress } from '@orderly.network/types';
8
8
  import { AuthGuard, useAuthGuard } from '@orderly.network/ui-connector';
9
9
  import { useAppContext, useAppConfig } from '@orderly.network/react-app';
10
10
  import { qrcode } from '@akamfoad/qr';
@@ -1700,14 +1700,14 @@ var SlippageItem = ({ value, isActive, onClick }) => {
1700
1700
  var Web3Wallet = () => {
1701
1701
  const { t } = useTranslation();
1702
1702
  const { wallet, connectedChain } = useWalletConnector();
1703
- const { state: accountState, account: account2 } = useAccount();
1703
+ const { state: accountState, account } = useAccount();
1704
1704
  const address = useMemo(() => {
1705
1705
  let address2 = accountState.address;
1706
1706
  if (connectedChain?.id && ABSTRACT_CHAIN_ID_MAP.has(parseInt(connectedChain?.id))) {
1707
- address2 = account2.getAdditionalInfo()?.AGWAddress;
1707
+ address2 = account.getAdditionalInfo()?.AGWAddress;
1708
1708
  }
1709
1709
  return address2;
1710
- }, [wallet, accountState, account2, connectedChain]);
1710
+ }, [wallet, accountState, account, connectedChain]);
1711
1711
  return /* @__PURE__ */ jsxs(Flex, { justify: "between", children: [
1712
1712
  /* @__PURE__ */ jsx(Text, { size: "sm", intensity: 98, children: t("transfer.web3Wallet.your") }),
1713
1713
  /* @__PURE__ */ jsxs(Flex, { gapX: 1, children: [
@@ -2482,10 +2482,10 @@ function useDepositAction(options2) {
2482
2482
  }
2483
2483
  function useDepositFee(options2) {
2484
2484
  const { nativeSymbol, depositFee = 0, getIndexPrice, networkId } = options2;
2485
- const { account: account2 } = useAccount();
2485
+ const { account } = useAccount();
2486
2486
  const tokenInfo = useTokenInfo(nativeSymbol, networkId);
2487
2487
  const feeProps = useMemo(() => {
2488
- const decimals = account2.walletAdapter?.chainNamespace === ChainNamespace.solana ? 9 : 18;
2488
+ const decimals = account.walletAdapter?.chainNamespace === ChainNamespace.solana ? 9 : 18;
2489
2489
  const dstGasFee = new Decimal(depositFee.toString()).div(new Decimal(10).pow(decimals)).toString();
2490
2490
  const indexPrice = getIndexPrice(nativeSymbol);
2491
2491
  const feeAmount = new Decimal(dstGasFee).mul(indexPrice || 0).toString();
@@ -2586,7 +2586,7 @@ var useDepositValidation = (options2) => {
2586
2586
  dstGasFee,
2587
2587
  nativeSymbol,
2588
2588
  nativeBalance,
2589
- account: account2,
2589
+ account,
2590
2590
  currentChain,
2591
2591
  depositError,
2592
2592
  needSwap
@@ -2633,7 +2633,7 @@ var useDepositValidation = (options2) => {
2633
2633
  }, [depositError]);
2634
2634
  const insufficientGasMessage = useMemo(() => {
2635
2635
  if (nativeSymbol && quantity && Number(quantity) > 0 && // when insufficient balance, the input status is error, so we don't need to check gas balance
2636
- !insufficientBalance && !depositFeeRevalidating && !nativeBalanceRevalidating && (account2.walletAdapter?.chainNamespace === ChainNamespace.solana || dstGasFee)) {
2636
+ !insufficientBalance && !depositFeeRevalidating && !nativeBalanceRevalidating && (account.walletAdapter?.chainNamespace === ChainNamespace.solana || dstGasFee)) {
2637
2637
  const notEnoughGas = new Decimal(nativeBalance || 0).lt(dstGasFee || 0);
2638
2638
  const isNotSolBalance = Number(dstGasFee) === 0 && Number(nativeBalance) == Number(dstGasFee);
2639
2639
  if (notEnoughGas || isNotSolBalance) {
@@ -2650,7 +2650,7 @@ var useDepositValidation = (options2) => {
2650
2650
  t,
2651
2651
  nativeSymbol,
2652
2652
  insufficientBalance,
2653
- account2,
2653
+ account,
2654
2654
  nativeBalance
2655
2655
  ]);
2656
2656
  const gasFeeMessage = useMemo(() => {
@@ -2694,10 +2694,10 @@ var useDepositValidation = (options2) => {
2694
2694
  t
2695
2695
  ]);
2696
2696
  const feeWarningMessage = useMemo(() => {
2697
- if (quantity && Number(quantity) > 0 && depositFee === 0n && !depositFeeRevalidating && account2.walletAdapter?.chainNamespace !== ChainNamespace.solana) {
2697
+ if (quantity && Number(quantity) > 0 && depositFee === 0n && !depositFeeRevalidating && account.walletAdapter?.chainNamespace !== ChainNamespace.solana) {
2698
2698
  return t("transfer.deposit.feeUnavailable");
2699
2699
  }
2700
- }, [t, quantity, depositFee, depositFeeRevalidating, account2]);
2700
+ }, [t, quantity, depositFee, depositFeeRevalidating, account]);
2701
2701
  const { inputStatus, hintMessage } = useMemo(() => {
2702
2702
  if (!quantity) {
2703
2703
  return { inputStatus: "default", hintMessage: "" };
@@ -4121,7 +4121,7 @@ var useSwapQuote = (options2) => {
4121
4121
  var SWAP_CONTRACT_ADDRESS = "0xe18f1051d1cCeCb61572eb686e1beb34A8612bf3";
4122
4122
  var useSwapDeposit = (options2) => {
4123
4123
  const { sourceToken, targetToken, currentChain, quantity, depositFee } = options2;
4124
- const { account: account2 } = useAccount();
4124
+ const { account } = useAccount();
4125
4125
  const brokerId = useConfig("brokerId");
4126
4126
  const { slippage, onSlippageChange } = useSlippage();
4127
4127
  const { t } = useTranslation();
@@ -4140,10 +4140,10 @@ var useSwapDeposit = (options2) => {
4140
4140
  slippage
4141
4141
  });
4142
4142
  const onSwapDeposit = useCallback(async () => {
4143
- if (!account2.address || !account2.walletAdapter || !swapData || !sourceToken || !targetToken || !brokerId) {
4143
+ if (!account.address || !account.walletAdapter || !swapData || !sourceToken || !targetToken || !brokerId) {
4144
4144
  return;
4145
4145
  }
4146
- const userAddress = account2.address;
4146
+ const userAddress = account.address;
4147
4147
  const receiver = userAddress;
4148
4148
  const orderlyBridgeFee = depositFee;
4149
4149
  const info = {
@@ -4157,7 +4157,7 @@ var useSwapDeposit = (options2) => {
4157
4157
  data: swapData["1inch"].data
4158
4158
  };
4159
4159
  const perpAccountInfo = {
4160
- accountId: account2.accountIdHashStr,
4160
+ accountId: account.accountIdHashStr,
4161
4161
  brokerHash: utils.parseBrokerHash(brokerId),
4162
4162
  tokenHash: utils.parseTokenHash(targetToken.symbol)
4163
4163
  };
@@ -4170,7 +4170,7 @@ var useSwapDeposit = (options2) => {
4170
4170
  };
4171
4171
  console.info("swap deposit payload", payload);
4172
4172
  try {
4173
- const result = await account2.walletAdapter.sendTransaction(
4173
+ const result = await account.walletAdapter.sendTransaction(
4174
4174
  SWAP_CONTRACT_ADDRESS,
4175
4175
  "deposit",
4176
4176
  payload,
@@ -4185,7 +4185,7 @@ var useSwapDeposit = (options2) => {
4185
4185
  toast.error(err.message || t("common.somethingWentWrong"));
4186
4186
  throw err;
4187
4187
  }
4188
- }, [account2, brokerId, depositFee, sourceToken, swapData, t, targetToken]);
4188
+ }, [account, brokerId, depositFee, sourceToken, swapData, t, targetToken]);
4189
4189
  return {
4190
4190
  swapPrice,
4191
4191
  swapQuantity,
@@ -4202,7 +4202,7 @@ var useSwapDeposit = (options2) => {
4202
4202
  var useDepositFormScript = (options2) => {
4203
4203
  const { wrongNetwork } = useAppContext();
4204
4204
  const { enableSwapDeposit } = useOrderlyContext();
4205
- const { account: account2 } = useAccount();
4205
+ const { account } = useAccount();
4206
4206
  const networkId = useConfig("networkId");
4207
4207
  const { chains, currentChain, settingChain, onChainChange } = useChainSelect();
4208
4208
  const swapTokens = useSwapTokens(currentChain?.id, enableSwapDeposit);
@@ -4345,7 +4345,7 @@ var useDepositFormScript = (options2) => {
4345
4345
  dstGasFee: fee.dstGasFee,
4346
4346
  nativeSymbol,
4347
4347
  nativeBalance,
4348
- account: account2,
4348
+ account,
4349
4349
  currentChain,
4350
4350
  depositError,
4351
4351
  needSwap
@@ -4376,7 +4376,7 @@ var useDepositFormScript = (options2) => {
4376
4376
  const targetQuantityLoading = swapPriceRevalidating;
4377
4377
  const warningMessage = validationMessage || swapErrorMessage;
4378
4378
  const [activeSubTab, setActiveSubTab] = useState("web3");
4379
- const showExclusiveDeposit = account2.walletAdapter?.chainNamespace !== ChainNamespace.solana;
4379
+ const showExclusiveDeposit = account.walletAdapter?.chainNamespace !== ChainNamespace.solana;
4380
4380
  return {
4381
4381
  sourceToken,
4382
4382
  targetToken,
@@ -4604,9 +4604,9 @@ var TextAreaInput = (props) => {
4604
4604
  item: accountInfo,
4605
4605
  disabled: props.disabled,
4606
4606
  selected: !!selectedAccount && selectedAccount.accountId === accountInfo.accountId,
4607
- onSelect: (account2) => {
4608
- onChange?.(account2.accountId);
4609
- setSelectedAccount(account2);
4607
+ onSelect: (account) => {
4608
+ onChange?.(account.accountId);
4609
+ setSelectedAccount(account);
4610
4610
  setAccountDropdownOpen?.(false);
4611
4611
  }
4612
4612
  }
@@ -4964,7 +4964,7 @@ var useSettlePnl = (options2) => {
4964
4964
  const { accountId } = options2 || {};
4965
4965
  const { t } = useTranslation();
4966
4966
  const ee = useEventEmitter();
4967
- const { account: account2, state } = useAccount();
4967
+ const { account, state } = useAccount();
4968
4968
  const [positionData] = usePositionStream();
4969
4969
  const hasPositions = useMemo(
4970
4970
  () => !!positionData?.rows?.length,
@@ -4972,7 +4972,7 @@ var useSettlePnl = (options2) => {
4972
4972
  );
4973
4973
  const onSettlePnl = async () => {
4974
4974
  const isSubAccount = accountId && state.mainAccountId !== accountId;
4975
- const settleFn = isSubAccount ? account2.settleSubAccount({ subAccountId: accountId }) : account2.settle({ accountId });
4975
+ const settleFn = isSubAccount ? account.settleSubAccount({ subAccountId: accountId }) : account.settle({ accountId });
4976
4976
  return settleFn.then((res) => {
4977
4977
  toast.success(t("settle.settlement.requested"));
4978
4978
  return Promise.resolve(res);
@@ -4984,7 +4984,7 @@ var useSettlePnl = (options2) => {
4984
4984
  ) !== -1) {
4985
4985
  ee.emit("wallet:sign-message-with-ledger-error", {
4986
4986
  message: e.message,
4987
- userAddress: account2.address
4987
+ userAddress: account.address
4988
4988
  });
4989
4989
  } else if (e.message.indexOf("user rejected") !== -1) {
4990
4990
  toast.error(t("transfer.rejectTransaction"));
@@ -5534,7 +5534,7 @@ var useWithdrawFormScript = (options2) => {
5534
5534
  const [hintMessage, setHintMessage] = useState();
5535
5535
  const [withdrawTo, setWithdrawTo] = useState("wallet" /* Wallet */);
5536
5536
  const { wrongNetwork, widgetConfigs } = useAppContext();
5537
- const { account: account2, state } = useAccount();
5537
+ const { account, state } = useAccount();
5538
5538
  const [chains, { findByChainId }] = useChains(networkId, {
5539
5539
  filter: (chain) => chain.network_infos?.bridge_enable || chain.network_infos?.bridgeless
5540
5540
  });
@@ -5753,7 +5753,7 @@ var useWithdrawFormScript = (options2) => {
5753
5753
  ) !== -1) {
5754
5754
  ee.emit("wallet:sign-message-with-ledger-error", {
5755
5755
  message: e.message,
5756
- userAddress: account2.address
5756
+ userAddress: account.address
5757
5757
  });
5758
5758
  return;
5759
5759
  }
@@ -7020,22 +7020,22 @@ var useTransferFormScript = (options2) => {
7020
7020
  }
7021
7021
  }, [tokensInfo, options2.token]);
7022
7022
  const onFromAccountChange = useCallback(
7023
- (account2) => {
7024
- setFromAccount(account2);
7023
+ (account) => {
7024
+ setFromAccount(account);
7025
7025
  const firstSubAccount = subAccounts?.[0];
7026
- if (account2?.id === mainAccountId) {
7026
+ if (account?.id === mainAccountId) {
7027
7027
  setToAccount(firstSubAccount);
7028
7028
  return;
7029
7029
  }
7030
- if (account2?.id && account2?.id !== mainAccountId) {
7030
+ if (account?.id && account?.id !== mainAccountId) {
7031
7031
  setToAccount(mainAccount);
7032
7032
  return;
7033
7033
  }
7034
7034
  },
7035
7035
  [mainAccountId, mainAccount, subAccounts]
7036
7036
  );
7037
- const onToAccountChange = useCallback((account2) => {
7038
- setToAccount(account2);
7037
+ const onToAccountChange = useCallback((account) => {
7038
+ setToAccount(account);
7039
7039
  }, []);
7040
7040
  const onExchange = useCallback(() => {
7041
7041
  setFromAccount(toAccount);
@@ -7182,7 +7182,102 @@ var SwapCoin = (props) => {
7182
7182
  }
7183
7183
  );
7184
7184
  };
7185
- var nativeTokenAddress2 = "0x0000000000000000000000000000000000000000";
7185
+ var ConvertFormUI = (props) => {
7186
+ const {
7187
+ loading,
7188
+ disabled,
7189
+ quantity,
7190
+ onQuantityChange,
7191
+ maxQuantity,
7192
+ token,
7193
+ targetToken,
7194
+ sourceTokens,
7195
+ onSourceTokenChange,
7196
+ onConvert,
7197
+ slippage,
7198
+ onSlippageChange,
7199
+ convertRate,
7200
+ outAmounts,
7201
+ minimumReceived,
7202
+ isQuoteLoading,
7203
+ currentLTV,
7204
+ nextLTV,
7205
+ networkId,
7206
+ balanceRevalidating
7207
+ } = props;
7208
+ return /* @__PURE__ */ jsxs(Box, { className: textVariants({ weight: "semibold" }), children: [
7209
+ /* @__PURE__ */ jsxs(Box, { className: "oui-mb-6 lg:oui-mb-8", children: [
7210
+ /* @__PURE__ */ jsx(Box, { mt: 3, mb: 1, children: /* @__PURE__ */ jsx(
7211
+ QuantityInput,
7212
+ {
7213
+ value: quantity,
7214
+ onValueChange: onQuantityChange,
7215
+ token,
7216
+ tokens: sourceTokens,
7217
+ onTokenChange: onSourceTokenChange
7218
+ }
7219
+ ) }),
7220
+ /* @__PURE__ */ jsx(
7221
+ AvailableQuantity,
7222
+ {
7223
+ token,
7224
+ quantity,
7225
+ maxQuantity: maxQuantity.toString(),
7226
+ loading: balanceRevalidating,
7227
+ onClick: () => {
7228
+ onQuantityChange(maxQuantity.toString());
7229
+ }
7230
+ }
7231
+ ),
7232
+ /* @__PURE__ */ jsx(ExchangeDivider, {}),
7233
+ /* @__PURE__ */ jsx(
7234
+ QuantityInput,
7235
+ {
7236
+ readOnly: true,
7237
+ loading: isQuoteLoading,
7238
+ token: targetToken,
7239
+ value: isQuoteLoading || !quantity || Number.isNaN(Number(outAmounts)) ? "" : outAmounts
7240
+ }
7241
+ ),
7242
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", itemAlign: "start", mt: 2, gap: 1, children: [
7243
+ /* @__PURE__ */ jsx(
7244
+ SwapCoin,
7245
+ {
7246
+ indexPrice: isQuoteLoading || !quantity || Number.isNaN(Number(convertRate)) ? "-" : convertRate,
7247
+ sourceSymbol: token?.token,
7248
+ targetSymbol: targetToken?.token
7249
+ }
7250
+ ),
7251
+ /* @__PURE__ */ jsx(Slippage, { value: slippage, onValueChange: onSlippageChange }),
7252
+ /* @__PURE__ */ jsx(
7253
+ MinimumReceived,
7254
+ {
7255
+ symbol: targetToken?.token || "",
7256
+ precision: targetToken?.precision ?? 6,
7257
+ value: isQuoteLoading || !quantity || Number.isNaN(Number(minimumReceived)) ? "-" : minimumReceived.toString()
7258
+ }
7259
+ ),
7260
+ /* @__PURE__ */ jsx(
7261
+ LtvWidget,
7262
+ {
7263
+ showDiff: typeof quantity !== "undefined" && Number(quantity) > 0,
7264
+ currentLtv: currentLTV,
7265
+ nextLTV
7266
+ }
7267
+ )
7268
+ ] })
7269
+ ] }),
7270
+ /* @__PURE__ */ jsx(Flex, { itemAlign: "center", justify: "center", children: /* @__PURE__ */ jsx(
7271
+ ConvertAction,
7272
+ {
7273
+ networkId,
7274
+ disabled,
7275
+ loading,
7276
+ onConvert
7277
+ }
7278
+ ) })
7279
+ ] });
7280
+ };
7186
7281
  var splitTokenBySymbol = (items) => {
7187
7282
  return items.reduce(
7188
7283
  (result, item) => {
@@ -7196,58 +7291,11 @@ var splitTokenBySymbol = (items) => {
7196
7291
  { usdc: [], others: [] }
7197
7292
  );
7198
7293
  };
7199
- var findMainnetQuoteChainInfo = (tokenInfo) => {
7200
- const arbitrumChainInfo = tokenInfo.chain_details.find(
7201
- (item) => parseInt(item.chain_id) === Arbitrum.id
7202
- );
7203
- const nativeTokenChainInfo = tokenInfo.chain_details.find(
7204
- (item) => !item.contract_address
7205
- );
7206
- if (arbitrumChainInfo) {
7207
- return {
7208
- contract_address: arbitrumChainInfo.contract_address || nativeTokenAddress2,
7209
- quoteChainId: arbitrumChainInfo.chain_id,
7210
- decimals: arbitrumChainInfo.decimals
7211
- };
7212
- }
7213
- if (nativeTokenChainInfo) {
7214
- return {
7215
- contract_address: nativeTokenAddress2,
7216
- quoteChainId: nativeTokenChainInfo.chain_id,
7217
- decimals: nativeTokenChainInfo.decimals
7218
- };
7219
- }
7220
- return {
7221
- contract_address: tokenInfo.chain_details[0]?.contract_address,
7222
- quoteChainId: tokenInfo.chain_details[0]?.chain_id,
7223
- decimals: tokenInfo.chain_details[0]?.decimals
7224
- };
7225
- };
7226
- var getMainnetConvertTokenInfo = (tokenInfo) => {
7227
- const chainInfo = findMainnetQuoteChainInfo(tokenInfo);
7228
- if (!chainInfo) {
7229
- return void 0;
7230
- }
7231
- return {
7232
- ...tokenInfo,
7233
- symbol: tokenInfo.token,
7234
- precision: tokenInfo.decimals ?? 6,
7235
- ...chainInfo
7236
- };
7237
- };
7238
- var findQuoteTargetChainInfo = (targetToken, quoteChainId) => {
7239
- const info = targetToken?.chain_details?.find(
7240
- (item) => item.chain_id === quoteChainId
7241
- );
7242
- if (!info) {
7243
- return void 0;
7244
- }
7245
- return {
7246
- ...info,
7247
- contract_address: info.contract_address || nativeTokenAddress2,
7248
- precision: targetToken?.precision
7249
- };
7250
- };
7294
+ var getConvertTokenInfo = (tokenInfo) => ({
7295
+ ...tokenInfo,
7296
+ symbol: tokenInfo.token,
7297
+ precision: tokenInfo.decimals ?? 6
7298
+ });
7251
7299
  var useToken3 = (options2) => {
7252
7300
  const { defaultValue } = options2;
7253
7301
  const [sourceToken, setSourceToken] = useState();
@@ -7259,11 +7307,7 @@ var useToken3 = (options2) => {
7259
7307
  (item) => item.on_chain_swap
7260
7308
  );
7261
7309
  return filteredTokensInfo.reduce((result, item) => {
7262
- const tokenInfo = getMainnetConvertTokenInfo(item);
7263
- if (!tokenInfo) {
7264
- return result;
7265
- }
7266
- result.push(tokenInfo);
7310
+ result.push(getConvertTokenInfo(item));
7267
7311
  return result;
7268
7312
  }, []);
7269
7313
  }, [tokensInfo]);
@@ -7279,28 +7323,20 @@ var useToken3 = (options2) => {
7279
7323
  setSourceTokens(others);
7280
7324
  setTargetToken(usdc[0]);
7281
7325
  }, [defaultValue, newTokensInfo]);
7282
- const targetChainInfo = useMemo(() => {
7283
- return findQuoteTargetChainInfo(targetToken, sourceToken?.quoteChainId);
7284
- }, [sourceToken, targetToken]);
7285
7326
  return {
7286
7327
  sourceToken,
7287
7328
  sourceTokens,
7288
7329
  onSourceTokenChange: setSourceToken,
7289
- targetToken,
7290
- targetChainInfo
7330
+ targetToken
7291
7331
  };
7292
7332
  };
7333
+ var calculateQuoteRate = (inputAmount, estimatedUsdcValue) => new Decimal(estimatedUsdcValue).div(inputAmount).toString();
7334
+ var calculateMinimumReceived = (estimatedUsdcValue, slippageLimitPercent) => new Decimal(estimatedUsdcValue).mul(new Decimal(1).minus(new Decimal(slippageLimitPercent).div(100))).toString();
7293
7335
 
7294
7336
  // src/components/convertForm/convertForm.script.tsx
7295
- var { calcMinimumReceived } = account;
7296
7337
  var ORDERLY_CONVERT_SLIPPAGE_KEY = "orderly_convert_slippage";
7297
- var ODOS_QUOTE_DEBOUNCE_MS = 300;
7298
- var normalizeAmount = (amount, decimals) => {
7299
- return new Decimal(amount).mul(new Decimal(10).pow(decimals)).toFixed(0);
7300
- };
7301
- var unnormalizeAmount = (amount, decimals) => {
7302
- return new Decimal(amount).div(new Decimal(10).pow(decimals)).toString();
7303
- };
7338
+ var SWAP_QUOTE_DEBOUNCE_MS = 300;
7339
+ var getQuoteErrorMessage = (error) => error instanceof Error ? error.message : String(error);
7304
7340
  var useConvertFormScript = (options2) => {
7305
7341
  const { token: defaultToken, close } = options2;
7306
7342
  const { t } = useTranslation();
@@ -7308,15 +7344,9 @@ var useConvertFormScript = (options2) => {
7308
7344
  const config = useConfig();
7309
7345
  const networkId = config.get("networkId");
7310
7346
  const [quantity, setQuantity] = useState("");
7311
- const { wrongNetwork } = useAppContext();
7347
+ const { wrongNetwork, connectWallet } = useAppContext();
7312
7348
  const { wallet } = useWalletConnector();
7313
- const {
7314
- sourceToken,
7315
- sourceTokens,
7316
- onSourceTokenChange,
7317
- targetToken,
7318
- targetChainInfo
7319
- } = useToken3({ defaultValue: defaultToken });
7349
+ const { sourceToken, sourceTokens, onSourceTokenChange, targetToken } = useToken3({ defaultValue: defaultToken });
7320
7350
  const { walletName, address } = useMemo(
7321
7351
  () => ({
7322
7352
  walletName: wallet?.label,
@@ -7329,7 +7359,7 @@ var useConvertFormScript = (options2) => {
7329
7359
  };
7330
7360
  const [slippage, setSlippage] = useLocalStorage(
7331
7361
  ORDERLY_CONVERT_SLIPPAGE_KEY,
7332
- 1
7362
+ 0.5
7333
7363
  );
7334
7364
  const { maxAmount, convert } = useConvert({ token: sourceToken?.token });
7335
7365
  const onConvert = async () => {
@@ -7355,45 +7385,18 @@ var useConvertFormScript = (options2) => {
7355
7385
  const [
7356
7386
  postQuote,
7357
7387
  { data: quoteData, reset: resetQuote, isMutating: isQuoteLoading }
7358
- ] = useOdosQuote();
7388
+ ] = useSwapQuote$1();
7359
7389
  const quoteRequest = useMemo(() => {
7360
- const { quoteChainId, contract_address, decimals } = sourceToken || {};
7361
- const targetAddress = targetChainInfo?.contract_address;
7362
- if (!quantity || new Decimal(quantity).lte(0) || !quoteChainId || !contract_address || typeof decimals === "undefined" || !targetAddress || !address) {
7390
+ if (!quantity || new Decimal(quantity).lte(0) || !sourceToken?.token || !targetToken?.token) {
7363
7391
  return null;
7364
7392
  }
7365
- const inputAmount = normalizeAmount(quantity, decimals);
7366
7393
  return {
7367
- inputAmount,
7368
- inputTokenAddress: contract_address.toLowerCase(),
7369
- outputTokenAddress: targetAddress.toLowerCase(),
7370
- body: {
7371
- chainId: parseInt(quoteChainId),
7372
- inputTokens: [
7373
- {
7374
- amount: inputAmount,
7375
- tokenAddress: contract_address
7376
- }
7377
- ],
7378
- outputTokens: [
7379
- {
7380
- proportion: 1,
7381
- tokenAddress: targetAddress
7382
- }
7383
- ],
7384
- userAddr: address
7385
- // simple: true,
7386
- }
7394
+ fromToken: sourceToken.token,
7395
+ toToken: targetToken.token,
7396
+ amount: new Decimal(quantity).toNumber(),
7397
+ slippage: new Decimal(slippage).div(100).toNumber()
7387
7398
  };
7388
- }, [
7389
- quantity,
7390
- sourceToken?.quoteChainId,
7391
- sourceToken?.contract_address,
7392
- sourceToken?.decimals,
7393
- targetChainInfo?.contract_address,
7394
- targetChainInfo?.decimals,
7395
- address
7396
- ]);
7399
+ }, [quantity, slippage, sourceToken?.token, targetToken?.token]);
7397
7400
  useEffect(() => {
7398
7401
  resetQuote();
7399
7402
  if (!quoteRequest) {
@@ -7401,37 +7404,39 @@ var useConvertFormScript = (options2) => {
7401
7404
  }
7402
7405
  let active = true;
7403
7406
  const timer = window.setTimeout(() => {
7404
- postQuote(quoteRequest.body).catch((error) => {
7407
+ postQuote(quoteRequest).catch((error) => {
7405
7408
  if (!active) {
7406
7409
  return;
7407
7410
  }
7408
- let message = t("transfer.convert.failed");
7409
- if (error instanceof Error) {
7410
- message = error.message;
7411
- } else if (error) {
7412
- message = String(error);
7413
- }
7414
- if (message === "Failed to fetch") {
7415
- message = t("transfer.convert.failed");
7411
+ const code = Number(error?.code);
7412
+ console.error("[convertForm] Swap quote failed:", error);
7413
+ toast.error(getQuoteErrorMessage(error));
7414
+ if (code === -1002) {
7415
+ void Promise.resolve(connectWallet()).catch((connectError) => {
7416
+ console.error(
7417
+ "[convertForm] Account recovery failed:",
7418
+ connectError
7419
+ );
7420
+ });
7416
7421
  }
7417
- console.error("[convertForm] Odos quote failed:", error);
7418
- toast.error(message);
7419
7422
  resetQuote();
7420
7423
  });
7421
- }, ODOS_QUOTE_DEBOUNCE_MS);
7424
+ }, SWAP_QUOTE_DEBOUNCE_MS);
7422
7425
  return () => {
7423
7426
  active = false;
7424
7427
  window.clearTimeout(timer);
7425
7428
  };
7426
- }, [postQuote, quoteRequest, resetQuote, t]);
7429
+ }, [connectWallet, postQuote, quoteRequest, resetQuote]);
7427
7430
  const isQuoteDataMatched = useMemo(() => {
7428
7431
  if (!quoteData || !quoteRequest) {
7429
7432
  return false;
7430
7433
  }
7431
- const inAmount = quoteData?.inAmounts?.[0]?.toString();
7432
- const inToken = quoteData?.inTokens?.[0]?.toLowerCase();
7433
- const outToken = quoteData?.outTokens?.[0]?.toLowerCase();
7434
- return inAmount === quoteRequest.inputAmount && inToken === quoteRequest.inputTokenAddress && outToken === quoteRequest.outputTokenAddress;
7434
+ const fromToken = quoteData.fromToken;
7435
+ const toToken = quoteData.toToken;
7436
+ if (!fromToken || !toToken || !fromToken.tokenAddress || !toToken.tokenAddress || !fromToken.amount || !toToken.estimatedAmount || !toToken.estimatedValue || !quoteData.gasEstimate || typeof quoteData.expiresAt !== "number") {
7437
+ return false;
7438
+ }
7439
+ return quoteData.expiresAt > Date.now();
7435
7440
  }, [quoteData, quoteRequest]);
7436
7441
  useEffect(() => {
7437
7442
  if (quoteData && !isQuoteDataMatched) {
@@ -7440,38 +7445,57 @@ var useConvertFormScript = (options2) => {
7440
7445
  }, [isQuoteDataMatched, quoteData, resetQuote]);
7441
7446
  const memoizedOutAmounts = useMemo(() => {
7442
7447
  if (quoteData && !isQuoteLoading && isQuoteDataMatched) {
7443
- return quoteData?.outAmounts[0];
7448
+ return quoteData.toToken.estimatedValue;
7444
7449
  }
7445
7450
  return "-";
7446
7451
  }, [quoteData, isQuoteDataMatched, isQuoteLoading]);
7447
7452
  const memoizedConvertRate = useMemo(() => {
7448
- if (quoteData && !isQuoteLoading && isQuoteDataMatched) {
7449
- return new Decimal(
7450
- unnormalizeAmount(
7451
- quoteData.outAmounts[0],
7452
- targetChainInfo?.decimals ?? 6
7453
- )
7454
- ).div(
7455
- unnormalizeAmount(quoteData.inAmounts[0], sourceToken?.decimals ?? 6)
7456
- ).toString();
7453
+ if (quoteData && quoteRequest && !isQuoteLoading && isQuoteDataMatched) {
7454
+ return calculateQuoteRate(
7455
+ quoteRequest.amount,
7456
+ quoteData.toToken.estimatedValue
7457
+ );
7457
7458
  }
7458
7459
  return "-";
7459
- }, [
7460
- isQuoteDataMatched,
7461
- isQuoteLoading,
7462
- quoteData,
7463
- sourceToken,
7464
- targetChainInfo
7465
- ]);
7460
+ }, [isQuoteDataMatched, isQuoteLoading, quoteData, quoteRequest]);
7466
7461
  const memoizedMinimumReceived = useMemo(() => {
7467
7462
  if (!quoteData || isQuoteLoading || !isQuoteDataMatched) {
7468
- return 0;
7463
+ return "0";
7469
7464
  }
7470
- return calcMinimumReceived({
7471
- amount: quoteData?.outAmounts[0],
7472
- slippage: Number(slippage)
7473
- });
7474
- }, [quoteData, isQuoteDataMatched, isQuoteLoading, slippage]);
7465
+ const effectiveSlippage = Number(quoteData.slippageLimitPercent);
7466
+ if (!Number.isFinite(effectiveSlippage)) {
7467
+ return "0";
7468
+ }
7469
+ return calculateMinimumReceived(
7470
+ quoteData.toToken.estimatedValue,
7471
+ effectiveSlippage.toString()
7472
+ );
7473
+ }, [quoteData, isQuoteDataMatched, isQuoteLoading]);
7474
+ useEffect(() => {
7475
+ if (!quoteData || !quoteRequest || !isQuoteDataMatched) {
7476
+ return;
7477
+ }
7478
+ const delay = Math.max(0, quoteData.expiresAt - Date.now());
7479
+ let active = true;
7480
+ const timer = window.setTimeout(() => {
7481
+ resetQuote();
7482
+ postQuote(quoteRequest).catch((error) => {
7483
+ if (!active) {
7484
+ return;
7485
+ }
7486
+ console.error(
7487
+ "[convertForm] Expired swap quote refresh failed:",
7488
+ error
7489
+ );
7490
+ toast.error(getQuoteErrorMessage(error));
7491
+ resetQuote();
7492
+ });
7493
+ }, delay);
7494
+ return () => {
7495
+ active = false;
7496
+ window.clearTimeout(timer);
7497
+ };
7498
+ }, [isQuoteDataMatched, postQuote, quoteData, quoteRequest, resetQuote]);
7475
7499
  const currentLtv = useComputedLTV();
7476
7500
  const nextLTV = useComputedLTV({
7477
7501
  input: Number(quantity),
@@ -7504,110 +7528,9 @@ var useConvertFormScript = (options2) => {
7504
7528
  outAmounts: memoizedOutAmounts,
7505
7529
  isQuoteLoading,
7506
7530
  currentLTV: currentLtv,
7507
- nextLTV,
7508
- targetChainInfo
7531
+ nextLTV
7509
7532
  };
7510
7533
  };
7511
- var ConvertFormUI = (props) => {
7512
- const {
7513
- loading,
7514
- disabled,
7515
- quantity,
7516
- onQuantityChange,
7517
- maxQuantity,
7518
- token,
7519
- targetToken,
7520
- sourceTokens,
7521
- onSourceTokenChange,
7522
- onConvert,
7523
- slippage,
7524
- onSlippageChange,
7525
- convertRate,
7526
- outAmounts,
7527
- minimumReceived,
7528
- isQuoteLoading,
7529
- currentLTV,
7530
- nextLTV,
7531
- networkId,
7532
- balanceRevalidating,
7533
- targetChainInfo
7534
- } = props;
7535
- return /* @__PURE__ */ jsxs(Box, { className: textVariants({ weight: "semibold" }), children: [
7536
- /* @__PURE__ */ jsxs(Box, { className: "oui-mb-6 lg:oui-mb-8", children: [
7537
- /* @__PURE__ */ jsx(Box, { mt: 3, mb: 1, children: /* @__PURE__ */ jsx(
7538
- QuantityInput,
7539
- {
7540
- value: quantity,
7541
- onValueChange: onQuantityChange,
7542
- token,
7543
- tokens: sourceTokens,
7544
- onTokenChange: onSourceTokenChange
7545
- }
7546
- ) }),
7547
- /* @__PURE__ */ jsx(
7548
- AvailableQuantity,
7549
- {
7550
- token,
7551
- quantity,
7552
- maxQuantity: maxQuantity.toString(),
7553
- loading: balanceRevalidating,
7554
- onClick: () => {
7555
- onQuantityChange(maxQuantity.toString());
7556
- }
7557
- }
7558
- ),
7559
- /* @__PURE__ */ jsx(ExchangeDivider, {}),
7560
- /* @__PURE__ */ jsx(
7561
- QuantityInput,
7562
- {
7563
- readOnly: true,
7564
- loading: isQuoteLoading,
7565
- token: targetToken,
7566
- value: isQuoteLoading || !quantity || Number.isNaN(Number(outAmounts)) ? "" : unnormalizeAmount(outAmounts, targetChainInfo?.decimals ?? 6)
7567
- }
7568
- ),
7569
- /* @__PURE__ */ jsxs(Flex, { direction: "column", itemAlign: "start", mt: 2, gap: 1, children: [
7570
- /* @__PURE__ */ jsx(
7571
- SwapCoin,
7572
- {
7573
- indexPrice: isQuoteLoading || !quantity || Number.isNaN(Number(convertRate)) ? "-" : convertRate,
7574
- sourceSymbol: token?.token,
7575
- targetSymbol: targetToken?.token
7576
- }
7577
- ),
7578
- /* @__PURE__ */ jsx(Slippage, { value: slippage, onValueChange: onSlippageChange }),
7579
- /* @__PURE__ */ jsx(
7580
- MinimumReceived,
7581
- {
7582
- symbol: targetToken?.token || "",
7583
- precision: targetChainInfo?.precision ?? 6,
7584
- value: isQuoteLoading || !quantity || Number.isNaN(Number(minimumReceived)) ? "-" : unnormalizeAmount(
7585
- minimumReceived.toString(),
7586
- targetChainInfo?.decimals ?? 6
7587
- )
7588
- }
7589
- ),
7590
- /* @__PURE__ */ jsx(
7591
- LtvWidget,
7592
- {
7593
- showDiff: typeof quantity !== "undefined" && Number(quantity) > 0,
7594
- currentLtv: currentLTV,
7595
- nextLTV
7596
- }
7597
- )
7598
- ] })
7599
- ] }),
7600
- /* @__PURE__ */ jsx(Flex, { itemAlign: "center", justify: "center", children: /* @__PURE__ */ jsx(
7601
- ConvertAction,
7602
- {
7603
- networkId,
7604
- disabled,
7605
- loading,
7606
- onConvert
7607
- }
7608
- ) })
7609
- ] });
7610
- };
7611
7534
  var ConvertDialogId = "ConvertDialogId";
7612
7535
  var ConvertSheetId = "ConvertSheetId";
7613
7536
  var ConvertFormWidget = (props) => {