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