@orderly.network/ui-transfer 3.1.11 → 3.1.12-alpha.0

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
@@ -2,19 +2,18 @@ import { i18n, useTranslation, Trans } from '@orderly.network/i18n';
2
2
  import { registerSimpleDialog, registerSimpleSheet, Tabs, TabPanel, ArrowDownSquareFillIcon, ArrowUpSquareFillIcon, useModal, ExtensionSlot, ExtensionPositionEnum, toast, Box, Text, Flex, cn, Button, textVariants, ExclamationFillIcon, ArrowLeftRightIcon, WalletIcon, DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuPortal, DropdownMenuContent, ScrollArea, useDocumentDirection, Spinner, Select, Input, inputFormatter, useScreen, modal, Tooltip, ToastTile, CheckedCircleFillIcon, Tips, AlertDialog, EditIcon, ChainIcon, Badge, CaretUpIcon, CaretDownIcon, SimpleDialog, CloseRoundFillIcon, TokenIcon, WarningIcon, SelectItem, ChevronRightIcon, Checkbox, CloseIcon } from '@orderly.network/ui';
3
3
  import { forwardRef, useState, isValidElement, useMemo, useCallback, useEffect, useRef } from 'react';
4
4
  import { useConfig, useAccount, useAppStore, useTransfer, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSessionStorage, useEventEmitter, useWalletConnector, useLocalStorage, usePrivateQuery, useConvert, useSwapQuote as useSwapQuote$1, useComputedLTV, useOrderlyContext, useIndexPricesStream, useDeposit, useAssetsHistory, useChains, useMemoizedFn, useWithdraw, useWalletTopic, usePositionStream, useMainTokenStore, useSWR, useTokenInfo, useQuery, useTokensInfo, useHoldingStream, useInternalTransfer, useDebouncedCallback, useTransferHistory, useBalanceTopic } from '@orderly.network/hooks';
5
- import { zero, Decimal, praseChainIdToNumber, int2hex, toNonExponential, formatWithPrecision, isSolana } from '@orderly.network/utils';
5
+ import { zero, Decimal, praseChainIdToNumber, int2hex, toNonExponential, formatWithPrecision, isSolana, getTimestamp } from '@orderly.network/utils';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { AccountStatusEnum, ChainNamespace, AssetHistoryStatusEnum, AssetHistorySideEnum, isWalletChainChangePendingResult, EMPTY_OBJECT, isNativeTokenChecker, ABSTRACT_CHAIN_ID_MAP, nativeTokenAddress } from '@orderly.network/types';
7
+ import { AccountStatusEnum, ChainNamespace, AssetHistoryStatusEnum, AssetHistorySideEnum, isWalletChainChangePendingResult, EMPTY_OBJECT, isNativeTokenChecker, ABSTRACT_CHAIN_ID_MAP, nativeTokenAddress, SOLANA_MAINNET_CHAINID, SOLANA_TESTNET_CHAINID, SolanaDevnetChainInfo } 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';
11
11
  import { account } from '@orderly.network/perp';
12
- import { utils } from '@orderly.network/core';
12
+ import { utils, SimpleDI } from '@orderly.network/core';
13
13
  import { ChainSelectorDialogId } from '@orderly.network/ui-chain-selector';
14
- import { PublicKey } from '@solana/web3.js';
14
+ import { PublicKey, Connection } from '@solana/web3.js';
15
15
  import { ethers } from 'ethers';
16
16
  import { injectable } from '@orderly.network/plugin-core';
17
- import { DefaultSolanaWalletAdapter } from '@orderly.network/default-solana-adapter';
18
17
 
19
18
  // src/components/depositForm/depositForm.ui.tsx
20
19
  var useLtvScript = () => {
@@ -240,13 +239,19 @@ var AvailableTooltipMessage = ({
240
239
  return /* @__PURE__ */ jsx(Text, { size: "2xs", intensity: 80, children: t("transfer.withdraw.available.tooltip", { amount: amountText }) });
241
240
  };
242
241
  var AvailableQuantity = (props) => {
243
- const { quantity, maxQuantity, token, loading } = props;
242
+ const {
243
+ quantity,
244
+ maxQuantity,
245
+ token,
246
+ loading,
247
+ showDisplayName = false
248
+ } = props;
244
249
  const { t } = useTranslation();
245
250
  const { isMobile } = useScreen();
246
251
  const dir = useDocumentDirection();
247
252
  const isRTL = dir === "rtl";
248
253
  const { getIndexPrice } = useIndexPricesStream();
249
- const name = token?.display_name || token?.symbol || "";
254
+ const name = showDisplayName ? token?.display_name || token?.symbol || "" : token?.symbol || "";
250
255
  const dp = token?.precision ?? token?.decimals ?? 2;
251
256
  const notional = useMemo(() => {
252
257
  if (props.notional !== void 0 && props.notional !== null) {
@@ -914,7 +919,8 @@ var useExclusiveDepositOptions = (params) => {
914
919
  chainId,
915
920
  chainName: chain?.network_infos?.name ?? `Chain ${chainId}`,
916
921
  explorerUrl: chain?.network_infos?.explorer_base_url ?? "",
917
- tokenSymbol: token.token
922
+ tokenSymbol: token.token,
923
+ displayName: detail.display_name || token.token
918
924
  });
919
925
  }
920
926
  }
@@ -949,7 +955,7 @@ var useExclusiveDepositOptions = (params) => {
949
955
  for (const combo of combos) {
950
956
  if (combo.chainId === chainId && !seen.has(combo.tokenSymbol)) {
951
957
  seen.add(combo.tokenSymbol);
952
- result.push({ label: combo.tokenSymbol, value: combo.tokenSymbol });
958
+ result.push({ label: combo.displayName, value: combo.tokenSymbol });
953
959
  }
954
960
  }
955
961
  result.sort((a, b) => {
@@ -1376,6 +1382,7 @@ var QuantityInput = (props) => {
1376
1382
  tokenShowCaret,
1377
1383
  balancesRevalidating,
1378
1384
  showBalance,
1385
+ showDisplayName = false,
1379
1386
  ...rest
1380
1387
  } = props;
1381
1388
  const { t } = useTranslation();
@@ -1383,6 +1390,7 @@ var QuantityInput = (props) => {
1383
1390
  const inputRef = useRef(null);
1384
1391
  const [open, setOpen] = useState(false);
1385
1392
  const [width, setWidth] = useState(0);
1393
+ const getTokenLabel = (tokenInfo) => showDisplayName ? tokenInfo.display_name || tokenInfo.symbol : tokenInfo.symbol;
1386
1394
  const tokenOptions = useMemo(() => {
1387
1395
  return tokens.map((token2) => {
1388
1396
  const currentToken = vaultBalanceList?.find(
@@ -1391,17 +1399,17 @@ var QuantityInput = (props) => {
1391
1399
  const insufficientBalance = currentToken ? new Decimal(currentToken.balance ?? 0).lt(value ? Number(value) : 0) : false;
1392
1400
  return {
1393
1401
  ...token2,
1394
- name: token2.display_name || token2.symbol,
1402
+ name: getTokenLabel(token2),
1395
1403
  insufficientBalance
1396
1404
  };
1397
1405
  });
1398
- }, [tokens, value, vaultBalanceList]);
1406
+ }, [tokens, value, vaultBalanceList, showDisplayName]);
1399
1407
  useEffect(() => {
1400
1408
  const rect = inputRef?.current?.getBoundingClientRect();
1401
1409
  setWidth(rect?.width || 0);
1402
1410
  }, [inputRef]);
1403
1411
  const _onTokenChange = (value2) => {
1404
- const find = tokens.find((item) => item.symbol === value2);
1412
+ const find = tokens.find((item) => getTokenLabel(item) === value2) ?? tokens.find((item) => item.symbol === value2);
1405
1413
  if (find) {
1406
1414
  onTokenChange?.(find);
1407
1415
  }
@@ -1430,6 +1438,7 @@ var QuantityInput = (props) => {
1430
1438
  /* @__PURE__ */ jsx(Box, { className: "oui-absolute oui-top-0", children: /* @__PURE__ */ jsx(Text, { size: "2xs", intensity: 36, children: label || t("common.quantity") }) }),
1431
1439
  loading && /* @__PURE__ */ jsx(Box, { className: "oui-absolute oui-bottom-1", children: /* @__PURE__ */ jsx(Spinner, { size: "sm" }) })
1432
1440
  ] });
1441
+ const tokenLabel = token ? getTokenLabel(token) : void 0;
1433
1442
  const suffix = /* @__PURE__ */ jsx("div", { className: "oui-absolute oui-end-0", children: /* @__PURE__ */ jsx(
1434
1443
  Select.tokens,
1435
1444
  {
@@ -1438,7 +1447,7 @@ var QuantityInput = (props) => {
1438
1447
  disabled: rest.disabled,
1439
1448
  variant: "text",
1440
1449
  tokens: tokenOptions,
1441
- value: token?.display_name || token?.symbol,
1450
+ value: tokenLabel,
1442
1451
  size: rest.size,
1443
1452
  onValueChange: _onTokenChange,
1444
1453
  showIcon: true,
@@ -2058,7 +2067,7 @@ var DepositForm = (props) => {
2058
2067
  ConvertRate,
2059
2068
  {
2060
2069
  sourceSymbol: sourceToken?.display_name || sourceToken?.symbol,
2061
- targetSymbol: targetToken?.display_name || targetToken?.symbol,
2070
+ targetSymbol: targetToken?.symbol,
2062
2071
  precision: targetToken?.precision,
2063
2072
  swapPrice,
2064
2073
  swapPriceInUSD
@@ -2151,7 +2160,8 @@ var DepositForm = (props) => {
2151
2160
  tokenValueFormatter: showSourceDepositCap ? tokenValueFormatter : void 0,
2152
2161
  disabled: !props.isLoggedIn,
2153
2162
  balancesRevalidating: batchBalancesRevalidating,
2154
- showBalance: true
2163
+ showBalance: true,
2164
+ showDisplayName: true
2155
2165
  }
2156
2166
  )
2157
2167
  ] }),
@@ -2165,7 +2175,8 @@ var DepositForm = (props) => {
2165
2175
  loading: balanceRevalidating,
2166
2176
  onClick: () => {
2167
2177
  onQuantityChange(maxDepositAmount);
2168
- }
2178
+ },
2179
+ showDisplayName: true
2169
2180
  }
2170
2181
  ),
2171
2182
  /* @__PURE__ */ jsx(
@@ -6518,7 +6529,8 @@ var WithdrawForm = (props) => {
6518
6529
  },
6519
6530
  token: sourceToken,
6520
6531
  value: props.showQty,
6521
- readOnly: true
6532
+ readOnly: true,
6533
+ showDisplayName: true
6522
6534
  }
6523
6535
  )
6524
6536
  ]
@@ -8187,58 +8199,173 @@ var Dot = (props) => {
8187
8199
  }
8188
8200
  );
8189
8201
  };
8190
- var blockCount = 5;
8202
+ var blockSpan = 25;
8203
+ var maxAttempts = 2;
8191
8204
  async function getEvmBlockTime(chain) {
8192
8205
  const provider = new ethers.JsonRpcProvider(
8193
8206
  chain.network_infos.public_rpc_url
8194
8207
  );
8195
- const latest = await provider.getBlockNumber();
8196
- const blocks = await Promise.all(
8197
- Array.from({ length: blockCount }, (_, i) => provider.getBlock(latest - i))
8198
- );
8199
- const timestamps = blocks.filter((b) => b?.timestamp != null).map((b) => Number(b?.timestamp));
8200
- if (timestamps.length < 2) {
8208
+ let lastError;
8209
+ try {
8210
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
8211
+ try {
8212
+ const head = await provider.getBlock("latest");
8213
+ if (head?.timestamp == null) {
8214
+ continue;
8215
+ }
8216
+ const tail = await provider.getBlock(head.number - blockSpan);
8217
+ if (tail?.timestamp == null) {
8218
+ continue;
8219
+ }
8220
+ const elapsed = Number(head.timestamp) - Number(tail.timestamp);
8221
+ if (elapsed > 0) {
8222
+ return elapsed / blockSpan;
8223
+ }
8224
+ } catch (error) {
8225
+ lastError = error;
8226
+ }
8227
+ }
8228
+ console.error(
8229
+ "getEvmBlockTime failed",
8230
+ chain.network_infos.chain_id,
8231
+ lastError ?? "no usable block timestamps"
8232
+ );
8201
8233
  return 0;
8234
+ } finally {
8235
+ provider.destroy();
8202
8236
  }
8203
- let sum = 0;
8204
- for (let i = 0; i < timestamps.length - 1; i++) {
8205
- const diff = timestamps[i] - timestamps[i + 1];
8206
- sum += diff;
8207
- }
8208
- return sum / (timestamps.length - 1);
8209
8237
  }
8210
- async function getSolanaBlockTime(chain, wallet) {
8211
- if (!wallet) {
8212
- return 0;
8213
- }
8214
- const walletAdapter = new DefaultSolanaWalletAdapter();
8215
- walletAdapter.active({
8216
- address: wallet.accounts[0].address,
8217
- chain: { id: chain.network_infos.chain_id },
8218
- provider: wallet.provider
8219
- });
8220
- const samples = await walletAdapter.connection.getRecentPerformanceSamples(60);
8238
+ var SAMPLE_LIMIT = 60;
8239
+ var SOLANA_RPC_PROXY_PATH = "/v1/solana-rpc-proxy";
8240
+ var RPC_TIMEOUT_MS = 8e3;
8241
+ function averageBlockTimeFromSamples(samples) {
8221
8242
  let totalBlockTime = 0;
8222
8243
  let validSamples = 0;
8223
8244
  for (const sample of samples) {
8224
8245
  if (sample.numSlots > 0 && sample.samplePeriodSecs > 0) {
8225
- const blockTime = sample.samplePeriodSecs / sample.numSlots;
8226
- totalBlockTime += blockTime;
8246
+ totalBlockTime += sample.samplePeriodSecs / sample.numSlots;
8227
8247
  validSamples++;
8228
8248
  }
8229
8249
  }
8250
+ if (validSamples === 0) {
8251
+ return 0;
8252
+ }
8230
8253
  return totalBlockTime / validSamples;
8231
8254
  }
8255
+ async function fetchBlockTime(connection) {
8256
+ const samples = await connection.getRecentPerformanceSamples(SAMPLE_LIMIT);
8257
+ return averageBlockTimeFromSamples(samples);
8258
+ }
8259
+ function createConnection(url, options2 = {}) {
8260
+ return new Connection(url, {
8261
+ commitment: "confirmed",
8262
+ // Avoid ~15s backoff on 429; fail fast and let the caller return 0.
8263
+ disableRetryOnRateLimit: true,
8264
+ fetch: (input, init) => fetch(input, { ...init, signal: AbortSignal.timeout(RPC_TIMEOUT_MS) }),
8265
+ ...options2
8266
+ });
8267
+ }
8268
+ function createOrderlyProxyConnection() {
8269
+ const account = SimpleDI.get("account");
8270
+ if (!account?.apiBaseUrl || !account.accountId) {
8271
+ return null;
8272
+ }
8273
+ if (!account.keyStore?.getOrderlyKey()) {
8274
+ return null;
8275
+ }
8276
+ return createConnection(`${account.apiBaseUrl}${SOLANA_RPC_PROXY_PATH}`, {
8277
+ // web3.js only wraps fetchMiddleware in a sync try/catch and treats the
8278
+ // 3rd arg as a `next` callback (not fetch). An async throw would hang the
8279
+ // request forever, so always invoke `next` and never return a rejected promise.
8280
+ fetchMiddleware: (info, init, next) => {
8281
+ void (async () => {
8282
+ try {
8283
+ const payload = {
8284
+ url: SOLANA_RPC_PROXY_PATH,
8285
+ method: init?.method ?? "POST",
8286
+ data: JSON.parse(init?.body || "{}")
8287
+ };
8288
+ const signature = await account.signer.sign(payload, getTimestamp());
8289
+ next(info, {
8290
+ ...init,
8291
+ headers: {
8292
+ ...init?.headers,
8293
+ ...signature,
8294
+ "orderly-account-id": account.accountId
8295
+ }
8296
+ });
8297
+ } catch (error) {
8298
+ console.error("solana-rpc-proxy sign failed", error);
8299
+ next(info, init);
8300
+ }
8301
+ })();
8302
+ }
8303
+ });
8304
+ }
8305
+ async function getSolanaBlockTime(chain) {
8306
+ const chainId = Number(chain.network_infos.chain_id);
8307
+ try {
8308
+ if (chainId === SOLANA_MAINNET_CHAINID) {
8309
+ const connection = createOrderlyProxyConnection();
8310
+ if (!connection) {
8311
+ return 0;
8312
+ }
8313
+ return await fetchBlockTime(connection);
8314
+ }
8315
+ if (chainId === SOLANA_TESTNET_CHAINID) {
8316
+ const rpcUrl = chain.network_infos.public_rpc_url || SolanaDevnetChainInfo.public_rpc_url;
8317
+ return await fetchBlockTime(createConnection(rpcUrl));
8318
+ }
8319
+ return 0;
8320
+ } catch (error) {
8321
+ console.error("getSolanaBlockTime failed", chainId, error);
8322
+ return 0;
8323
+ }
8324
+ }
8232
8325
 
8233
8326
  // src/contract/getBlockTime.ts
8234
8327
  async function getBlockTime(inputs) {
8235
- const { chainId, chain, wallet } = inputs;
8328
+ const { chain } = inputs;
8329
+ const chainId = Number(inputs.chainId);
8236
8330
  if (isSolana(chainId)) {
8237
- return getSolanaBlockTime(chain, wallet);
8331
+ return getSolanaBlockTime(chain);
8238
8332
  }
8239
8333
  return getEvmBlockTime(chain);
8240
8334
  }
8241
8335
 
8336
+ // src/contract/abi/endpointV2Abi.json
8337
+ var endpointV2Abi_default = [
8338
+ {
8339
+ inputs: [
8340
+ {
8341
+ internalType: "address",
8342
+ name: "receiver",
8343
+ type: "address"
8344
+ },
8345
+ {
8346
+ internalType: "uint32",
8347
+ name: "srcEid",
8348
+ type: "uint32"
8349
+ }
8350
+ ],
8351
+ name: "getReceiveLibrary",
8352
+ outputs: [
8353
+ {
8354
+ internalType: "address",
8355
+ name: "lib",
8356
+ type: "address"
8357
+ },
8358
+ {
8359
+ internalType: "bool",
8360
+ name: "isDefault",
8361
+ type: "bool"
8362
+ }
8363
+ ],
8364
+ stateMutability: "view",
8365
+ type: "function"
8366
+ }
8367
+ ];
8368
+
8242
8369
  // src/contract/abi/getAppUlnConfigAbi.json
8243
8370
  var getAppUlnConfigAbi_default = [
8244
8371
  {
@@ -8324,6 +8451,8 @@ var CHAIN_ID_TO_ENDPOINT_ID = {
8324
8451
  // Manta Pacific Mainnet
8325
8452
  5e3: 30181,
8326
8453
  // Mantle Mainnet
8454
+ 5003: 40246,
8455
+ // Mantle Sepolia Testnet
8327
8456
  81457: 30243,
8328
8457
  // Blast Mainnet
8329
8458
  252: 30255,
@@ -8461,6 +8590,8 @@ var CHAIN_ID_TO_ENDPOINT_ID = {
8461
8590
  // Orderly
8462
8591
  291: 30213,
8463
8592
  // Orderly Mainnet
8593
+ 4460: 40200,
8594
+ // Orderly Testnet
8464
8595
  // CoreDAO
8465
8596
  1116: 30153,
8466
8597
  // CoreDAO Mainnet
@@ -8648,6 +8779,8 @@ var CHAIN_ID_TO_ENDPOINT_ID = {
8648
8779
  // X Layer
8649
8780
  196: 30274,
8650
8781
  // X Layer Mainnet
8782
+ 1952: 40416,
8783
+ // X Layer Testnet (xlayer2-testnet)
8651
8784
  // XChain
8652
8785
  94524: 30291,
8653
8786
  // XChain Mainnet
@@ -8697,31 +8830,168 @@ var CHAIN_ID_TO_ENDPOINT_ID = {
8697
8830
  // Tron
8698
8831
  728126428: 30420,
8699
8832
  // Tron Mainnet
8700
- 2494104990: 40420
8833
+ 2494104990: 40420,
8701
8834
  // Tron Testnet
8835
+ // Newer mainnets (LayerZero metadata)
8836
+ 2044: 30148,
8837
+ // Shrapnel Subnet Mainnet
8838
+ 2355: 30379,
8839
+ // Silicon Mainnet
8840
+ 5031: 30380,
8841
+ // Somnia Mainnet
8842
+ 484: 30381,
8843
+ // Camp Mainnet
8844
+ 6985385: 30382,
8845
+ // Humanity Mainnet
8846
+ 9745: 30383,
8847
+ // Plasma Mainnet
8848
+ 9069: 30384,
8849
+ // Apex Fusion Nexus Mainnet
8850
+ 202110: 30385,
8851
+ // Dinari Mainnet
8852
+ 1408: 30386,
8853
+ // zkVerify Mainnet
8854
+ 16661: 30388,
8855
+ // 0G Mainnet
8856
+ 10088: 30389,
8857
+ // GateLayer Mainnet
8858
+ 143: 30390,
8859
+ // Monad Mainnet
8860
+ 5064014: 30391,
8861
+ // Ethereal Mainnet
8862
+ 1612: 30392,
8863
+ // Openledger Mainnet
8864
+ 97477: 30393,
8865
+ // Doma Mainnet
8866
+ 1776: 30394,
8867
+ // Injective EVM Mainnet
8868
+ 988: 30396,
8869
+ // Stable Mainnet
8870
+ 261131: 30397,
8871
+ // Zama Mainnet
8872
+ 4326: 30398,
8873
+ // MegaETH Mainnet
8874
+ 26514: 30399,
8875
+ // Horizen Mainnet
8876
+ 4153: 30401,
8877
+ // Rise Mainnet
8878
+ 151: 30402,
8879
+ // Redbelly Mainnet
8880
+ 4114: 30403,
8881
+ // Citrea Mainnet
8882
+ 2288: 30404,
8883
+ // Moca Mainnet
8884
+ 2366: 30406,
8885
+ // Kite Mainnet
8886
+ 1672: 30407,
8887
+ // Pharos Mainnet
8888
+ 3282: 30408,
8889
+ // Irys Mainnet
8890
+ 88888: 30409,
8891
+ // Chiliz Mainnet
8892
+ 4217: 30410,
8893
+ // Tempo Mainnet
8894
+ 685689: 30412,
8895
+ // Gensyn Mainnet
8896
+ 904: 30413,
8897
+ // Ault Mainnet
8898
+ 47763: 30414,
8899
+ // Neox Mainnet
8900
+ 72957: 30415,
8901
+ // Rayls Mainnet
8902
+ 4663: 30416,
8903
+ // Robinhood Chain Mainnet
8904
+ 46630: 40451,
8905
+ // Robinhood Chain Testnet
8906
+ 5042: 30417,
8907
+ // Arc Mainnet
8908
+ 36900: 30418,
8909
+ // ADI Mainnet (permissionless LayerZero deployment, not in official docs; verified on-chain via RelayV2 endpoint())
8910
+ 99999: 40462,
8911
+ // ADI Network AB Testnet
8912
+ 222: 30464,
8913
+ // Opn Mainnet
8914
+ 6714: 30465,
8915
+ // Anubis Mainnet
8916
+ 4352: 30466,
8917
+ // MemeCore Mainnet
8918
+ 177: 30467
8919
+ // HashKey Mainnet
8702
8920
  };
8703
8921
  function getEndpointId(chainId) {
8704
8922
  return CHAIN_ID_TO_ENDPOINT_ID[chainId];
8705
8923
  }
8706
8924
 
8925
+ // src/contract/layerzeroConfig.ts
8926
+ var ORDERLY_RPC_URL = {
8927
+ mainnet: "https://rpc.orderly.network",
8928
+ testnet: "https://testnet-rpc.orderly.org"
8929
+ };
8930
+ var ORDERLY_ENDPOINT_V2 = {
8931
+ mainnet: "0x1a44076050125825900e736c501f859c50fE728c",
8932
+ testnet: "0x6EDCE65403992e310A62460808c4b910D972f10f"
8933
+ };
8934
+ var ORDERLY_RELAY_OAPP = {
8935
+ mainnet: "0x461C12FBa639303Da045255dd32eEa7E38AC69b0",
8936
+ testnet: "0xe907d027F6E62794021b9839B4D234618d11Ebab"
8937
+ };
8938
+ var ORDERLY_SOL_PEER_OAPP = {
8939
+ mainnet: "0xCecAe061aa078e13b5e70D5F9eCee90a3F2B6AeA",
8940
+ testnet: "0x5Bf771A65d057e778C5f0Ed52A0003316f94322D"
8941
+ };
8942
+ function getOrderlyNetworkKey(isMainnet) {
8943
+ return isMainnet ? "mainnet" : "testnet";
8944
+ }
8945
+
8707
8946
  // src/contract/getChainConfirmations.ts
8708
8947
  async function getChainConfirmations(chain) {
8709
8948
  const chainId = chain.network_infos.chain_id;
8710
8949
  const isMainnet = chain.network_infos.mainnet;
8711
- const publicRpcUrl = isMainnet ? "https://rpc.orderly.network" : "https://testnet-rpc.orderly.org";
8712
- const contractAddress = isMainnet ? "0xCFf08a35A5f27F306e2DA99ff198dB90f13DEF77" : "0x3013C32e5F45E69ceA9baD4d96786704C2aE148c";
8713
- const endpointId = getEndpointId(chainId);
8714
- const address = "0x0000000000000000000000000000000000000000";
8715
- const provider = new ethers.JsonRpcProvider(publicRpcUrl);
8716
- const contract = new ethers.Contract(
8717
- contractAddress,
8718
- // full abi: https://explorer-orderly-mainnet-0.t.conduit.xyz/address/0xCFf08a35A5f27F306e2DA99ff198dB90f13DEF77?tab=contract_abi
8719
- // this only need to use getAppUlnConfig abi, other functions are not needed
8720
- getAppUlnConfigAbi_default,
8721
- provider
8722
- );
8723
- const result = await contract.getAppUlnConfig(address, endpointId);
8724
- return Number(result.confirmations || 0);
8950
+ const networkKey = getOrderlyNetworkKey(isMainnet);
8951
+ const sourceEid = getEndpointId(chainId);
8952
+ if (!sourceEid) {
8953
+ return 0;
8954
+ }
8955
+ const oapp = resolveDepositOApp(chainId, networkKey);
8956
+ const provider = new ethers.JsonRpcProvider(ORDERLY_RPC_URL[networkKey]);
8957
+ try {
8958
+ const endpoint = new ethers.Contract(
8959
+ ORDERLY_ENDPOINT_V2[networkKey],
8960
+ endpointV2Abi_default,
8961
+ provider
8962
+ );
8963
+ const [receiveLibAddress] = await endpoint.getReceiveLibrary(
8964
+ oapp,
8965
+ sourceEid
8966
+ );
8967
+ if (!receiveLibAddress || receiveLibAddress === ethers.ZeroAddress) {
8968
+ return 0;
8969
+ }
8970
+ const receiveLib = new ethers.Contract(
8971
+ receiveLibAddress,
8972
+ getAppUlnConfigAbi_default,
8973
+ provider
8974
+ );
8975
+ const config = await receiveLib.getAppUlnConfig(oapp, sourceEid);
8976
+ const confirmations = Number(config.confirmations || 0);
8977
+ if (confirmations > 0) {
8978
+ return confirmations;
8979
+ }
8980
+ const defaultConfig = await receiveLib.getAppUlnConfig(
8981
+ ethers.ZeroAddress,
8982
+ sourceEid
8983
+ );
8984
+ return Number(defaultConfig.confirmations || 0);
8985
+ } catch (error) {
8986
+ console.error("getChainConfirmations error", error);
8987
+ return 0;
8988
+ }
8989
+ }
8990
+ function resolveDepositOApp(chainId, networkKey) {
8991
+ if (isSolana(chainId)) {
8992
+ return ORDERLY_SOL_PEER_OAPP[networkKey];
8993
+ }
8994
+ return ORDERLY_RELAY_OAPP[networkKey];
8725
8995
  }
8726
8996
 
8727
8997
  // src/contract/useTransactionTime.ts
@@ -8731,7 +9001,6 @@ var useTransactionTime = (chainId) => {
8731
9001
  const timeMap = useRef({});
8732
9002
  const confirmationsMap = useRef({});
8733
9003
  const [, { findByChainId }] = useChains();
8734
- const { wallet } = useWalletConnector();
8735
9004
  const chain = useMemo(() => {
8736
9005
  if (!chainId) {
8737
9006
  return;
@@ -8740,7 +9009,7 @@ var useTransactionTime = (chainId) => {
8740
9009
  return findByChainId(id);
8741
9010
  }, [chainId, findByChainId]);
8742
9011
  useEffect(() => {
8743
- if (!chain || !wallet) {
9012
+ if (!chain) {
8744
9013
  return;
8745
9014
  }
8746
9015
  const chainId2 = chain.network_infos.chain_id;
@@ -8749,8 +9018,7 @@ var useTransactionTime = (chainId) => {
8749
9018
  } else {
8750
9019
  getBlockTime({
8751
9020
  chainId: chainId2,
8752
- chain,
8753
- wallet
9021
+ chain
8754
9022
  }).then((time) => {
8755
9023
  console.log("average block time", chainId2, time);
8756
9024
  setBlockTime(time);
@@ -8770,7 +9038,7 @@ var useTransactionTime = (chainId) => {
8770
9038
  console.error("getChainConfirmations error", error);
8771
9039
  });
8772
9040
  }
8773
- }, [chain, wallet]);
9041
+ }, [chain]);
8774
9042
  const transactionTime = useMemo(() => {
8775
9043
  if (blockTime && confirmations) {
8776
9044
  return blockTime * confirmations;
@@ -8919,8 +9187,13 @@ function useDepositStatusScript() {
8919
9187
  onClose
8920
9188
  };
8921
9189
  }
9190
+ var MIN_ESTIMATED_SECONDS = 30;
9191
+ var MAX_ESTIMATED_SECONDS = 30 * 60;
8922
9192
  function formatEstimatedTime(totalSeconds) {
8923
- const sec = Math.max(30, totalSeconds);
9193
+ const sec = Math.min(
9194
+ MAX_ESTIMATED_SECONDS,
9195
+ Math.max(MIN_ESTIMATED_SECONDS, totalSeconds)
9196
+ );
8924
9197
  let minutes = Math.floor(sec / 60);
8925
9198
  let seconds = sec % 60;
8926
9199
  if (seconds > 0 && seconds <= 30) {