{loading ? (
@@ -227,7 +220,7 @@ export const TransactionHistoryTable = (
) : (
-
+
@@ -243,85 +236,81 @@ export const TransactionHistoryTable = (
{pendingTokenDepositsCount > 0 &&
}
-
- {() => (
- (
-
- {props.columns}
-
- )}
- className="table-auto last:border-b-0"
- rowGetter={({ index }) => transactions[index]}
- rowRenderer={({ index, style }) => {
- const tx = transactions[index]
+ (
+
+ {props.columns}
+
+ )}
+ className="table-auto last:border-b-0"
+ rowGetter={({ index }) => transactions[index]}
+ rowRenderer={({ index, style }) => {
+ const tx = transactions[index]
- if (!tx) {
- return null
- }
+ if (!tx) {
+ return null
+ }
- const isLastRow = index + 1 === transactions.length
- const key = `${tx.parentChainId}-${tx.childChainId}-${tx.txId}`
- const secondsPassed = dayjs().diff(dayjs(tx.createdAt), 'second')
+ const isLastRow = index + 1 === transactions.length
+ const key = `${tx.parentChainId}-${tx.childChainId}-${tx.txId}`
+ const secondsPassed = dayjs().diff(dayjs(tx.createdAt), 'second')
- // only blink the topmost tx, in case many txs are queued in a short amount of time
- const isTopmostPendingTx =
- topmostPendingTxId && topmostPendingTxId === tx.txId
+ // only blink the topmost tx, in case many txs are queued in a short amount of time
+ const isTopmostPendingTx =
+ topmostPendingTxId && topmostPendingTxId === tx.txId
- return (
-
-
-
- )
- }}
- >
- TIME}
- />
- TOKEN}
- />
- FROM}
- />
- TO}
- />
- STATUS}
- />
-
- )}
-
+ return (
+
+
+
+ )
+ }}
+ >
+ TIME}
+ />
+ TOKEN}
+ />
+ FROM}
+ />
+ TO}
+ />
+ STATUS}
+ />
+
)
}
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionStatusInfo.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionStatusInfo.tsx
index 88ab67d208..fb4ee1f9d7 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionStatusInfo.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionStatusInfo.tsx
@@ -3,21 +3,12 @@
Format: "You have [X] deposits to retry and [Y] withdrawals ready to claim. [CTA]"
*/
-import { useAccount } from 'wagmi'
-import { useMemo } from 'react'
-import {
- DocumentTextIcon,
- ExclamationTriangleIcon
-} from '@heroicons/react/24/outline'
+import { ExclamationTriangleIcon } from '@heroicons/react/24/outline'
import { twMerge } from 'tailwind-merge'
import Image from 'next/image'
import ArrowsIcon from '@/images/arrows.svg'
-import { isDepositReadyToRedeem } from '../../state/app/utils'
-import { useAppContextActions } from '../App/AppContext'
-import { useTransactionHistory } from '../../hooks/useTransactionHistory'
-import { Button } from '../common/Button'
-import { isTxClaimable, isTxPending } from './helpers'
+import { useTransactionReminderInfo } from './useTransactionReminderInfo'
const Content = ({
numClaimableTransactions,
@@ -87,79 +78,37 @@ const Content = ({
)
}
- return (
-
-
- See transaction history
-
- )
+ return null
}
export const TransactionStatusInfo = () => {
- const { address } = useAccount()
- const { openTransactionHistoryPanel } = useAppContextActions()
- const { transactions } = useTransactionHistory(address)
-
const {
numClaimableTransactions,
numRetryablesToRedeem,
- numPendingTransactions
- } = useMemo(() => {
- return transactions.reduce(
- (acc, tx) => {
- // standard bridge withdrawal
- if (isTxClaimable(tx)) {
- acc.numClaimableTransactions += 1
- }
- // failed retryable
- if (isDepositReadyToRedeem(tx)) {
- acc.numRetryablesToRedeem += 1
- }
- // all pending
- if (isTxPending(tx)) {
- acc.numPendingTransactions += 1
- }
- return acc
- },
- {
- numClaimableTransactions: 0,
- numRetryablesToRedeem: 0,
- numPendingTransactions: 0
- }
- )
- }, [transactions])
+ numPendingTransactions,
+ colorClassName
+ } = useTransactionReminderInfo()
- const buttonClassName = useMemo(() => {
- if (numRetryablesToRedeem > 0) {
- return 'bg-red-700'
- }
- if (numClaimableTransactions > 0) {
- return 'bg-lime-dark'
- }
- if (numPendingTransactions > 0) {
- return 'bg-cyan-dark'
- }
- return 'bg-gray-1 text-white/70'
- }, [numClaimableTransactions, numPendingTransactions, numRetryablesToRedeem])
+ if (
+ numClaimableTransactions === 0 &&
+ numRetryablesToRedeem === 0 &&
+ numPendingTransactions === 0
+ ) {
+ return null
+ }
return (
-
+
)
}
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetails.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetails.tsx
index a4122e6275..e3802a095b 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetails.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetails.tsx
@@ -22,12 +22,12 @@ import { GET_HELP_LINK, ether } from '../../constants'
import { useTransactionHistory } from '../../hooks/useTransactionHistory'
import { shortenAddress } from '../../util/CommonUtils'
import { isTxCompleted } from './helpers'
-import { Address } from '../../util/AddressUtils'
import { sanitizeTokenSymbol } from '../../util/TokenUtils'
import { isBatchTransfer } from '../../util/TokenDepositUtils'
import { BatchTransferNativeTokenTooltip } from './TransactionHistoryTable'
import { useNativeCurrency } from '../../hooks/useNativeCurrency'
import { isCustomDestinationAddressTx } from '../../state/app/utils'
+import { useTransactionHistoryAddressStore } from './TransactionHistorySearchBar'
const DetailsBox = ({
children,
@@ -43,14 +43,11 @@ const DetailsBox = ({
)
}
-export const TransactionsTableDetails = ({
- address
-}: {
- address: Address | undefined
-}) => {
+export const TransactionsTableDetails = () => {
+ const { sanitizedAddress } = useTransactionHistoryAddressStore()
const { tx: txFromStore, isOpen, close, reset } = useTxDetailsStore()
const { ethToUSD } = useETHPrice()
- const { transactions } = useTransactionHistory(address)
+ const { transactions } = useTransactionHistory(sanitizedAddress)
const tx = useMemo(() => {
if (!txFromStore) {
@@ -69,7 +66,7 @@ export const TransactionsTableDetails = ({
const childProvider = getProviderForChainId(tx?.childChainId ?? 0)
const nativeCurrency = useNativeCurrency({ provider: childProvider })
- if (!tx || !address || !nativeCurrency) {
+ if (!tx || !sanitizedAddress || !nativeCurrency) {
return null
}
@@ -82,9 +79,9 @@ export const TransactionsTableDetails = ({
!isNetwork(tx.parentChainId).isTestnet && tx.asset === ether.symbol
const isDifferentSourceAddress =
- address.toLowerCase() !== tx.sender?.toLowerCase()
+ sanitizedAddress.toLowerCase() !== tx.sender?.toLowerCase()
const isDifferentDestinationAddress = isCustomDestinationAddressTx({
- sender: address,
+ sender: sanitizedAddress,
destination: tx.destination
})
@@ -269,7 +266,7 @@ export const TransactionsTableDetails = ({
)}
-
+
{!isTxCompleted(tx) && (
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsSteps.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsSteps.tsx
index a349b939ff..7eff130e15 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsSteps.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsSteps.tsx
@@ -21,7 +21,7 @@ import { ExternalLink } from '../common/ExternalLink'
import { TransferCountdown } from '../common/TransferCountdown'
import { isDepositReadyToRedeem } from '../../state/app/utils'
import { Address } from '../../util/AddressUtils'
-import { isTeleportTx } from '../../hooks/useTransactions'
+import { isTeleportTx } from '../../types/Transactions'
import {
firstRetryableLegRequiresRedeem,
secondRetryableLegForTeleportRequiresRedeem
@@ -31,6 +31,7 @@ import {
minutesToHumanReadableTime,
useTransferDuration
} from '../../hooks/useTransferDuration'
+import { useTransactionHistoryAddressStore } from './TransactionHistorySearchBar'
function needsToClaimTransfer(tx: MergedTransaction) {
return tx.isCctp || tx.isWithdrawal
@@ -136,14 +137,7 @@ const LastStepEndItem = ({
(!isTeleport && isDepositReadyToRedeem(tx)) ||
(isTeleport && secondRetryableLegForTeleportRequiresRedeem(tx))
) {
- return (
-
- )
+ return
}
return null
@@ -162,13 +156,12 @@ export const TransactionFailedOnNetwork = ({
)
export const TransactionsTableDetailsSteps = ({
- tx,
- address
+ tx
}: {
tx: MergedTransaction
- address: Address | undefined
}) => {
const { approximateDurationInMinutes } = useTransferDuration(tx)
+ const { sanitizedAddress } = useTransactionHistoryAddressStore()
const { sourceChainId } = tx
@@ -240,9 +233,7 @@ export const TransactionsTableDetailsSteps = ({
/>
)}
- {isTeleportTx(tx) && (
-
- )}
+ {isTeleportTx(tx) &&
}
{/* If claiming is required we show this step */}
{needsToClaimTransfer(tx) && (
@@ -256,7 +247,6 @@ export const TransactionsTableDetailsSteps = ({
type={tx.isWithdrawal ? 'withdrawals' : 'deposits'}
isError={false}
tx={tx}
- address={address}
/>
)
}
@@ -268,7 +258,7 @@ export const TransactionsTableDetailsSteps = ({
done={isTxCompleted(tx)}
failure={isTxExpired(tx) || isDestinationChainFailure}
text={destinationChainTxText}
- endItem={
}
+ endItem={
}
/>
)
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsTeleporterSteps.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsTeleporterSteps.tsx
index 0540259aa3..a9a573b189 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsTeleporterSteps.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableDetailsTeleporterSteps.tsx
@@ -1,5 +1,4 @@
import { useMemo } from 'react'
-import { Address } from 'wagmi'
import { twMerge } from 'tailwind-merge'
import {
ArrowTopRightOnSquareIcon,
@@ -72,11 +71,9 @@ const TeleportMiddleStepFailureExplanationNote = ({
}
export const TransactionsTableDetailsTeleporterSteps = ({
- tx,
- address
+ tx
}: {
tx: TeleporterMergedTransaction
- address: Address | undefined
}) => {
const l2TxID = tx.parentToChildMsgData?.childTxId
const isFirstRetryableLegSucceeded =
@@ -96,15 +93,8 @@ export const TransactionsTableDetailsTeleporterSteps = ({
typeof tx.l2ToL3MsgData?.l3TxID !== 'undefined'
const firstRetryableRedeemButton = useMemo(
- () => (
-
- ),
- [tx, address]
+ () =>
,
+ [tx]
)
const firstTransactionExternalLink = useMemo(
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRow.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRow.tsx
index 515ba807c6..01f887a666 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRow.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRow.tsx
@@ -121,11 +121,9 @@ const StatusLabel = ({ tx }: { tx: MergedTransaction }) => {
export function TransactionsTableRow({
tx,
- address,
className = ''
}: {
tx: MergedTransaction
- address: Address | undefined
className?: string
}) {
const { open: openTxDetails } = useTxDetailsStore()
@@ -189,7 +187,7 @@ export function TransactionsTableRow({
@@ -259,7 +257,6 @@ export function TransactionsTableRow({
tx={tx}
isError={isError}
type={tx.isWithdrawal ? 'withdrawals' : 'deposits'}
- address={address}
/>
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRowAction.tsx b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRowAction.tsx
index af4fe167ef..1b6bce2c75 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRowAction.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRowAction.tsx
@@ -1,4 +1,6 @@
import { useCallback } from 'react'
+import { useAccount, useNetwork } from 'wagmi'
+
import { GET_HELP_LINK } from '../../constants'
import { useClaimWithdrawal } from '../../hooks/useClaimWithdrawal'
import { useClaimCctp } from '../../state/cctpState'
@@ -13,31 +15,37 @@ import { getNetworkName } from '../../util/networks'
import { errorToast } from '../common/atoms/Toast'
import { Button } from '../common/Button'
import { useSwitchNetworkWithConfig } from '../../hooks/useSwitchNetworkWithConfig'
-import { useNetwork } from 'wagmi'
import { isDepositReadyToRedeem } from '../../state/app/utils'
import { useRedeemRetryable } from '../../hooks/useRedeemRetryable'
import { TransferCountdown } from '../common/TransferCountdown'
-import { Address } from '../../util/AddressUtils'
import { getChainIdForRedeemingRetryable } from '../../util/RetryableUtils'
-import { isTeleportTx } from '../../hooks/useTransactions'
+import { isTeleportTx } from '../../types/Transactions'
import { useRedeemTeleporter } from '../../hooks/useRedeemTeleporter'
import { sanitizeTokenSymbol } from '../../util/TokenUtils'
import { formatAmount } from '../../util/NumberUtils'
+import { useTransactionHistoryAddressStore } from './TransactionHistorySearchBar'
+import { Tooltip } from '../common/Tooltip'
export function TransactionsTableRowAction({
tx,
isError,
- type,
- address
+ type
}: {
tx: MergedTransaction | TeleporterMergedTransaction
isError: boolean
type: 'deposits' | 'withdrawals'
- address: Address | undefined
}) {
+ const { address: connectedAddress } = useAccount()
const { chain } = useNetwork()
const { switchNetworkAsync } = useSwitchNetworkWithConfig()
const networkName = getNetworkName(chain?.id ?? 0)
+ const { sanitizedAddress: searchedAddress } =
+ useTransactionHistoryAddressStore()
+
+ const isViewingAnotherAddress =
+ connectedAddress &&
+ searchedAddress &&
+ connectedAddress.toLowerCase() !== searchedAddress.toLowerCase()
const tokenSymbol = sanitizeTokenSymbol(tx.asset, {
erc20L1Address: tx.tokenAddress,
@@ -48,10 +56,10 @@ export function TransactionsTableRowAction({
const { claim: claimCctp, isClaiming: isClaimingCctp } = useClaimCctp(tx)
const { redeem, isRedeeming: isRetryableRedeeming } = useRedeemRetryable(
tx,
- address
+ searchedAddress
)
const { redeem: teleporterRedeem, isRedeeming: isTeleporterRedeeming } =
- useRedeemTeleporter(tx, address)
+ useRedeemTeleporter(tx, searchedAddress)
const isRedeeming = isRetryableRedeeming || isTeleporterRedeeming
@@ -163,16 +171,25 @@ export function TransactionsTableRowAction({
return isClaiming || isClaimingCctp ? (
Claiming...
) : (
-
+
+
)
}
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/helpers.ts b/packages/arb-token-bridge-ui/src/components/TransactionHistory/helpers.ts
index bc44d3cec3..ce795b4526 100644
--- a/packages/arb-token-bridge-ui/src/components/TransactionHistory/helpers.ts
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/helpers.ts
@@ -15,7 +15,8 @@ import {
TeleporterMergedTransaction,
WithdrawalStatus
} from '../../state/app/state'
-import { ChainId, getL1BlockTime, isNetwork } from '../../util/networks'
+import { getL1BlockTime, isNetwork } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { Deposit, Transfer } from '../../hooks/useTransactionHistory'
import {
getParentToChildMessageDataFromParentTxHash,
@@ -31,20 +32,12 @@ import { getAttestationHashAndMessageFromReceipt } from '../../util/cctp/getAtte
import { getOutgoingMessageState } from '../../util/withdrawals/helpers'
import { getUniqueIdOrHashFromEvent } from '../../hooks/useArbTokenBridge'
import { getProviderForChainId } from '../../token-bridge-sdk/utils'
-import { isTeleportTx } from '../../hooks/useTransactions'
+import { isTeleportTx } from '../../types/Transactions'
const PARENT_CHAIN_TX_DETAILS_OF_CLAIM_TX =
'arbitrum:bridge:claim:parent:tx:details'
const DEPOSITS_LOCAL_STORAGE_KEY = 'arbitrum:bridge:deposits'
-export enum StatusLabel {
- PENDING = 'Pending',
- CLAIMABLE = 'Claimable',
- SUCCESS = 'Success',
- EXPIRED = 'Expired',
- FAILURE = 'Failure'
-}
-
function isDeposit(tx: MergedTransaction): boolean {
return !tx.isWithdrawal
}
diff --git a/packages/arb-token-bridge-ui/src/components/TransactionHistory/useTransactionReminderInfo.ts b/packages/arb-token-bridge-ui/src/components/TransactionHistory/useTransactionReminderInfo.ts
new file mode 100644
index 0000000000..7efe41e359
--- /dev/null
+++ b/packages/arb-token-bridge-ui/src/components/TransactionHistory/useTransactionReminderInfo.ts
@@ -0,0 +1,60 @@
+import { useMemo } from 'react'
+import { useAccount } from 'wagmi'
+
+import { useTransactionHistory } from '../../hooks/useTransactionHistory'
+import { isTxClaimable, isTxPending } from './helpers'
+import { isDepositReadyToRedeem } from '../../state/app/utils'
+
+export function useTransactionReminderInfo() {
+ const { address } = useAccount()
+ const { transactions } = useTransactionHistory(address)
+
+ const {
+ numClaimableTransactions,
+ numRetryablesToRedeem,
+ numPendingTransactions
+ } = useMemo(() => {
+ return transactions.reduce(
+ (acc, tx) => {
+ // standard bridge withdrawal
+ if (isTxClaimable(tx)) {
+ acc.numClaimableTransactions += 1
+ }
+ // failed retryable
+ if (isDepositReadyToRedeem(tx)) {
+ acc.numRetryablesToRedeem += 1
+ }
+ // all pending
+ if (isTxPending(tx)) {
+ acc.numPendingTransactions += 1
+ }
+ return acc
+ },
+ {
+ numClaimableTransactions: 0,
+ numRetryablesToRedeem: 0,
+ numPendingTransactions: 0
+ }
+ )
+ }, [transactions])
+
+ const colorClassName = useMemo(() => {
+ if (numRetryablesToRedeem > 0) {
+ return { dark: 'bg-red-700', light: 'bg-retry' }
+ }
+ if (numClaimableTransactions > 0) {
+ return { dark: 'bg-lime-dark', light: 'bg-claim' }
+ }
+ if (numPendingTransactions > 0) {
+ return { dark: 'bg-cyan-dark', light: 'bg-pending' }
+ }
+ return { dark: 'bg-gray-1 text-white/70', light: '' }
+ }, [numClaimableTransactions, numPendingTransactions, numRetryablesToRedeem])
+
+ return {
+ numClaimableTransactions,
+ numRetryablesToRedeem,
+ numPendingTransactions,
+ colorClassName
+ }
+}
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/EstimatedGas.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/EstimatedGas.tsx
index be0675afcc..0b1de4f338 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/EstimatedGas.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/EstimatedGas.tsx
@@ -3,7 +3,8 @@ import { useMemo } from 'react'
import { twMerge } from 'tailwind-merge'
import { useAppState } from '../../state'
-import { ChainId, getNetworkName, isNetwork } from '../../util/networks'
+import { getNetworkName, isNetwork } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { Tooltip } from '../common/Tooltip'
import { formatAmount } from '../../util/NumberUtils'
import { useNativeCurrency } from '../../hooks/useNativeCurrency'
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/OneNovaTransferDialog.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/OneNovaTransferDialog.tsx
index 44a8c540d5..c48987fa35 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/OneNovaTransferDialog.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/OneNovaTransferDialog.tsx
@@ -7,7 +7,8 @@ import { BridgesTable } from '../common/BridgesTable'
import { SecurityNotGuaranteed } from './SecurityLabels'
import { Dialog, UseDialogProps } from '../common/Dialog'
import { FastBridgeInfo, FastBridgeNames } from '../../util/fastBridges'
-import { ChainId, getNetworkName, isNetwork } from '../../util/networks'
+import { getNetworkName, isNetwork } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { ether } from '../../constants'
import { useArbQueryParams } from '../../hooks/useArbQueryParams'
import { useNetworks } from '../../hooks/useNetworks'
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx
index 65fcb9dafe..6d95a50d2a 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx
@@ -34,9 +34,9 @@ import { TokenLogoFallback } from './TokenInfo'
import { useBalanceOnSourceChain } from '../../hooks/useBalanceOnSourceChain'
import { useSourceChainNativeCurrencyDecimals } from '../../hooks/useSourceChainNativeCurrencyDecimals'
-function tokenListIdsToNames(ids: number[]): string {
+function tokenListIdsToNames(ids: string[]): string {
return ids
- .map((tokenListId: number) => listIdsToNames[tokenListId])
+ .map((tokenListId: string) => listIdsToNames[tokenListId])
.join(', ')
}
@@ -90,7 +90,7 @@ function TokenListInfo({ token }: { token: ERC20BridgeToken | null }) {
return 'Native USDC on Arbitrum Sepolia'
}
- const listIds: Set
= token.listIds
+ const listIds: Set = token.listIds
const listIdsSize = listIds.size
if (listIdsSize === 0) {
return 'Added by User'
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx
index 93af1c6977..8d90a95caa 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx
@@ -47,7 +47,7 @@ import { useSetInputAmount } from '../../hooks/TransferPanel/useSetInputAmount'
export const ARB_ONE_NATIVE_USDC_TOKEN = {
...ArbOneNativeUSDC,
- listIds: new Set(),
+ listIds: new Set(),
type: TokenType.ERC20,
// the address field is for L1 address but native USDC does not have an L1 address
// the L2 address is used instead to avoid errors
@@ -57,7 +57,7 @@ export const ARB_ONE_NATIVE_USDC_TOKEN = {
export const ARB_SEPOLIA_NATIVE_USDC_TOKEN = {
...ArbOneNativeUSDC,
- listIds: new Set(),
+ listIds: new Set(),
type: TokenType.ERC20,
address: CommonAddress.ArbitrumSepolia.USDC,
l2Address: CommonAddress.ArbitrumSepolia.USDC
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferDisabledDialog.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferDisabledDialog.tsx
index 12b9dcfdd0..8f5d993e54 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferDisabledDialog.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferDisabledDialog.tsx
@@ -6,7 +6,8 @@ import { Dialog } from '../common/Dialog'
import { sanitizeTokenSymbol } from '../../util/TokenUtils'
import { useNetworks } from '../../hooks/useNetworks'
import { ExternalLink } from '../common/ExternalLink'
-import { ChainId, getNetworkName } from '../../util/networks'
+import { getNetworkName } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { getL2ConfigForTeleport } from '../../token-bridge-sdk/teleport'
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'
import { withdrawOnlyTokens } from '../../util/WithdrawOnlyUtils'
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx
index b3b08daae4..5710d4ba57 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx
@@ -75,6 +75,7 @@ import { MoveFundsButton } from './MoveFundsButton'
import { ProjectsListing } from '../common/ProjectsListing'
import { useAmountBigNumber } from './hooks/useAmountBigNumber'
import { useSourceChainNativeCurrencyDecimals } from '../../hooks/useSourceChainNativeCurrencyDecimals'
+import { useMainContentTabs } from '../MainContent/MainContent'
const signerUndefinedError = 'Signer is undefined'
const transferNotAllowedError = 'Transfer not allowed'
@@ -140,8 +141,8 @@ export function TransferPanel() {
chainId: networks.sourceChain.id
})
- const { openTransactionHistoryPanel, setTransferring } =
- useAppContextActions()
+ const { setTransferring } = useAppContextActions()
+ const { switchToTransactionHistoryTab } = useMainContentTabs()
const { addPendingTransaction } = useTransactionHistory(walletAddress)
const isCctpTransfer = useIsCctpTransfer()
@@ -497,7 +498,7 @@ export function TransferPanel() {
}
addPendingTransaction(newTransfer)
- openTransactionHistoryPanel()
+ switchToTransactionHistoryTab()
setTransferring(false)
clearAmountInput()
} catch (e) {
@@ -836,7 +837,7 @@ export function TransferPanel() {
)
}
- openTransactionHistoryPanel()
+ switchToTransactionHistoryTab()
setTransferring(false)
clearAmountInput()
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts
index 4d748b11ca..9cb4413a42 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts
@@ -16,7 +16,7 @@ const commonUSDC = {
type: TokenType.ERC20,
symbol: 'USDC',
decimals: 6,
- listIds: new Set()
+ listIds: new Set()
}
export function useUpdateUSDCTokenData() {
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/utils.ts b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/utils.ts
index 930bab1453..8f6ee3a2ba 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/utils.ts
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/utils.ts
@@ -1,4 +1,4 @@
-import { ChainId } from '../../../util/networks'
+import { ChainId } from '../../../types/ChainId'
export enum NetworkType {
parentChain = 'parentChain',
diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelSummary.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelSummary.tsx
index 53015bc306..3761043fd8 100644
--- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelSummary.tsx
+++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelSummary.tsx
@@ -1,6 +1,7 @@
import React, { useMemo } from 'react'
import { InformationCircleIcon } from '@heroicons/react/24/outline'
import { twMerge } from 'tailwind-merge'
+import Image from 'next/image'
import { formatAmount } from '../../util/NumberUtils'
import { getNetworkName, isNetwork } from '../../util/networks'
@@ -20,6 +21,7 @@ import { NoteBox } from '../common/NoteBox'
import { DISABLED_CHAIN_IDS } from './useTransferReadiness'
import { useIsBatchTransferSupported } from '../../hooks/TransferPanel/useIsBatchTransferSupported'
import { getConfirmationTime } from '../../util/WithdrawalUtils'
+import LightningIcon from '@/images/LightningIcon.svg'
export type TransferPanelSummaryToken = {
symbol: string
@@ -284,7 +286,7 @@ function ConfirmationTimeInfo({ chainId }: { chainId: number }) {
return (
<>
Confirmation time:
-
+
{confirmationTimeInReadableFormat}
@@ -292,13 +294,19 @@ function ConfirmationTimeInfo({ chainId }: { chainId: number }) {
{confirmationTimeInReadableFormatShort}
{fastWithdrawalActive && (
-
-
-
+
)}
>
diff --git a/packages/arb-token-bridge-ui/src/components/common/AddCustomChain.tsx b/packages/arb-token-bridge-ui/src/components/common/AddCustomChain.tsx
index 76a346f12e..9be3138a8d 100644
--- a/packages/arb-token-bridge-ui/src/components/common/AddCustomChain.tsx
+++ b/packages/arb-token-bridge-ui/src/components/common/AddCustomChain.tsx
@@ -11,7 +11,6 @@ import SyntaxHighlighter from 'react-syntax-highlighter'
import { stackoverflowDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'
import {
- ChainId,
ChainWithRpcUrl,
getCustomChainsFromLocalStorage,
getCustomChainFromLocalStorageById,
@@ -22,6 +21,7 @@ import {
rpcURLs,
isNetwork
} from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { Loader } from './atoms/Loader'
import { Erc20Data, fetchErc20Data } from '../../util/TokenUtils'
import { getProviderForChainId } from '@/token-bridge-sdk/utils'
diff --git a/packages/arb-token-bridge-ui/src/components/common/HeaderAccountPopover.tsx b/packages/arb-token-bridge-ui/src/components/common/HeaderAccountPopover.tsx
index 14a265f973..11e9ba28ee 100644
--- a/packages/arb-token-bridge-ui/src/components/common/HeaderAccountPopover.tsx
+++ b/packages/arb-token-bridge-ui/src/components/common/HeaderAccountPopover.tsx
@@ -4,8 +4,7 @@ import {
ArrowTopRightOnSquareIcon,
ChevronDownIcon,
Cog6ToothIcon,
- DocumentDuplicateIcon,
- DocumentTextIcon
+ DocumentDuplicateIcon
} from '@heroicons/react/24/outline'
import { useState } from 'react'
import { useCopyToClipboard, useMedia } from 'react-use'
@@ -31,7 +30,6 @@ export function HeaderAccountPopover({
accountShort,
ensName,
ensAvatar,
- openTransactionHistory,
disconnect,
udInfo,
chain,
@@ -130,17 +128,6 @@ export function HeaderAccountPopover({
- {/* Transactions button */}
- {isCorrectNetworkConnected && (
-
- )}
-
{/* Explorer button */}
{isCorrectNetworkConnected && chain && (
(
- callback: () => T,
- delay: number
-): { forceTrigger: typeof callback } => {
- const savedCallback = useRef(callback)
- const savedTimer = useRef(undefined)
-
- // Remember the latest callback if it changes.
- useEffect(() => {
- savedCallback.current = callback
- }, [callback])
-
- // Set up the interval.
- useEffect(() => {
- savedTimer.current = setInterval(() => savedCallback.current(), delay)
- return () => clearInterval(savedTimer.current!)
- }, [delay])
-
- const forceTrigger = () => {
- clearInterval(savedTimer.current!)
- // make call then setup the timer again
- const res = savedCallback.current()
- savedTimer.current = setInterval(() => savedCallback.current(), delay)
- return res
- }
-
- return { forceTrigger }
-}
diff --git a/packages/arb-token-bridge-ui/src/components/common/Layout.tsx b/packages/arb-token-bridge-ui/src/components/common/Layout.tsx
index 119e218f30..b88df815e4 100644
--- a/packages/arb-token-bridge-ui/src/components/common/Layout.tsx
+++ b/packages/arb-token-bridge-ui/src/components/common/Layout.tsx
@@ -52,7 +52,7 @@ export function Layout(props: LayoutProps) {
aria-hidden
/>
-
+
diff --git a/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx b/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx
index dc328d6034..aab6e65c24 100644
--- a/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx
+++ b/packages/arb-token-bridge-ui/src/components/common/NetworkSelectionContainer.tsx
@@ -15,7 +15,8 @@ import {
import { twMerge } from 'tailwind-merge'
import { AutoSizer, List, ListRowProps } from 'react-virtualized'
-import { ChainId, isNetwork, getNetworkName } from '../../util/networks'
+import { isNetwork, getNetworkName } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { useIsTestnetMode } from '../../hooks/useIsTestnetMode'
import { SearchPanel } from './SearchPanel/SearchPanel'
import { SearchPanelTable } from './SearchPanel/SearchPanelTable'
diff --git a/packages/arb-token-bridge-ui/src/components/common/TransferCountdown.tsx b/packages/arb-token-bridge-ui/src/components/common/TransferCountdown.tsx
index 5806342bc8..d19c8c2e5b 100644
--- a/packages/arb-token-bridge-ui/src/components/common/TransferCountdown.tsx
+++ b/packages/arb-token-bridge-ui/src/components/common/TransferCountdown.tsx
@@ -5,7 +5,7 @@ import {
useTransferDuration
} from '../../hooks/useTransferDuration'
import { isNetwork } from '../../util/networks'
-import { isTeleportTx } from '../../hooks/useTransactions'
+import { isTeleportTx } from '../../types/Transactions'
/**
* Displays a transfer countdown for a deposit, withdrawal, or cctp.
diff --git a/packages/arb-token-bridge-ui/src/components/syncers/BalanceUpdater.tsx b/packages/arb-token-bridge-ui/src/components/syncers/BalanceUpdater.tsx
deleted file mode 100644
index 6a35e1cea2..0000000000
--- a/packages/arb-token-bridge-ui/src/components/syncers/BalanceUpdater.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { useEffect } from 'react'
-import { useLatest } from 'react-use'
-import { useAccount } from 'wagmi'
-
-import { useAppState } from '../../state'
-import { useUpdateUSDCBalances } from '../../hooks/CCTP/useUpdateUSDCBalances'
-
-// Updates all balances periodically
-const BalanceUpdater = (): JSX.Element => {
- const {
- app: { arbTokenBridge, selectedToken }
- } = useAppState()
- const { address: walletAddress } = useAccount()
- const latestTokenBridge = useLatest(arbTokenBridge)
-
- const { updateUSDCBalances } = useUpdateUSDCBalances({
- walletAddress
- })
-
- useEffect(() => {
- const interval = setInterval(() => {
- updateUSDCBalances()
-
- if (selectedToken) {
- latestTokenBridge?.current?.token?.updateTokenData(
- selectedToken.address
- )
- }
- }, 10000)
-
- return () => clearInterval(interval)
- }, [selectedToken])
-
- return <>>
-}
-
-export { BalanceUpdater }
diff --git a/packages/arb-token-bridge-ui/src/components/syncers/useBalanceUpdater.tsx b/packages/arb-token-bridge-ui/src/components/syncers/useBalanceUpdater.tsx
new file mode 100644
index 0000000000..728322ced2
--- /dev/null
+++ b/packages/arb-token-bridge-ui/src/components/syncers/useBalanceUpdater.tsx
@@ -0,0 +1,26 @@
+import { useInterval, useLatest } from 'react-use'
+import { useAccount } from 'wagmi'
+
+import { useAppState } from '../../state'
+import { useUpdateUSDCBalances } from '../../hooks/CCTP/useUpdateUSDCBalances'
+
+// Updates all balances periodically
+export function useBalanceUpdater() {
+ const {
+ app: { arbTokenBridge, selectedToken }
+ } = useAppState()
+ const { address: walletAddress } = useAccount()
+ const latestTokenBridge = useLatest(arbTokenBridge)
+
+ const { updateUSDCBalances } = useUpdateUSDCBalances({
+ walletAddress
+ })
+
+ useInterval(() => {
+ updateUSDCBalances()
+
+ if (selectedToken) {
+ latestTokenBridge?.current?.token?.updateTokenData(selectedToken.address)
+ }
+ }, 10000)
+}
diff --git a/packages/arb-token-bridge-ui/src/constants.ts b/packages/arb-token-bridge-ui/src/constants.ts
index 85b03a5336..1e2e7b9ab4 100644
--- a/packages/arb-token-bridge-ui/src/constants.ts
+++ b/packages/arb-token-bridge-ui/src/constants.ts
@@ -12,8 +12,6 @@ export const DOCS_DOMAIN = 'https://docs.arbitrum.io'
export const USDC_LEARN_MORE_LINK = `${DOCS_DOMAIN}/bridge-tokens/concepts/usdc-concept`
-export const FAST_BRIDGE_ARTICLE_LINK = `${SUPPORT_LINK_BASE}/hc/en-us/articles/18213771832987`
-
export const TOKEN_APPROVAL_ARTICLE_LINK = `${SUPPORT_LINK_BASE}/hc/en-us/articles/18213893952923`
export const ETH_BALANCE_ARTICLE_LINK = `${SUPPORT_LINK_BASE}/hc/en-us/articles/18213854684699`
diff --git a/packages/arb-token-bridge-ui/src/generateOpenGraphImages.tsx b/packages/arb-token-bridge-ui/src/generateOpenGraphImages.tsx
index 6df1761284..01ff07ff39 100644
--- a/packages/arb-token-bridge-ui/src/generateOpenGraphImages.tsx
+++ b/packages/arb-token-bridge-ui/src/generateOpenGraphImages.tsx
@@ -2,7 +2,8 @@ import React from 'react'
import satori, { Font } from 'satori'
import sharp from 'sharp'
import fs from 'fs'
-import { ChainId, isNetwork } from './util/networks'
+import { isNetwork } from './util/networks'
+import { ChainId } from './types/ChainId'
import { getBridgeUiConfigForChain } from './util/bridgeUiConfig'
import { orbitMainnets, orbitTestnets } from './util/orbitChainsList'
diff --git a/packages/arb-token-bridge-ui/src/hooks/CCTP/useCCTPIsBlocked.ts b/packages/arb-token-bridge-ui/src/hooks/CCTP/useCCTPIsBlocked.ts
index d4c8c0bc98..c8ec3a1701 100644
--- a/packages/arb-token-bridge-ui/src/hooks/CCTP/useCCTPIsBlocked.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/CCTP/useCCTPIsBlocked.ts
@@ -1,5 +1,5 @@
import useSWRImmutable from 'swr/immutable'
-import { ChainId } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { getCctpUtils } from '@/token-bridge-sdk/cctp'
export function useCCTPIsBlocked() {
diff --git a/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useChainIdsForNetworkSelection.ts b/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useChainIdsForNetworkSelection.ts
index 6d139ed254..68b776da8f 100644
--- a/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useChainIdsForNetworkSelection.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useChainIdsForNetworkSelection.ts
@@ -1,8 +1,8 @@
import {
- ChainId,
getDestinationChainIds,
getSupportedChainIds
} from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { useIsTestnetMode } from '../useIsTestnetMode'
import { useNetworks } from '../useNetworks'
diff --git a/packages/arb-token-bridge-ui/src/hooks/__tests__/useArbQueryParams.test.ts b/packages/arb-token-bridge-ui/src/hooks/__tests__/useArbQueryParams.test.ts
index e31ac3dd95..924645d6de 100644
--- a/packages/arb-token-bridge-ui/src/hooks/__tests__/useArbQueryParams.test.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/__tests__/useArbQueryParams.test.ts
@@ -2,7 +2,8 @@
* @jest-environment jsdom
*/
import { registerCustomArbitrumNetwork } from '@arbitrum/sdk'
-import { ChainId, customChainLocalStorageKey } from '../../util/networks'
+import { customChainLocalStorageKey } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { AmountQueryParam, ChainParam } from '../useArbQueryParams'
import { createMockOrbitChain } from './helpers'
diff --git a/packages/arb-token-bridge-ui/src/hooks/__tests__/useNetworks.test.ts b/packages/arb-token-bridge-ui/src/hooks/__tests__/useNetworks.test.ts
index ec03fd1f9c..b7b2de2db3 100644
--- a/packages/arb-token-bridge-ui/src/hooks/__tests__/useNetworks.test.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/__tests__/useNetworks.test.ts
@@ -2,7 +2,8 @@
* @jest-environment jsdom
*/
import { registerCustomArbitrumNetwork } from '@arbitrum/sdk'
-import { ChainId, customChainLocalStorageKey } from '../../util/networks'
+import { customChainLocalStorageKey } from '../../util/networks'
+import { ChainId } from '../../types/ChainId'
import { sanitizeQueryParams } from '../useNetworks'
import { createMockOrbitChain } from './helpers'
diff --git a/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts b/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts
index c4b4451e12..4d67ec0638 100644
--- a/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts
@@ -1,27 +1,13 @@
import { Signer } from '@ethersproject/abstract-signer'
-import { TransactionReceipt } from '@ethersproject/abstract-provider'
-import { BigNumber, ContractReceipt, ethers } from 'ethers'
+import { BigNumber, ContractReceipt } from 'ethers'
import { TokenList } from '@uniswap/token-lists'
import {
EventArgs,
- ParentEthDepositTransaction,
- ParentEthDepositTransactionReceipt,
- ParentContractCallTransaction,
- ParentContractCallTransactionReceipt,
- ChildContractTransaction,
- ChildTransactionReceipt,
ChildToParentMessageStatus as OutgoingMessageState,
ChildToParentTransactionEvent
} from '@arbitrum/sdk'
-import { StandardArbERC20 } from '@arbitrum/sdk/dist/lib/abi/StandardArbERC20'
import { WithdrawalInitiatedEvent } from '@arbitrum/sdk/dist/lib/abi/L2ArbitrumGateway'
-import {
- NewTransaction,
- Transaction,
- ParentToChildMessageData
-} from './useTransactions'
-
export { OutgoingMessageState }
export enum TokenType {
@@ -39,21 +25,6 @@ export type TransactionLifecycle = Partial<{
onTxError: (error: any) => void
}>
-export type L1EthDepositTransactionLifecycle = TransactionLifecycle<
- ParentEthDepositTransaction,
- ParentEthDepositTransactionReceipt
->
-
-export type L1ContractCallTransactionLifecycle = TransactionLifecycle<
- ParentContractCallTransaction,
- ParentContractCallTransactionReceipt
->
-
-export type L2ContractCallTransactionLifecycle = TransactionLifecycle<
- ChildContractTransaction,
- ChildTransactionReceipt
->
-
export enum NodeBlockDeadlineStatusTypes {
NODE_NOT_CREATED,
EXECUTE_CALL_EXCEPTION
@@ -97,7 +68,7 @@ export interface BridgeToken {
address: string
l2Address?: string
logoURI?: string
- listIds: Set // no listID indicates added by user
+ listIds: Set // no listID indicates added by user
isL2Native?: boolean
}
@@ -106,27 +77,9 @@ export interface ERC20BridgeToken extends BridgeToken {
decimals: number
}
-export interface L2TokenData {
- balance: BigNumber
- contract: StandardArbERC20
-}
-
export interface ContractStorage {
[contractAddress: string]: T | undefined
}
-export interface BridgeBalance {
- balance: BigNumber | null
-
- arbChainBalance: BigNumber | null
-}
-
-// removing 'tokens' / 'balance' could result in one interface
-export interface AddressToSymbol {
- [tokenAddress: string]: string
-}
-export interface AddressToDecimals {
- [tokenAddress: string]: number
-}
export type GasEstimates = {
estimatedParentChainGas: BigNumber
@@ -147,8 +100,8 @@ export interface ArbTokenBridgeEth {
export interface ArbTokenBridgeToken {
add: (erc20L1orL2Address: string) => Promise
addL2NativeToken: (erc20L2Address: string) => void
- addTokensFromList: (tokenList: TokenList, listID: number) => void
- removeTokensFromList: (listID: number) => void
+ addTokensFromList: (tokenList: TokenList, listID: string) => void
+ removeTokensFromList: (listID: string) => void
updateTokenData: (l1Address: string) => Promise
triggerOutbox: (params: {
event: L2ToL1EventResultPlus
@@ -156,22 +109,8 @@ export interface ArbTokenBridgeToken {
}) => Promise
}
-export interface TransactionActions {
- addTransaction: (transaction: NewTransaction) => void
- updateTransaction: (
- txReceipt: TransactionReceipt,
- tx?: ethers.ContractTransaction,
- l1ToL2MsgData?: ParentToChildMessageData
- ) => void
-}
-
-export type ArbTokenBridgeTransactions = {
- transactions: Transaction[]
-} & Pick
-
export interface ArbTokenBridge {
bridgeTokens: ContractStorage | undefined
eth: ArbTokenBridgeEth
token: ArbTokenBridgeToken
- transactions: ArbTokenBridgeTransactions
}
diff --git a/packages/arb-token-bridge-ui/src/hooks/useAccountIsBlocked.ts b/packages/arb-token-bridge-ui/src/hooks/useAccountIsBlocked.ts
index 1ec288e21a..dd4bd75035 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useAccountIsBlocked.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useAccountIsBlocked.ts
@@ -66,10 +66,13 @@ export function useAccountIsBlocked() {
return null
}
- return [address.toLowerCase(), 'useAccountIsBlocked']
+ return [
+ address.toLocaleLowerCase() as Address,
+ 'useAccountIsBlocked'
+ ] as const
}, [address])
- const { data: isBlocked } = useSWRImmutable(
+ const { data: isBlocked } = useSWRImmutable(
queryKey,
// Extracts the first element of the query key as the fetcher param
([_address]) => fetcher(_address)
diff --git a/packages/arb-token-bridge-ui/src/hooks/useAccountMenu.ts b/packages/arb-token-bridge-ui/src/hooks/useAccountMenu.ts
index d94d0ac0bd..0c894fafe9 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useAccountMenu.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useAccountMenu.ts
@@ -11,9 +11,7 @@ import {
useEnsAvatar
} from 'wagmi'
import { useArbQueryParams } from './useArbQueryParams'
-import { trackEvent } from '../util/AnalyticsUtils'
import { shortenAddress } from '../util/CommonUtils'
-import { useAppContextActions } from '../components/App/AppContext'
import { onDisconnectHandler } from '../util/walletConnectUtils'
type UDInfo = { name: string | null }
@@ -53,7 +51,6 @@ export const useAccountMenu = () => {
})
const { chain } = useNetwork()
- const { openTransactionHistoryPanel } = useAppContextActions()
const [, setQueryParams] = useArbQueryParams()
const [udInfo, setUDInfo] = useState(udInfoDefaults)
@@ -101,17 +98,11 @@ export const useAccountMenu = () => {
resolveUdName()
}, [address, l1Provider])
- function openTransactionHistory() {
- openTransactionHistoryPanel()
- trackEvent('Open Transaction History Click', { pageElement: 'Header' })
- }
-
return {
address,
accountShort,
ensName,
ensAvatar,
- openTransactionHistory,
disconnect,
udInfo,
chain,
diff --git a/packages/arb-token-bridge-ui/src/hooks/useArbQueryParams.tsx b/packages/arb-token-bridge-ui/src/hooks/useArbQueryParams.tsx
index 0d07a46d3e..0d61bd7394 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useArbQueryParams.tsx
+++ b/packages/arb-token-bridge-ui/src/hooks/useArbQueryParams.tsx
@@ -32,7 +32,7 @@ import {
getChainQueryParamForChain,
isValidChainQueryParam
} from '../types/ChainQueryParam'
-import { ChainId } from '../util/networks'
+import { ChainId } from '../types/ChainId'
export enum AmountQueryParamEnum {
MAX = 'max'
diff --git a/packages/arb-token-bridge-ui/src/hooks/useArbTokenBridge.ts b/packages/arb-token-bridge-ui/src/hooks/useArbTokenBridge.ts
index 2d462063da..39e39f2b83 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useArbTokenBridge.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useArbTokenBridge.ts
@@ -12,7 +12,6 @@ import {
} from '@arbitrum/sdk'
import { L2ToL1TransactionEvent as ClassicL2ToL1TransactionEvent } from '@arbitrum/sdk/dist/lib/abi/ArbSys'
-import useTransactions from './useTransactions'
import {
ArbTokenBridge,
ContractStorage,
@@ -137,10 +136,7 @@ export const useArbTokenBridge = (
const l1NetworkID = useMemo(() => String(l1.network.id), [l1.network.id])
- const [transactions, { addTransaction, updateTransaction }] =
- useTransactions()
-
- const removeTokensFromList = (listID: number) => {
+ const removeTokensFromList = (listID: string) => {
setBridgeTokens(prevBridgeTokens => {
const newBridgeTokens = { ...prevBridgeTokens }
for (const address in bridgeTokens) {
@@ -157,7 +153,7 @@ export const useArbTokenBridge = (
})
}
- const addTokensFromList = async (arbTokenList: TokenList, listId: number) => {
+ const addTokensFromList = async (arbTokenList: TokenList, listId: string) => {
const l1ChainID = l1.network.id
const l2ChainID = l2.network.id
@@ -537,11 +533,6 @@ export const useArbTokenBridge = (
removeTokensFromList,
updateTokenData,
triggerOutbox: triggerOutboxToken
- },
- transactions: {
- transactions,
- updateTransaction,
- addTransaction
}
}
}
diff --git a/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts b/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts
index f174dc8fb3..be9b21769d 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts
@@ -15,6 +15,7 @@ import { fetchErc20Data } from '../util/TokenUtils'
import { fetchNativeCurrency } from './useNativeCurrency'
import { getProviderForChainId } from '@/token-bridge-sdk/utils'
import { captureSentryErrorWithExtraData } from '../util/SentryUtils'
+import { useTransactionHistoryAddressStore } from '../components/TransactionHistory/TransactionHistorySearchBar'
export type UseClaimWithdrawalResult = {
claim: () => Promise
@@ -28,8 +29,11 @@ export function useClaimWithdrawal(
app: { arbTokenBridge }
} = useAppState()
const { address } = useAccount()
+ const { sanitizedAddress } = useTransactionHistoryAddressStore()
const { data: signer } = useSigner({ chainId: tx.parentChainId })
- const { updatePendingTransaction } = useTransactionHistory(address)
+ const { updatePendingTransaction } = useTransactionHistory(
+ sanitizedAddress ?? address
+ )
const [isClaiming, setIsClaiming] = useState(false)
const claim = useCallback(async () => {
diff --git a/packages/arb-token-bridge-ui/src/hooks/useDebouncedValue.ts b/packages/arb-token-bridge-ui/src/hooks/useDebouncedValue.ts
deleted file mode 100644
index 6e70fe1ba7..0000000000
--- a/packages/arb-token-bridge-ui/src/hooks/useDebouncedValue.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useState, useEffect } from 'react'
-
-export function useDebouncedValue(value: T, delay: number) {
- const [debouncedValue, setDebouncedValue] = useState(value)
-
- useEffect(() => {
- const handler = setTimeout(() => {
- setDebouncedValue(value)
- }, delay)
-
- return () => {
- clearTimeout(handler)
- }
- }, [value, delay])
-
- return debouncedValue
-}
diff --git a/packages/arb-token-bridge-ui/src/hooks/useIsTestnetMode.ts b/packages/arb-token-bridge-ui/src/hooks/useIsTestnetMode.ts
index 3917b493f6..052f54629a 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useIsTestnetMode.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useIsTestnetMode.ts
@@ -1,6 +1,7 @@
import { useCallback } from 'react'
import { useNetworks } from './useNetworks'
-import { ChainId, isNetwork } from '../util/networks'
+import { isNetwork } from '../util/networks'
+import { ChainId } from '../types/ChainId'
export const useIsTestnetMode = () => {
const [networks, setNetworks] = useNetworks()
diff --git a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts
index b141f2d144..58f97cd4a8 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useNetworks.ts
@@ -4,7 +4,8 @@ import { useCallback, useMemo } from 'react'
import { mainnet, arbitrum } from '@wagmi/core/chains'
import { useArbQueryParams } from './useArbQueryParams'
-import { ChainId, getCustomChainsFromLocalStorage } from '../util/networks'
+import { getCustomChainsFromLocalStorage } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import {
sepolia,
holesky,
diff --git a/packages/arb-token-bridge-ui/src/hooks/useRedeemTeleporter.ts b/packages/arb-token-bridge-ui/src/hooks/useRedeemTeleporter.ts
index 4845c0e67f..20edd6715d 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useRedeemTeleporter.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useRedeemTeleporter.ts
@@ -26,7 +26,7 @@ import { isUserRejectedError } from '../util/isUserRejectedError'
import { errorToast } from '../components/common/atoms/Toast'
import { useTransactionHistory } from './useTransactionHistory'
import { Address } from '../util/AddressUtils'
-import { isTeleportTx, L2ToL3MessageData } from './useTransactions'
+import { isTeleportTx, L2ToL3MessageData } from '../types/Transactions'
import { UseRedeemRetryableResult } from './useRedeemRetryable'
import { getUpdatedTeleportTransfer } from '../components/TransactionHistory/helpers'
diff --git a/packages/arb-token-bridge-ui/src/hooks/useTransactionHistory.ts b/packages/arb-token-bridge-ui/src/hooks/useTransactionHistory.ts
index 940eb0181b..c2f2779c19 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useTransactionHistory.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useTransactionHistory.ts
@@ -4,12 +4,8 @@ import useSWRInfinite from 'swr/infinite'
import { useCallback, useEffect, useMemo, useState } from 'react'
import dayjs from 'dayjs'
-import {
- ChainId,
- getChains,
- getChildChainIds,
- isNetwork
-} from '../util/networks'
+import { getChains, getChildChainIds, isNetwork } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import { fetchWithdrawals } from '../util/withdrawals/fetchWithdrawals'
import { fetchDeposits } from '../util/deposits/fetchDeposits'
import {
@@ -17,7 +13,7 @@ import {
L2ToL1EventResultPlus,
WithdrawalInitiated
} from './arbTokenBridge.types'
-import { isTeleportTx, Transaction } from './useTransactions'
+import { isTeleportTx, Transaction } from '../types/Transactions'
import { MergedTransaction } from '../state/app/state'
import {
isCustomDestinationAddressTx,
@@ -161,13 +157,7 @@ async function transformTransaction(tx: Transfer): Promise {
}
if (isDeposit(tx)) {
- return transformDeposit(
- await updateAdditionalDepositData({
- depositTx: tx,
- parentProvider,
- childProvider
- })
- )
+ return transformDeposit(await updateAdditionalDepositData(tx))
}
let withdrawal: L2ToL1EventResultPlus | undefined
@@ -838,7 +828,7 @@ export const useTransactionHistory = (
if (isLoadingTxsWithoutStatus || error) {
return {
- transactions: [],
+ transactions: newTransactionsData || [],
loading: isLoadingTxsWithoutStatus,
error,
failedChainPairs: [],
diff --git a/packages/arb-token-bridge-ui/src/hooks/useTransactions.ts b/packages/arb-token-bridge-ui/src/hooks/useTransactions.ts
deleted file mode 100644
index ffe0ee4886..0000000000
--- a/packages/arb-token-bridge-ui/src/hooks/useTransactions.ts
+++ /dev/null
@@ -1,442 +0,0 @@
-import { useReducer, useEffect, useMemo } from 'react'
-import { TransactionReceipt } from '@ethersproject/abstract-provider'
-import { AssetType, TransactionActions } from './arbTokenBridge.types'
-import { BigNumber, ethers } from 'ethers'
-import { ParentToChildMessageStatus } from '@arbitrum/sdk'
-import {
- MergedTransaction,
- TeleporterMergedTransaction
-} from '../state/app/state'
-
-type Action =
- | { type: 'ADD_TRANSACTION'; transaction: Transaction }
- | { type: 'SET_SUCCESS'; txID: string }
- | { type: 'SET_FAILURE'; txID: string }
- | { type: 'SET_INITIAL_TRANSACTIONS'; transactions: Transaction[] }
- | { type: 'CLEAR_PENDING' }
- | { type: 'CONFIRM_TRANSACTION'; txID: string }
- | { type: 'REMOVE_TRANSACTION'; txID: string }
- | { type: 'SET_BLOCK_NUMBER'; txID: string; blockNumber?: number }
- | { type: 'SET_RESOLVED_TIMESTAMP'; txID: string; timestamp?: string }
- | { type: 'ADD_TRANSACTIONS'; transactions: Transaction[] }
- | {
- type: 'UPDATE_PARENT_TO_CHILD_MSG_DATA'
- txID: string
- parentToChildMsgData: ParentToChildMessageData
- }
- | { type: 'SET_TRANSACTIONS'; transactions: Transaction[] }
-
-export type TxnStatus = 'pending' | 'success' | 'failure' | 'confirmed'
-
-/** @interface
- * Transaction
- * @alias Transaction
- * @description Bridge transaction data with up to date status.
- */
-export type TxnType =
- | 'deposit'
- | 'deposit-l1'
- | 'deposit-l2' // unused; keeping for cache backwrads compatability
- | 'withdraw'
- | 'outbox'
- | 'approve'
- | 'deposit-l2-auto-redeem' // unused; keeping for cache backwrads compatability
- | 'deposit-l2-ticket-created' // unused; keeping for cache backwrads compatability
- | 'approve-l2'
-
-const deprecatedTxTypes: Set = new Set([
- 'deposit-l2-auto-redeem',
- 'deposit-l2-ticket-created',
- 'deposit-l2'
-])
-
-export const txnTypeToLayer = (txnType: TxnType): 1 | 2 => {
- switch (txnType) {
- case 'deposit':
- case 'deposit-l1':
- case 'outbox':
- case 'approve':
- return 1
- case 'deposit-l2':
- case 'withdraw':
- case 'deposit-l2-auto-redeem':
- case 'deposit-l2-ticket-created':
- case 'approve-l2':
- return 2
- }
-}
-
-export interface ParentToChildMessageData {
- status: ParentToChildMessageStatus
- retryableCreationTxID: string
- childTxId?: string
- fetchingUpdate: boolean
-}
-
-export interface L2ToL3MessageData {
- status: ParentToChildMessageStatus
- retryableCreationTxID?: string
- l2ForwarderRetryableTxID?: string
- l3TxID?: string
- l2ChainId: number
-}
-
-export type ChildToParentMessageData = {
- uniqueId: BigNumber
-}
-
-type TransactionBase = {
- type: TxnType
- status?: TxnStatus
- value: string | null
- value2?: string
- txID?: string
- assetName: string
- assetType: AssetType
- tokenAddress?: string
- sender: string
- destination?: string
- blockNumber?: number
- l1NetworkID: string
- l2NetworkID?: string
- timestampResolved?: string // time when its status was changed
- timestampCreated?: string //time when this transaction is first added to the list
- parentToChildMsgData?: ParentToChildMessageData
- childToParentMsgData?: ChildToParentMessageData
- isClassic?: boolean
-}
-
-export interface Transaction extends TransactionBase {
- txID: string
- direction: 'deposit' | 'withdrawal'
- source: 'subgraph' | 'event_logs' | 'local_storage_cache'
- parentChainId: number
- childChainId: number
- nonce?: number
-}
-
-export interface TeleporterTransaction extends Transaction {
- l2ToL3MsgData: L2ToL3MessageData
-}
-
-export interface NewTransaction extends TransactionBase {
- status: 'pending'
-}
-
-export interface FailedTransaction extends TransactionBase {
- status: 'failure'
-}
-
-// TODO: enforce this type restriction
-export interface DepositTransaction extends Transaction {
- parentToChildMsgData: ParentToChildMessageData
- type: 'deposit' | 'deposit-l1'
-}
-
-export function isTeleportTx(
- tx: Transaction | MergedTransaction
-): tx is TeleporterTransaction | TeleporterMergedTransaction {
- return (tx as TeleporterTransaction).l2ToL3MsgData !== undefined
-}
-
-function updateStatus(state: Transaction[], status: TxnStatus, txID: string) {
- const newState = [...state]
- const index = newState.findIndex(txn => txn.txID === txID)
- const transaction = newState[index]
-
- if (!transaction) {
- console.warn('transaction not found', txID)
- return state
- }
-
- newState[index] = {
- ...transaction,
- status
- }
- return newState
-}
-
-function updateBlockNumber(
- state: Transaction[],
- txID: string,
- blockNumber?: number
-) {
- const newState = [...state]
- const index = newState.findIndex(txn => txn.txID === txID)
- const transaction = newState[index]
-
- if (!transaction) {
- console.warn('transaction not found', txID)
- return state
- }
-
- newState[index] = {
- ...transaction,
- blockNumber
- }
- return newState
-}
-
-function updateTxnParentToChildMsg(
- state: Transaction[],
- txID: string,
- parentToChildMsgData: ParentToChildMessageData
-) {
- const newState = [...state]
- const index = newState.findIndex(txn => txn.txID === txID)
- const transaction = newState[index]
-
- if (!transaction) {
- console.warn('transaction not found', txID)
- return state
- }
-
- if (!(transaction.type === 'deposit' || transaction.type === 'deposit-l1')) {
- throw new Error(
- "Attempting to add a parentToChildMsg to a tx that isn't a deposit:" +
- txID
- )
- }
-
- const previousParentToChildMsgData = transaction.parentToChildMsgData
- if (!previousParentToChildMsgData) {
- newState[index] = {
- ...transaction,
- parentToChildMsgData: {
- status: parentToChildMsgData.status,
- retryableCreationTxID: parentToChildMsgData.retryableCreationTxID,
- fetchingUpdate: false
- }
- }
- return newState
- }
-
- newState[index] = {
- ...transaction,
- parentToChildMsgData: {
- ...previousParentToChildMsgData,
- ...parentToChildMsgData
- }
- }
- return newState
-}
-
-function updateResolvedTimestamp(
- state: Transaction[],
- txID: string,
- timestamp?: string
-) {
- const newState = [...state]
- const index = newState.findIndex(txn => txn.txID === txID)
- const transaction = newState[index]
-
- if (!transaction) {
- console.warn('transaction not found', txID)
- return state
- }
-
- newState[index] = {
- ...transaction,
- timestampResolved: timestamp
- }
-
- return newState
-}
-function reducer(state: Transaction[], action: Action) {
- switch (action.type) {
- case 'SET_INITIAL_TRANSACTIONS': {
- // Add l1 to L2 stuff with pending status
- return [...action.transactions]
- }
- case 'ADD_TRANSACTIONS': {
- // sanity / safety check: ensure no duplicates:
- const currentTxIds = new Set(state.map(tx => tx.txID))
- const txsToAdd = action.transactions.filter(tx => {
- if (!currentTxIds.has(tx.txID)) {
- return true
- } else {
- console.warn(
- `Warning: trying to add ${tx.txID} which is already included`
- )
- return false
- }
- })
- return state.concat(txsToAdd)
- }
- case 'ADD_TRANSACTION': {
- return state.concat(action.transaction)
- }
- case 'REMOVE_TRANSACTION': {
- return state.filter(txn => txn.txID !== action.txID)
- }
- case 'SET_SUCCESS': {
- return updateStatus(state, 'success', action.txID)
- }
- case 'SET_FAILURE': {
- return updateStatus(state, 'failure', action.txID)
- }
- case 'CLEAR_PENDING': {
- return state.filter(txn => txn.status !== 'pending')
- }
- case 'CONFIRM_TRANSACTION': {
- return updateStatus(state, 'confirmed', action.txID)
- }
- case 'SET_BLOCK_NUMBER': {
- return updateBlockNumber(state, action.txID, action.blockNumber)
- }
- case 'SET_RESOLVED_TIMESTAMP': {
- return updateResolvedTimestamp(state, action.txID, action.timestamp)
- }
- case 'UPDATE_PARENT_TO_CHILD_MSG_DATA': {
- return updateTxnParentToChildMsg(
- state,
- action.txID,
- action.parentToChildMsgData
- )
- }
- case 'SET_TRANSACTIONS': {
- return action.transactions
- }
- default:
- return state
- }
-}
-
-const localStorageReducer = (state: Transaction[], action: Action) => {
- const newState = reducer(state, action)
- // don't cache fetchingUpdate state
- const stateForCache = newState.map(tx => {
- if (tx.parentToChildMsgData && tx.parentToChildMsgData.fetchingUpdate) {
- return {
- ...tx,
- parentToChildMsgData: {
- ...tx.parentToChildMsgData,
- fetchingUpdate: false
- }
- }
- }
- return tx
- })
- window.localStorage.setItem('arbTransactions', JSON.stringify(stateForCache))
- return newState
-}
-
-const useTransactions = (): [Transaction[], TransactionActions] => {
- const [state, dispatch] = useReducer(localStorageReducer, [])
-
- useEffect(() => {
- const cachedTransactions = window.localStorage.getItem('arbTransactions')
- dispatch({
- type: 'SET_INITIAL_TRANSACTIONS',
- transactions: cachedTransactions ? JSON.parse(cachedTransactions) : []
- })
- }, [])
-
- const addTransaction = (transaction: NewTransaction) => {
- if (!transaction.txID) {
- console.warn(' Cannot add transaction: TxID not included (???)')
- return
- }
- const tx = {
- ...transaction,
- timestampCreated: new Date().toISOString()
- } as Transaction
- return dispatch({
- type: 'ADD_TRANSACTION',
- transaction: tx
- })
- }
-
- const updateTxnParentToChildMsgData = async (
- txID: string,
- parentToChildMsgData: ParentToChildMessageData
- ) => {
- dispatch({
- type: 'UPDATE_PARENT_TO_CHILD_MSG_DATA',
- txID: txID,
- parentToChildMsgData
- })
- }
-
- const setTransactionSuccess = (txID: string) => {
- return dispatch({
- type: 'SET_SUCCESS',
- txID: txID
- })
- }
- const setTransactionBlock = (txID: string, blockNumber?: number) => {
- return dispatch({
- type: 'SET_BLOCK_NUMBER',
- txID,
- blockNumber
- })
- }
- const setResolvedTimestamp = (txID: string, timestamp?: string) => {
- return dispatch({
- type: 'SET_RESOLVED_TIMESTAMP',
- txID,
- timestamp
- })
- }
- const setTransactionFailure = (txID?: string) => {
- if (!txID) {
- console.warn(' Cannot set transaction failure: TxID not included (???)')
- return
- }
- return dispatch({
- type: 'SET_FAILURE',
- txID: txID
- })
- }
-
- const updateTransaction = (
- txReceipt: TransactionReceipt,
- tx?: ethers.ContractTransaction,
- parentToChildMsgData?: ParentToChildMessageData
- ) => {
- if (!txReceipt.transactionHash) {
- return console.warn(
- '*** TransactionHash not included in transaction receipt (???) *** '
- )
- }
- switch (txReceipt.status) {
- case 0: {
- setTransactionFailure(txReceipt.transactionHash)
- break
- }
- case 1: {
- setTransactionSuccess(txReceipt.transactionHash)
- break
- }
- default:
- console.warn('*** Status not included in transaction receipt *** ')
- break
- }
- if (tx?.blockNumber) {
- setTransactionBlock(txReceipt.transactionHash, tx.blockNumber)
- }
- if (tx) {
- setResolvedTimestamp(txReceipt.transactionHash, new Date().toISOString())
- }
- if (parentToChildMsgData) {
- updateTxnParentToChildMsgData(
- txReceipt.transactionHash,
- parentToChildMsgData
- )
- }
- }
-
- const transactions = useMemo(() => {
- return state.filter(tx => !deprecatedTxTypes.has(tx.type))
- }, [state])
-
- return [
- transactions,
- {
- addTransaction,
- updateTransaction
- }
- ]
-}
-
-export default useTransactions
diff --git a/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts b/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts
index f8671e23e2..ceb92a04c5 100644
--- a/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts
+++ b/packages/arb-token-bridge-ui/src/hooks/useTransferDuration.ts
@@ -3,12 +3,7 @@ import { isValidTeleportChainPair } from '@/token-bridge-sdk/teleport'
import { MergedTransaction } from '../state/app/state'
import { useRemainingTimeCctp } from '../state/cctpState'
-import {
- getBlockNumberReferenceChainIdByChainId,
- getConfirmPeriodBlocks,
- getL1BlockTime,
- isNetwork
-} from '../util/networks'
+import { isNetwork } from '../util/networks'
import { getConfirmationTime } from '../util/WithdrawalUtils'
const DEPOSIT_TIME_MINUTES = {
@@ -31,13 +26,6 @@ const DEPOSIT_TIME_MINUTES_ORBIT = {
testnet: 1
}
-/**
- * Buffer for after a node is confirmable but isn't yet confirmed.
- * A rollup block (RBlock) typically gets asserted every 30-60 minutes.
- */
-const CONFIRMATION_BUFFER_MINUTES = 60
-const SECONDS_IN_MIN = 60
-
type UseTransferDurationResult = {
approximateDurationInMinutes: number
estimatedMinutesLeft: number | null
@@ -122,22 +110,10 @@ export function getWithdrawalConfirmationDate({
// For new txs createdAt won't be defined yet, we default to the current time in that case
const createdAtDate = createdAt ? dayjs(createdAt) : dayjs()
- const { confirmationTimeInSeconds, fastWithdrawalActive } =
- getConfirmationTime(withdrawalFromChainId)
- if (fastWithdrawalActive && confirmationTimeInSeconds) {
- return createdAtDate.add(confirmationTimeInSeconds, 'second')
- }
-
- const blockNumberReferenceChainId = getBlockNumberReferenceChainIdByChainId({
- chainId: withdrawalFromChainId
- })
- // the block time is always base chain's block time regardless of withdrawing from L3 to L2 or from L2 to L1
- // and similarly, the confirm period blocks is always the number of blocks on the base chain
- const confirmationSeconds =
- getL1BlockTime(blockNumberReferenceChainId) *
- getConfirmPeriodBlocks(withdrawalFromChainId) +
- CONFIRMATION_BUFFER_MINUTES * SECONDS_IN_MIN
- return createdAtDate.add(confirmationSeconds, 'second')
+ const { confirmationTimeInSeconds } = getConfirmationTime(
+ withdrawalFromChainId
+ )
+ return createdAtDate.add(confirmationTimeInSeconds, 'second')
}
function getWithdrawalDuration(tx: MergedTransaction) {
diff --git a/packages/arb-token-bridge-ui/src/pages/api/cctp/[type].ts b/packages/arb-token-bridge-ui/src/pages/api/cctp/[type].ts
index ff4e3d2021..6925c98b5d 100644
--- a/packages/arb-token-bridge-ui/src/pages/api/cctp/[type].ts
+++ b/packages/arb-token-bridge-ui/src/pages/api/cctp/[type].ts
@@ -1,7 +1,7 @@
import { gql } from '@apollo/client'
import { NextApiRequest, NextApiResponse } from 'next'
-import { ChainId } from '../../../util/networks'
+import { ChainId } from '../../../types/ChainId'
import { Address } from '../../../util/AddressUtils'
import {
diff --git a/packages/arb-token-bridge-ui/src/pages/api/chains/[chainId]/block-number.ts b/packages/arb-token-bridge-ui/src/pages/api/chains/[chainId]/block-number.ts
index 02dd20f839..f23b2fd4c3 100644
--- a/packages/arb-token-bridge-ui/src/pages/api/chains/[chainId]/block-number.ts
+++ b/packages/arb-token-bridge-ui/src/pages/api/chains/[chainId]/block-number.ts
@@ -1,7 +1,7 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { gql } from '@apollo/client'
-import { ChainId } from '../../../../util/networks'
+import { ChainId } from '../../../../types/ChainId'
import {
getL1SubgraphClient,
getL2SubgraphClient,
diff --git a/packages/arb-token-bridge-ui/src/state/app/state.ts b/packages/arb-token-bridge-ui/src/state/app/state.ts
index e2b723a676..d962b01372 100644
--- a/packages/arb-token-bridge-ui/src/state/app/state.ts
+++ b/packages/arb-token-bridge-ui/src/state/app/state.ts
@@ -10,7 +10,7 @@ import {
ChildToParentMessageData,
L2ToL3MessageData,
TxnType
-} from '../../hooks/useTransactions'
+} from '../../types/Transactions'
import { ConnectionState } from '../../util'
import { CCTPSupportedChainId } from '../cctpState'
import { Address } from '../../util/AddressUtils'
diff --git a/packages/arb-token-bridge-ui/src/state/app/utils.ts b/packages/arb-token-bridge-ui/src/state/app/utils.ts
index b2a14492df..a5012cb2e0 100644
--- a/packages/arb-token-bridge-ui/src/state/app/utils.ts
+++ b/packages/arb-token-bridge-ui/src/state/app/utils.ts
@@ -17,7 +17,7 @@ import {
isTeleportTx,
TeleporterTransaction,
Transaction
-} from '../../hooks/useTransactions'
+} from '../../types/Transactions'
import { getUniqueIdOrHashFromEvent } from '../../hooks/useArbTokenBridge'
import {
firstRetryableLegRequiresRedeem,
@@ -289,14 +289,6 @@ export function isCustomDestinationAddressTx(
return tx.sender.toLowerCase() !== tx.destination.toLowerCase()
}
-export const isWithdrawalReadyToClaim = (tx: MergedTransaction) => {
- return (
- isWithdrawal(tx) &&
- isPending(tx) &&
- tx.status === outgoingStateToString[OutgoingMessageState.CONFIRMED]
- )
-}
-
export const isDepositReadyToRedeem = (tx: MergedTransaction) => {
if (isTeleportTx(tx)) {
return (
diff --git a/packages/arb-token-bridge-ui/src/state/cctpState.ts b/packages/arb-token-bridge-ui/src/state/cctpState.ts
index 7f0eb43f84..523aa80b73 100644
--- a/packages/arb-token-bridge-ui/src/state/cctpState.ts
+++ b/packages/arb-token-bridge-ui/src/state/cctpState.ts
@@ -5,12 +5,8 @@ import useSWRImmutable from 'swr/immutable'
import { useInterval } from 'react-use'
import { getCctpUtils } from '@/token-bridge-sdk/cctp'
-import {
- ChainId,
- getL1BlockTime,
- getNetworkName,
- isNetwork
-} from '../util/networks'
+import { getL1BlockTime, getNetworkName, isNetwork } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import { fetchCCTPDeposits, fetchCCTPWithdrawals } from '../util/cctp/fetchCCTP'
import { DepositStatus, MergedTransaction, WithdrawalStatus } from './app/state'
import { normalizeTimestamp } from './app/utils'
diff --git a/packages/arb-token-bridge-ui/src/state/index.ts b/packages/arb-token-bridge-ui/src/state/index.ts
index 35d1a41c11..29116cf134 100644
--- a/packages/arb-token-bridge-ui/src/state/index.ts
+++ b/packages/arb-token-bridge-ui/src/state/index.ts
@@ -1,9 +1,5 @@
import { IContext } from 'overmind'
-import {
- createActionsHook,
- createStateHook,
- createEffectsHook
-} from 'overmind-react'
+import { createActionsHook, createStateHook } from 'overmind-react'
import { namespaced } from 'overmind/config'
import * as app from './app'
@@ -20,4 +16,3 @@ export type Context = IContext<{
export const useAppState = createStateHook()
export const useActions = createActionsHook()
-export const useEffects = createEffectsHook()
diff --git a/packages/arb-token-bridge-ui/src/token-bridge-sdk/cctp.ts b/packages/arb-token-bridge-ui/src/token-bridge-sdk/cctp.ts
index eb446b7679..e816a8394b 100644
--- a/packages/arb-token-bridge-ui/src/token-bridge-sdk/cctp.ts
+++ b/packages/arb-token-bridge-ui/src/token-bridge-sdk/cctp.ts
@@ -5,7 +5,7 @@ import { ChainDomain } from '../pages/api/cctp/[type]'
import { prepareWriteContract, writeContract } from '@wagmi/core'
import { MessageTransmitterAbi } from '../util/cctp/MessageTransmitterAbi'
import { CCTPSupportedChainId } from '../state/cctpState'
-import { ChainId } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import { CommonAddress } from '../util/CommonAddressUtils'
import { Address } from '../util/AddressUtils'
diff --git a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts
index 54e7483bbf..b8bc6ae6dc 100644
--- a/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts
+++ b/packages/arb-token-bridge-ui/src/token-bridge-sdk/utils.ts
@@ -1,7 +1,8 @@
import { BigNumber, Signer } from 'ethers'
import { Provider, StaticJsonRpcProvider } from '@ethersproject/providers'
-import { ChainId, isNetwork, rpcURLs } from '../util/networks'
+import { isNetwork, rpcURLs } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import { BridgeTransferStarterPropsWithChainIds } from './BridgeTransferStarter'
import { isValidTeleportChainPair } from './teleport'
import {
diff --git a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts
index cb41de6fc8..15e2c0614c 100644
--- a/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts
+++ b/packages/arb-token-bridge-ui/src/types/ChainQueryParam.ts
@@ -1,10 +1,10 @@
import { Chain } from 'wagmi'
import * as chains from 'wagmi/chains'
import {
- ChainId,
getCustomChainFromLocalStorageById,
getSupportedChainIds
} from '../util/networks'
+import { ChainId } from '../types/ChainId'
import * as customChains from '../util/wagmi/wagmiAdditionalNetworks'
import { getOrbitChains, orbitChains } from '../util/orbitChainsList'
import { chainToWagmiChain } from '../util/wagmi/wagmiAdditionalNetworks'
diff --git a/packages/arb-token-bridge-ui/src/types/Transactions.ts b/packages/arb-token-bridge-ui/src/types/Transactions.ts
new file mode 100644
index 0000000000..8fa341fa26
--- /dev/null
+++ b/packages/arb-token-bridge-ui/src/types/Transactions.ts
@@ -0,0 +1,85 @@
+import { BigNumber } from 'ethers'
+import { ParentToChildMessageStatus } from '@arbitrum/sdk'
+
+import { AssetType } from '../hooks/arbTokenBridge.types'
+import {
+ MergedTransaction,
+ TeleporterMergedTransaction
+} from '../state/app/state'
+
+export type TxnStatus = 'pending' | 'success' | 'failure' | 'confirmed'
+
+/** @interface
+ * Transaction
+ * @alias Transaction
+ * @description Bridge transaction data with up to date status.
+ */
+export type TxnType =
+ | 'deposit'
+ | 'deposit-l1'
+ | 'deposit-l2' // unused; keeping for cache backwrads compatability
+ | 'withdraw'
+ | 'outbox'
+ | 'approve'
+ | 'deposit-l2-auto-redeem' // unused; keeping for cache backwrads compatability
+ | 'deposit-l2-ticket-created' // unused; keeping for cache backwrads compatability
+ | 'approve-l2'
+
+export interface ParentToChildMessageData {
+ status: ParentToChildMessageStatus
+ retryableCreationTxID: string
+ childTxId?: string
+ fetchingUpdate: boolean
+}
+
+export interface L2ToL3MessageData {
+ status: ParentToChildMessageStatus
+ retryableCreationTxID?: string
+ l2ForwarderRetryableTxID?: string
+ l3TxID?: string
+ l2ChainId: number
+}
+
+export type ChildToParentMessageData = {
+ uniqueId: BigNumber
+}
+
+type TransactionBase = {
+ type: TxnType
+ status?: TxnStatus
+ value: string | null
+ value2?: string
+ txID?: string
+ assetName: string
+ assetType: AssetType
+ tokenAddress?: string
+ sender: string
+ destination?: string
+ blockNumber?: number
+ l1NetworkID: string
+ l2NetworkID?: string
+ timestampResolved?: string // time when its status was changed
+ timestampCreated?: string //time when this transaction is first added to the list
+ parentToChildMsgData?: ParentToChildMessageData
+ childToParentMsgData?: ChildToParentMessageData
+ isClassic?: boolean
+}
+
+export interface Transaction extends TransactionBase {
+ txID: string
+ direction: 'deposit' | 'withdrawal'
+ source: 'subgraph' | 'event_logs' | 'local_storage_cache'
+ parentChainId: number
+ childChainId: number
+ nonce?: number
+}
+
+export interface TeleporterTransaction extends Transaction {
+ l2ToL3MsgData: L2ToL3MessageData
+}
+
+export function isTeleportTx(
+ tx: Transaction | MergedTransaction
+): tx is TeleporterTransaction | TeleporterMergedTransaction {
+ return (tx as TeleporterTransaction).l2ToL3MsgData !== undefined
+}
diff --git a/packages/arb-token-bridge-ui/src/util/AddressUtils.ts b/packages/arb-token-bridge-ui/src/util/AddressUtils.ts
index 4f33e3da77..9e15ef0750 100644
--- a/packages/arb-token-bridge-ui/src/util/AddressUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/AddressUtils.ts
@@ -1,3 +1,5 @@
+import { Provider } from '@ethersproject/providers'
+
import { getAPIBaseUrl } from '.'
import { getProviderForChainId } from '../token-bridge-sdk/utils'
@@ -29,3 +31,14 @@ export async function addressIsDenylisted(address: string) {
return false
}
}
+
+export function getNonce(
+ address: string | undefined,
+ { provider }: { provider: Provider }
+): Promise {
+ if (typeof address === 'undefined') {
+ return 0 as unknown as Promise
+ }
+
+ return provider.getTransactionCount(address)
+}
diff --git a/packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts b/packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts
new file mode 100644
index 0000000000..c46210ce24
--- /dev/null
+++ b/packages/arb-token-bridge-ui/src/util/ExponentialBackoffUtils.ts
@@ -0,0 +1,14 @@
+import { backOff as _backOff, BackoffOptions } from 'exponential-backoff'
+
+const backoffOptions: BackoffOptions = {
+ startingDelay: 1_000,
+ timeMultiple: 1.5
+}
+
+export function backOff(request: () => Promise): Promise {
+ return _backOff(request, backoffOptions)
+}
+
+export function wait(ms: number) {
+ return new Promise(resolve => setTimeout(resolve, ms))
+}
diff --git a/packages/arb-token-bridge-ui/src/util/L2ApprovalUtils.ts b/packages/arb-token-bridge-ui/src/util/L2ApprovalUtils.ts
index b5bfe7d038..55001b5acb 100644
--- a/packages/arb-token-bridge-ui/src/util/L2ApprovalUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/L2ApprovalUtils.ts
@@ -1,4 +1,4 @@
-import { ChainId } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import { xErc20RequiresApprovalOnChildChain } from './xErc20Utils'
export type RequireL2ApproveToken = {
diff --git a/packages/arb-token-bridge-ui/src/util/L2NativeUtils.ts b/packages/arb-token-bridge-ui/src/util/L2NativeUtils.ts
index e223f7b9ed..a6f0cb8652 100644
--- a/packages/arb-token-bridge-ui/src/util/L2NativeUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/L2NativeUtils.ts
@@ -1,4 +1,4 @@
-import { ChainId } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import { CommonAddress } from './CommonAddressUtils'
export type L2NativeToken = {
diff --git a/packages/arb-token-bridge-ui/src/util/RetryableUtils.ts b/packages/arb-token-bridge-ui/src/util/RetryableUtils.ts
index f65d704ccb..ad7f89ba80 100644
--- a/packages/arb-token-bridge-ui/src/util/RetryableUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/RetryableUtils.ts
@@ -12,7 +12,7 @@ import {
TeleporterMergedTransaction
} from '../state/app/state'
import { normalizeTimestamp } from '../state/app/utils'
-import { isTeleportTx } from '../hooks/useTransactions'
+import { isTeleportTx } from '../types/Transactions'
type GetRetryableTicketParams = {
parentChainTxHash: string
diff --git a/packages/arb-token-bridge-ui/src/util/SubgraphUtils.ts b/packages/arb-token-bridge-ui/src/util/SubgraphUtils.ts
index 53d3d6c5f3..dcdd31f896 100644
--- a/packages/arb-token-bridge-ui/src/util/SubgraphUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/SubgraphUtils.ts
@@ -1,4 +1,4 @@
-import { ChainId } from './networks'
+import { ChainId } from '../types/ChainId'
import { getAPIBaseUrl } from '.'
export function hasL1Subgraph(l2ChainId: number) {
diff --git a/packages/arb-token-bridge-ui/src/util/TokenListUtils.ts b/packages/arb-token-bridge-ui/src/util/TokenListUtils.ts
index 1622484a9d..09fe0ccd56 100644
--- a/packages/arb-token-bridge-ui/src/util/TokenListUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/TokenListUtils.ts
@@ -8,12 +8,15 @@ import CMCLogo from '@/images/lists/cmc.png'
import CoinGeckoLogo from '@/images/lists/coinGecko.svg'
import ArbitrumLogo from '@/images/lists/ArbitrumLogo.png'
import { ArbTokenBridge } from '../hooks/arbTokenBridge.types'
-import { ChainId } from './networks'
+import { ChainId } from '../types/ChainId'
+import orbitChainsData from './orbitChainsData.json'
-export const SPECIAL_ARBITRUM_TOKEN_TOKEN_LIST_ID = 0
+export const SPECIAL_ARBITRUM_TOKEN_TOKEN_LIST_ID =
+ 'SPECIAL_ARBITRUM_TOKEN_TOKEN_LIST_ID'
export interface BridgeTokenList {
- id: number
+ // string is required here to avoid duplicates when mapping orbit chains to tokenlists
+ id: string
originChainID: number
url: string
name: string
@@ -34,7 +37,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
isArbitrumTokenTokenList: true
},
{
- id: 1,
+ id: '1',
originChainID: ChainId.ArbitrumOne,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/arbed_arb_whitelist_era.json',
name: 'Arbitrum Whitelist Era',
@@ -42,7 +45,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
logoURI: ArbitrumLogo
},
{
- id: 2,
+ id: '2',
originChainID: ChainId.ArbitrumOne,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/arbed_uniswap_labs_default.json',
name: 'Arbed Uniswap List',
@@ -50,7 +53,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
logoURI: UniswapLogo
},
{
- id: 4,
+ id: '4',
originChainID: ChainId.ArbitrumOne,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/arbed_coingecko.json',
name: 'Arbed CoinGecko List',
@@ -58,7 +61,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
logoURI: CoinGeckoLogo
},
{
- id: 5,
+ id: '5',
originChainID: ChainId.ArbitrumOne,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/arbed_coinmarketcap.json',
name: 'Arbed CMC List',
@@ -66,7 +69,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
logoURI: CMCLogo
},
{
- id: 6,
+ id: '6',
originChainID: ChainId.ArbitrumNova,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/42170_arbed_uniswap_labs_default.json',
name: 'Arbed Uniswap List',
@@ -78,7 +81,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
// TODO: remove list for chain ID 412346 after fix:
// https://github.com/OffchainLabs/arb-token-bridge/issues/564
{
- id: 9,
+ id: '9',
// Local node
originChainID: ChainId.ArbitrumLocal,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/421613_arbed_coinmarketcap.json',
@@ -87,7 +90,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
logoURI: CMCLogo
},
{
- id: 10,
+ id: '10',
originChainID: ChainId.ArbitrumSepolia,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/421614_arbed_uniswap_labs.json',
name: 'Arbed Uniswap List',
@@ -96,7 +99,7 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
},
// CoinGecko
{
- id: 11,
+ id: '11',
originChainID: ChainId.ArbitrumNova,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/42170_arbed_coingecko.json',
name: 'Arbed CoinGecko List',
@@ -104,25 +107,15 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
logoURI: CoinGeckoLogo
},
{
- id: 13,
+ id: '13',
originChainID: ChainId.ArbitrumSepolia,
url: 'https://tokenlist.arbitrum.io/ArbTokenLists/421614_arbed_coingecko.json',
name: 'Arbed CoinGecko List',
isDefault: true,
logoURI: CoinGeckoLogo
},
- // Orbit
{
- id: 14,
- // Xai
- originChainID: 660279,
- url: 'https://tokenlist.arbitrum.io/ArbTokenLists/660279_arbed_uniswap_labs.json',
- name: 'Arbed Uniswap List',
- isDefault: true,
- logoURI: UniswapLogo
- },
- {
- id: 660279,
+ id: '660279',
// Xai
originChainID: 660279,
url: 'tokenLists/660279_default.json',
@@ -130,42 +123,33 @@ export const BRIDGE_TOKEN_LISTS: BridgeTokenList[] = [
isDefault: true,
logoURI: '/images/XaiLogo.svg'
},
- {
- id: 15,
- // Rari
- originChainID: 1380012617,
- url: 'https://tokenlist.arbitrum.io/ArbTokenLists/1380012617_arbed_uniswap_labs.json',
- name: 'Arbed Uniswap List',
- isDefault: true,
- logoURI: UniswapLogo
- },
- {
- id: 16,
- // Muster
- originChainID: 4078,
- url: 'https://tokenlist.arbitrum.io/ArbTokenLists/4078_arbed_uniswap_labs.json',
- name: 'Arbed Uniswap List',
- isDefault: true,
- logoURI: UniswapLogo
- },
- {
- id: 17,
- // Proof of Play Apex
- originChainID: 70700,
- url: 'https://tokenlist.arbitrum.io/ArbTokenLists/70700_arbed_uniswap_labs.json',
- name: 'Arbed Uniswap List',
- isDefault: true,
- logoURI: UniswapLogo
- },
- {
- id: 19,
- // SX Network
- originChainID: 4162,
- url: 'https://tokenlist.arbitrum.io/ArbTokenLists/4162_arbed_uniswap_labs.json',
- name: 'Arbed Uniswap List',
- isDefault: true,
- logoURI: UniswapLogo
- }
+ // For all orbit chains,
+ ...orbitChainsData.mainnet
+ .concat(orbitChainsData.testnet)
+ .reduce((acc, chain) => {
+ // Only include arbified native token list for L3 settling to ArbOne
+ if (chain.parentChainId === ChainId.ArbitrumOne) {
+ acc.push({
+ id: `${chain.chainId}_native`,
+ originChainID: chain.chainId,
+ url: `https://tokenlist.arbitrum.io/ArbTokenLists/${chain.chainId}_arbed_native_list.json`,
+ name: `${chain.name} Default List`,
+ isDefault: true,
+ logoURI: ArbitrumLogo
+ })
+ }
+
+ acc.push({
+ id: `${chain.chainId}_uniswap`,
+ originChainID: chain.chainId,
+ url: `https://tokenlist.arbitrum.io/ArbTokenLists/${chain.chainId}_arbed_uniswap_labs.json`,
+ name: `${chain.name} Arbed Uniswap List`,
+ isDefault: true,
+ logoURI: UniswapLogo
+ })
+
+ return acc
+ }, [] as BridgeTokenList[])
]
export const listIdsToNames: { [key: string]: string } = {}
@@ -176,7 +160,7 @@ BRIDGE_TOKEN_LISTS.forEach(bridgeTokenList => {
export interface TokenListWithId extends TokenList {
l2ChainId: string
- bridgeTokenListId: number
+ bridgeTokenListId: string
isValid?: boolean
}
diff --git a/packages/arb-token-bridge-ui/src/util/TokenTeleportEnabledUtils.ts b/packages/arb-token-bridge-ui/src/util/TokenTeleportEnabledUtils.ts
index 3eabd7ed9d..72127f7bc5 100644
--- a/packages/arb-token-bridge-ui/src/util/TokenTeleportEnabledUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/TokenTeleportEnabledUtils.ts
@@ -1,4 +1,4 @@
-import { ChainId } from './networks'
+import { ChainId } from '../types/ChainId'
export type TeleportEnabledToken = {
symbol: string
diff --git a/packages/arb-token-bridge-ui/src/util/TokenTransferDisabledUtils.ts b/packages/arb-token-bridge-ui/src/util/TokenTransferDisabledUtils.ts
index 563f9b6549..863b01a5d4 100644
--- a/packages/arb-token-bridge-ui/src/util/TokenTransferDisabledUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/TokenTransferDisabledUtils.ts
@@ -1,4 +1,4 @@
-import { ChainId } from '../util/networks'
+import { ChainId } from '../types/ChainId'
export type TransferDisabledToken = {
symbol: string
diff --git a/packages/arb-token-bridge-ui/src/util/TokenUtils.ts b/packages/arb-token-bridge-ui/src/util/TokenUtils.ts
index 428e0dc305..b180be53c8 100644
--- a/packages/arb-token-bridge-ui/src/util/TokenUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/TokenUtils.ts
@@ -11,7 +11,8 @@ import {
import { ERC20__factory } from '@arbitrum/sdk/dist/lib/abi/factories/ERC20__factory'
import { CommonAddress } from './CommonAddressUtils'
-import { ChainId, isNetwork } from './networks'
+import { isNetwork } from './networks'
+import { ChainId } from '../types/ChainId'
import { defaultErc20Decimals } from '../defaults'
import { ERC20BridgeToken, TokenType } from '../hooks/arbTokenBridge.types'
import { getBridger, getChainIdFromProvider } from '../token-bridge-sdk/utils'
diff --git a/packages/arb-token-bridge-ui/src/util/WithdrawOnlyUtils.ts b/packages/arb-token-bridge-ui/src/util/WithdrawOnlyUtils.ts
index beeb63fe91..08a45510a7 100644
--- a/packages/arb-token-bridge-ui/src/util/WithdrawOnlyUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/WithdrawOnlyUtils.ts
@@ -4,7 +4,8 @@
import { ethers } from 'ethers'
import { getProviderForChainId } from '@/token-bridge-sdk/utils'
-import { ChainId, isNetwork } from '../util/networks'
+import { isNetwork } from '../util/networks'
+import { ChainId } from '../types/ChainId'
import {
isTokenArbitrumOneUSDCe,
isTokenArbitrumSepoliaUSDCe
@@ -217,6 +218,24 @@ export const withdrawOnlyTokens: { [chainId: number]: WithdrawOnlyToken[] } = {
l2CustomAddr: '',
l1Address: '0x83e817E1574e2201a005EC0f7e700ED5606F555E',
l2Address: '0x87ABaD012da6DcD0438e36967FcaD54C9d64F86C'
+ },
+ {
+ symbol: 'Pepe',
+ l2CustomAddr: '',
+ l1Address: '0x6982508145454Ce325dDbE47a25d4ec3d2311933',
+ l2Address: '0x35E6A59F786d9266c7961eA28c7b768B33959cbB'
+ },
+ {
+ symbol: 'cbBTC',
+ l2CustomAddr: '',
+ l1Address: '0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf',
+ l2Address: '0x4A605F93288e95db40cE72934b888641D9689a48'
+ },
+ {
+ symbol: 'NST',
+ l2CustomAddr: '',
+ l1Address: '0x70Bef3bB2f001dA2fDDb207dAe696cD9FAFf3f5d',
+ l2Address: '0xd5A1a674F0DA33A4147a8Cd96143E598e738c7FF'
}
],
[ChainId.ArbitrumNova]: []
diff --git a/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts b/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts
index ac29f2c02c..7d14ef12e6 100644
--- a/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts
+++ b/packages/arb-token-bridge-ui/src/util/WithdrawalUtils.ts
@@ -10,8 +10,11 @@ import { GasEstimates } from '../hooks/arbTokenBridge.types'
import { Address } from './AddressUtils'
import { captureSentryErrorWithExtraData } from './SentryUtils'
import { getBridgeUiConfigForChain } from './bridgeUiConfig'
-import { isNetwork } from './networks'
-
+import {
+ getBlockNumberReferenceChainIdByChainId,
+ getConfirmPeriodBlocks,
+ getL1BlockTime
+} from './networks'
export async function withdrawInitTxEstimateGas({
amount,
address,
@@ -111,22 +114,26 @@ export async function withdrawInitTxEstimateGas({
const SECONDS_IN_MINUTE = 60
const SECONDS_IN_HOUR = 3600
const SECONDS_IN_DAY = 86400
-const DEFAULT_CONFIRMATION_TIME = 7 * SECONDS_IN_DAY
-const DEFAULT_TESTNET_CONFIRMATION_TIME = SECONDS_IN_HOUR
+/**
+ * Buffer for after a node is confirmable but isn't yet confirmed.
+ * A rollup block (RBlock) typically gets asserted every 30-60 minutes.
+ */
+const CONFIRMATION_BUFFER_MINUTES = 60
function formatDuration(seconds: number, short = false): string {
if (seconds < SECONDS_IN_MINUTE) {
- return `${seconds} ${short ? 'secs' : 'seconds'}`
+ return `${seconds} ${short ? 'secs' : seconds === 1 ? 'second' : 'seconds'}`
}
if (seconds < SECONDS_IN_HOUR) {
- return `${Math.round(seconds / SECONDS_IN_MINUTE)} ${
- short ? 'mins' : 'minutes'
- }`
+ const minutes = Math.round(seconds / SECONDS_IN_MINUTE)
+ return `${minutes} ${short ? 'mins' : minutes === 1 ? 'minute' : 'minutes'}`
}
if (seconds < SECONDS_IN_DAY) {
- return `${Math.round(seconds / SECONDS_IN_HOUR)} hours`
+ const hours = Math.round(seconds / SECONDS_IN_HOUR)
+ return `${hours} ${hours === 1 ? 'hour' : 'hours'}`
}
- return `${Math.round(seconds / SECONDS_IN_DAY)} days`
+ const days = Math.round(seconds / SECONDS_IN_DAY)
+ return `${days} ${days === 1 ? 'day' : 'days'}`
}
/**
@@ -135,7 +142,6 @@ function formatDuration(seconds: number, short = false): string {
*/
export function getConfirmationTime(chainId: number) {
const { fastWithdrawalTime } = getBridgeUiConfigForChain(chainId)
- const isTestnet = isNetwork(chainId).isTestnet
const fastWithdrawalActive = typeof fastWithdrawalTime !== 'undefined'
@@ -144,9 +150,16 @@ export function getConfirmationTime(chainId: number) {
if (fastWithdrawalActive) {
confirmationTimeInSeconds = fastWithdrawalTime / 1000
} else {
- confirmationTimeInSeconds = isTestnet
- ? DEFAULT_TESTNET_CONFIRMATION_TIME
- : DEFAULT_CONFIRMATION_TIME
+ // Calculate confirmation period using block time from root chain:
+ // - Ethereum mainnet for Arbitrum chains
+ // - Parent chain for Base chains
+ const blockNumberReferenceChainId = getBlockNumberReferenceChainIdByChainId(
+ { chainId }
+ )
+ confirmationTimeInSeconds =
+ getL1BlockTime(blockNumberReferenceChainId) *
+ getConfirmPeriodBlocks(chainId) +
+ CONFIRMATION_BUFFER_MINUTES * SECONDS_IN_MINUTE
}
const confirmationTimeInReadableFormat = formatDuration(
diff --git a/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts b/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts
index fe0e2f7952..445272a7f7 100644
--- a/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts
+++ b/packages/arb-token-bridge-ui/src/util/__tests__/networks.test.ts
@@ -1,11 +1,11 @@
import { registerCustomArbitrumNetwork } from '@arbitrum/sdk'
import {
- ChainId,
getBlockNumberReferenceChainIdByChainId,
getDestinationChainIds,
getSupportedChainIds
} from '../networks'
+import { ChainId } from '../../types/ChainId'
import { orbitTestnets } from '../orbitChainsList'
const xaiTestnetChainId = 37714555429
diff --git a/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts b/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts
index d7d4461918..03d8d03695 100644
--- a/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts
+++ b/packages/arb-token-bridge-ui/src/util/bridgeUiConfig.ts
@@ -1,4 +1,5 @@
-import { ChainId, getCustomChainFromLocalStorageById } from './networks'
+import { getCustomChainFromLocalStorageById } from './networks'
+import { ChainId } from '../types/ChainId'
import { orbitChains, BridgeUiConfig } from './orbitChainsList'
export function getBridgeUiConfigForChain(chainId: number): BridgeUiConfig {
diff --git a/packages/arb-token-bridge-ui/src/util/cctp/fetchCCTP.ts b/packages/arb-token-bridge-ui/src/util/cctp/fetchCCTP.ts
index bddf51db87..7b19be6214 100644
--- a/packages/arb-token-bridge-ui/src/util/cctp/fetchCCTP.ts
+++ b/packages/arb-token-bridge-ui/src/util/cctp/fetchCCTP.ts
@@ -1,4 +1,4 @@
-import { ChainId } from '../networks'
+import { ChainId } from '../../types/ChainId'
import { getAPIBaseUrl, sanitizeQueryParams } from '..'
import {
CompletedCCTPTransfer,
diff --git a/packages/arb-token-bridge-ui/src/util/deposits/fetchDeposits.ts b/packages/arb-token-bridge-ui/src/util/deposits/fetchDeposits.ts
index b2ec571855..17acc4dd64 100644
--- a/packages/arb-token-bridge-ui/src/util/deposits/fetchDeposits.ts
+++ b/packages/arb-token-bridge-ui/src/util/deposits/fetchDeposits.ts
@@ -6,7 +6,7 @@ import {
FetchDepositsFromSubgraphResult
} from './fetchDepositsFromSubgraph'
import { AssetType } from '../../hooks/arbTokenBridge.types'
-import { Transaction } from '../../hooks/useTransactions'
+import { Transaction } from '../../types/Transactions'
import { defaultErc20Decimals } from '../../defaults'
import { fetchNativeCurrency } from '../../hooks/useNativeCurrency'
import {
diff --git a/packages/arb-token-bridge-ui/src/util/deposits/helpers.ts b/packages/arb-token-bridge-ui/src/util/deposits/helpers.ts
index 53781fd739..bdd6cc93ec 100644
--- a/packages/arb-token-bridge-ui/src/util/deposits/helpers.ts
+++ b/packages/arb-token-bridge-ui/src/util/deposits/helpers.ts
@@ -18,7 +18,7 @@ import {
Transaction,
TxnStatus,
TeleporterTransaction
-} from '../../hooks/useTransactions'
+} from '../../types/Transactions'
import { fetchErc20Data } from '../TokenUtils'
import {
getL2ConfigForTeleport,
@@ -31,15 +31,12 @@ import {
normalizeTimestamp
} from '../../state/app/utils'
-export const updateAdditionalDepositData = async ({
- depositTx,
- parentProvider,
- childProvider
-}: {
+export const updateAdditionalDepositData = async (
depositTx: Transaction
- parentProvider: Provider
- childProvider: Provider
-}): Promise => {
+): Promise => {
+ const parentProvider = getProviderForChainId(depositTx.parentChainId)
+ const childProvider = getProviderForChainId(depositTx.childChainId)
+
// 1. for all the fetched txns, fetch the transaction receipts and update their exact status
// 2. on the basis of those, finally calculate the status of the transaction
diff --git a/packages/arb-token-bridge-ui/src/util/fastBridges.ts b/packages/arb-token-bridge-ui/src/util/fastBridges.ts
index 31e258336c..45f17f6c77 100644
--- a/packages/arb-token-bridge-ui/src/util/fastBridges.ts
+++ b/packages/arb-token-bridge-ui/src/util/fastBridges.ts
@@ -10,7 +10,7 @@ import Wormhole from '@/images/bridge/wormhole.svg'
// import LIFI from '@/images/bridge/lifi.webp'
import Router from '@/images/bridge/router.webp'
-import { ChainId } from './networks'
+import { ChainId } from '../types/ChainId'
import { USDC_LEARN_MORE_LINK } from '../constants'
export enum FastBridgeNames {
diff --git a/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts b/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts
index ce13b2be68..ed19d16c55 100644
--- a/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts
+++ b/packages/arb-token-bridge-ui/src/util/fetchL2Gateways.ts
@@ -18,18 +18,7 @@ import {
export async function fetchL2Gateways(l2Provider: Provider) {
const l2Network = await getArbitrumNetwork(l2Provider)
- if (!l2Network.tokenBridge) {
- return []
- }
-
- /* configure gateway addresses for fetching withdrawals */
- const { childErc20Gateway, childCustomGateway, childWethGateway } =
- l2Network.tokenBridge
- const gatewaysToUse = [
- childErc20Gateway,
- childCustomGateway,
- childWethGateway
- ]
+ const gatewaysToUse = []
const l2ArbReverseGateway = l2ArbReverseGatewayAddresses[l2Network.chainId]
const l2DaiGateway = l2DaiGatewayAddresses[l2Network.chainId]
const l2wstETHGateway = l2wstETHGatewayAddresses[l2Network.chainId]
diff --git a/packages/arb-token-bridge-ui/src/util/index.ts b/packages/arb-token-bridge-ui/src/util/index.ts
index 4e96205668..6844b28394 100644
--- a/packages/arb-token-bridge-ui/src/util/index.ts
+++ b/packages/arb-token-bridge-ui/src/util/index.ts
@@ -13,13 +13,6 @@ export const sanitizeImageSrc = (url: string): string => {
return url
}
-export function preloadImages(imageSources: string[]) {
- imageSources.forEach(imageSrc => {
- const image = new Image()
- image.src = imageSrc
- })
-}
-
export const loadEnvironmentVariableWithFallback = ({
env,
fallback
diff --git a/packages/arb-token-bridge-ui/src/util/infura.ts b/packages/arb-token-bridge-ui/src/util/infura.ts
index 20fa95514d..dfe3b4d48a 100644
--- a/packages/arb-token-bridge-ui/src/util/infura.ts
+++ b/packages/arb-token-bridge-ui/src/util/infura.ts
@@ -1,7 +1,7 @@
import { providers } from 'ethers'
import { Chain, ChainProviderFn } from 'wagmi'
-import { ChainId } from './networks'
+import { ChainId } from '../types/ChainId'
// custom implementation based on https://github.com/wevm/wagmi/blob/wagmi%400.12.13/packages/core/src/providers/infura.ts
// with multiple infura keys support
diff --git a/packages/arb-token-bridge-ui/src/util/networks.ts b/packages/arb-token-bridge-ui/src/util/networks.ts
index 813f5fecf5..ee6eaa341e 100644
--- a/packages/arb-token-bridge-ui/src/util/networks.ts
+++ b/packages/arb-token-bridge-ui/src/util/networks.ts
@@ -1,4 +1,4 @@
-import { StaticJsonRpcProvider } from '@ethersproject/providers'
+import { Provider, StaticJsonRpcProvider } from '@ethersproject/providers'
import {
ArbitrumNetwork,
getChildrenForNetwork,
@@ -10,27 +10,10 @@ import {
import { loadEnvironmentVariableWithFallback } from './index'
import { getBridgeUiConfigForChain } from './bridgeUiConfig'
import { fetchErc20Data } from './TokenUtils'
+import { orbitChains } from './orbitChainsList'
+import { ChainId } from '../types/ChainId'
import { getRpcUrl } from './rpc/getRpcUrl'
-export enum ChainId {
- // L1
- Ethereum = 1,
- // L1 Testnets
- Local = 1337,
- Sepolia = 11155111,
- Holesky = 17000,
- // L2
- ArbitrumOne = 42161,
- ArbitrumNova = 42170,
- Base = 8453,
- // L2 Testnets
- ArbitrumSepolia = 421614,
- ArbitrumLocal = 412346,
- BaseSepolia = 84532,
- // L3 Testnets
- L3Local = 333333
-}
-
/** The network that you reference when calling `block.number` in solidity */
type BlockNumberReferenceNetwork = {
chainId: ChainId
@@ -587,6 +570,16 @@ export function getSupportedChainIds({
})
}
+export function isAlchemyChain(chainId: number) {
+ const chain = orbitChains[chainId]
+
+ if (typeof chain === 'undefined') {
+ return false
+ }
+
+ return chain.rpcUrl.toLowerCase().includes('alchemy.com')
+}
+
export function mapCustomChainToNetworkData(chain: ChainWithRpcUrl) {
// custom chain details need to be added to various objects to make it work with the UI
//
diff --git a/packages/arb-token-bridge-ui/src/util/orbitChainsData.json b/packages/arb-token-bridge-ui/src/util/orbitChainsData.json
index 259c700f50..de7701c857 100644
--- a/packages/arb-token-bridge-ui/src/util/orbitChainsData.json
+++ b/packages/arb-token-bridge-ui/src/util/orbitChainsData.json
@@ -435,7 +435,8 @@
"name": "SX Network",
"symbol": "SX",
"logoUrl": "/images/sxTokenLogo.png"
- }
+ },
+ "fastWithdrawalTime": 43200000
}
},
{
@@ -670,7 +671,8 @@
"name": "EDU",
"symbol": "EDU",
"logoUrl": "/images/EduChainTokenLogo.png"
- }
+ },
+ "fastWithdrawalTime": 3600000
}
},
{
@@ -862,6 +864,147 @@
},
"fastWithdrawalTime": 900000
}
+ },
+ {
+ "chainId": 88899,
+ "confirmPeriodBlocks": 274908,
+ "ethBridge": {
+ "bridge": "0x80b4c2dBEacFF9921cD456e5E1489919185b8a1d",
+ "inbox": "0x319a9c8be1CF9ECB16D29d6327A6Fa2e26Bf42BC",
+ "outbox": "0xd9AD042DCb18628a941C8868bf25e5eCf897E48c",
+ "rollup": "0xd6df93D93c2554412622C567965DA7B16929f0A5",
+ "sequencerInbox": "0x3A2898B10c88cb619635efdC027538D7Aa99BF79"
+ },
+ "nativeToken": "0xA6C6ea2e0140849bE02A3a34780CF61b766916c5",
+ "explorerUrl": "https://unite-mainnet.explorer.alchemy.com/",
+ "rpcUrl": "https://unite-mainnet.g.alchemy.com/public",
+ "isCustom": true,
+ "isTestnet": false,
+ "name": "Unite Mainnet",
+ "slug": "unite-mainnet",
+ "parentChainId": 8453,
+ "tokenBridge": {
+ "parentCustomGateway": "0xeA2Ffb3BA907418a5a9A9Cdb90212c814230Ba5d",
+ "parentErc20Gateway": "0x03b9C7978143A3A360cb37101F2A3f7f1B0eE8e8",
+ "parentGatewayRouter": "0xbaD53A171A9D0785EC179b5C3eFd3d7083b8D3a7",
+ "parentMultiCall": "0xb444317D808b5cFfE66495920D40A35E7D247cC4",
+ "parentProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "parentWeth": "0x0000000000000000000000000000000000000000",
+ "parentWethGateway": "0x0000000000000000000000000000000000000000",
+ "childCustomGateway": "0xa123C9a36e7162686197B92800f62573E69FE379",
+ "childErc20Gateway": "0x012595d521139F2Df03F0666a09f08caC99C4b1B",
+ "childGatewayRouter": "0x3224F78EC97bB795D16D5954Aa9e408f882520B2",
+ "childMultiCall": "0x95FdfA72d6C87968da0f38ac17a847203838f56C",
+ "childProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "childWeth": "0x0000000000000000000000000000000000000000",
+ "childWethGateway": "0x0000000000000000000000000000000000000000"
+ },
+ "bridgeUiConfig": {
+ "color": "#7aad00",
+ "network": {
+ "name": "Unite Mainnet",
+ "logo": "/images/unite-mainnet_Logo.png"
+ },
+ "nativeTokenData": {
+ "name": "Unite",
+ "symbol": "UNITE",
+ "logoUrl": "/images/unite-mainnet_Logo.png"
+ }
+ }
+ },
+ {
+ "chainId": 149,
+ "confirmPeriodBlocks": 45818,
+ "ethBridge": {
+ "bridge": "0xa2ed3b6B4069295F5C89F60B61a196dE09741fb6",
+ "inbox": "0xBC0862181F93f2fef61Cd5Edd4C7D8C5cCDb76AE",
+ "outbox": "0x51229C00f364F40dF07C4e71de02e6D16Ffb1aEa",
+ "rollup": "0x1210118afD15EF90CA4f83cF65dc659876299e7A",
+ "sequencerInbox": "0xf80Ce375724AF270D23526B93c37E9B17A64bD8a"
+ },
+ "nativeToken": "0x7777778E9199FBC424b7494D55D26579c011E8c6",
+ "explorerUrl": "https://socialnetwork-mainnet.explorer.alchemy.com/",
+ "rpcUrl": "https://socialnetwork-mainnet.g.alchemy.com/public",
+ "isCustom": true,
+ "isTestnet": false,
+ "name": "Social Network",
+ "slug": "social-network",
+ "parentChainId": 1,
+ "tokenBridge": {
+ "parentCustomGateway": "0xE32125cE1A8fFf30B5c0bB164B7E81816CA626F6",
+ "parentErc20Gateway": "0xB2e209Af16f087D2c985fFcee64EcabEF10A149F",
+ "parentGatewayRouter": "0x7eAc61b1477906a94e35F5efFAC24305C1654A19",
+ "parentMultiCall": "0x7cdCB0Cc61f47B8Dd8f47C5A29edaDd84a1BDf5e",
+ "parentProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "parentWeth": "0x0000000000000000000000000000000000000000",
+ "parentWethGateway": "0x0000000000000000000000000000000000000000",
+ "childCustomGateway": "0xE00D3DBD78aE6D674bE410Eb4828611897579746",
+ "childErc20Gateway": "0x33888CC3084689e2929277488D6D4f20a90B83BB",
+ "childGatewayRouter": "0x5cCcde8552d6eb4f27313766fe4D590b4677fbF8",
+ "childMultiCall": "0x7Cab274d056ec9CdB4231B30a36D36FD789DF9C3",
+ "childProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "childWeth": "0x0000000000000000000000000000000000000000",
+ "childWethGateway": "0x0000000000000000000000000000000000000000"
+ },
+ "bridgeUiConfig": {
+ "color": "#12266B",
+ "network": {
+ "name": "Social Network",
+ "logo": "/images/SocialMainnet_Logo.webp"
+ },
+ "nativeTokenData": {
+ "name": "Earth",
+ "symbol": "Earth"
+ }
+ }
+ },
+ {
+ "chainId": 140,
+ "confirmPeriodBlocks": 1081,
+ "ethBridge": {
+ "bridge": "0x77778b624B03D5D41FeC06641629BB3C98D94892",
+ "inbox": "0x1CB71Be210c6a0BE2b95B6FBD09b1a43Ae679f97",
+ "outbox": "0xf32E5481acde9E41cdD0EFAc6cDe3C7876cf65b3",
+ "rollup": "0xeD6F7916Da27b1A4680EB0C63aA3C768bCc10EDA",
+ "sequencerInbox": "0x7F17f54174c07F9213dc0EF9009c082542549A9C"
+ },
+ "nativeToken": "0x6e6C39CAC539Ab057d357d16d69Fd04d2b0fc38f",
+ "explorerUrl": "https://explorer.data-lake.co/",
+ "rpcUrl": "https://rpc.data-lake.co/",
+ "isCustom": true,
+ "isTestnet": false,
+ "name": "Data Lake Mainnet",
+ "slug": "data-lake-mainnet",
+ "parentChainId": 42170,
+ "tokenBridge": {
+ "parentCustomGateway": "0xB6725767227Aa858b112a4E563a7D357eddbECEa",
+ "parentErc20Gateway": "0x1fbdB03f9fe57Cf0049e0F238984C7a9cf4D8ca1",
+ "parentGatewayRouter": "0x63a9cd1aF4d8E254470E32F9D11FA516fdCc4a14",
+ "parentMultiCall": "0x23d1171380e3cbAA161F6EB31e3A3c6B548A467a",
+ "parentProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "parentWeth": "0x0000000000000000000000000000000000000000",
+ "parentWethGateway": "0x0000000000000000000000000000000000000000",
+ "childCustomGateway": "0x0E13f3E7828925F31D3FE3e8Aa7343Cb95a78525",
+ "childErc20Gateway": "0x3b0825034A4F5b725990df6621EbE09C1ecb24dB",
+ "childGatewayRouter": "0x71e8d7eC6311Bbf7654E54115FD2c23d8C10Ff5f",
+ "childMultiCall": "0x8c4a651c207c63fd388574FeEcE51AAFD23f69a7",
+ "childProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "childWeth": "0x0000000000000000000000000000000000000000",
+ "childWethGateway": "0x0000000000000000000000000000000000000000"
+ },
+ "bridgeUiConfig": {
+ "color": "#876D9C",
+ "network": {
+ "name": "Data Lake Mainnet",
+ "logo": "/images/DataLakeMainnet_Logo.png",
+ "description": "The Data Lake Chain is a pioneering Layer 3 blockchain designed to empower decentralized science (DeSci) and healthcare research. Built on Arbitrum Orbit, the Data Lake Chain is tailored for secure and compliant management of consents."
+ },
+ "nativeTokenData": {
+ "name": "Data Lake Token",
+ "symbol": "LAKE",
+ "logoUrl": "/images/DataLakeMainnet_NativeTokenLogo.png"
+ }
+ }
}
],
"testnet": [
@@ -1284,6 +1427,95 @@
"logoUrl": "/images/UsdcLogo.svg"
}
}
+ },
+ {
+ "chainId": 888991,
+ "confirmPeriodBlocks": 900,
+ "ethBridge": {
+ "bridge": "0xA1AF96d8315DCa65F2ff6f8170Fa3e5dB0A6aD3C",
+ "inbox": "0xCA323c4C0A04109F303e3bfd879AEd5F49c9f0C4",
+ "outbox": "0x54a8712d8d5f8D3cD29737d06734eE493758B7cb",
+ "rollup": "0xB2Ff332B564DA65EDd2FDcbf298458837c732997",
+ "sequencerInbox": "0x0b172ba2776C08F6c3147ed2471A32EC4592812B"
+ },
+ "nativeToken": "0xf7a942db06a0cd6945ba4635c46e31c54ed175a4",
+ "explorerUrl": "https://unite-testnet.explorer.alchemy.com/",
+ "rpcUrl": "https://unite-testnet.g.alchemy.com/public",
+ "isCustom": true,
+ "isTestnet": true,
+ "name": "Unite Testnet",
+ "slug": "unite-testnet",
+ "parentChainId": 84532,
+ "tokenBridge": {
+ "parentCustomGateway": "0xb7B03E20ca71c6036F8F841cCc213e7CaC3e9868",
+ "parentErc20Gateway": "0x98614745322365Ae378Db2A6319F873A4775398C",
+ "parentGatewayRouter": "0xA8f3C0d5eC3E9ACd3422cBf5f25c6C4e608c2499",
+ "parentMultiCall": "0xE0753Df74d86D6B25aCd2d049389c7E52e2dd728",
+ "parentProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "parentWeth": "0x0000000000000000000000000000000000000000",
+ "parentWethGateway": "0x0000000000000000000000000000000000000000",
+ "childCustomGateway": "0x01a902C5b160F0c786aDfc702799D25218d8A9B4",
+ "childErc20Gateway": "0xaABa25Ba10B9aFEf17D403B4038886e7FD743E83",
+ "childGatewayRouter": "0xdbAEDA962D2D201F65c06C81Dd5A0FC948FB3A20",
+ "childMultiCall": "0x7df4290268655542E0B39465820a39C4b091D77e",
+ "childProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "childWeth": "0x0000000000000000000000000000000000000000",
+ "childWethGateway": "0x0000000000000000000000000000000000000000"
+ },
+ "bridgeUiConfig": {
+ "color": "#7aad00",
+ "network": {
+ "name": "Unite Testnet",
+ "logo": "/images/unite-testnet_Logo.png"
+ },
+ "nativeTokenData": {
+ "name": "Unite",
+ "symbol": "UNITE",
+ "logoUrl": "/images/unite-testnet_Logo.png"
+ }
+ }
+ },
+ {
+ "chainId": 98864,
+ "confirmPeriodBlocks": 60,
+ "ethBridge": {
+ "bridge": "0xF3BE11Ead404740017e4839712Af28e3c0b5C202",
+ "inbox": "0xDe66d6a8BabE07f6838ea712e708BBD47837de52",
+ "outbox": "0xE8806C827217b9C1D9610b5334254Da4d143dF3D",
+ "rollup": "0x7404f23fc2189e090E2342FaaF7f20efa7bD366a",
+ "sequencerInbox": "0xDcAb173C5D846d686856A2D3300B8a64ba12130D"
+ },
+ "explorerUrl": "https://test-explorer.plumenetwork.xyz/",
+ "rpcUrl": "https://test-rpc.plumenetwork.xyz/",
+ "isCustom": true,
+ "isTestnet": true,
+ "name": "Plume Devnet",
+ "slug": "plume-devnet",
+ "parentChainId": 11155111,
+ "tokenBridge": {
+ "parentCustomGateway": "0xa8168b76Aa023228CaA8Ef5110477cD6d02F1508",
+ "parentErc20Gateway": "0xD7A43a671c177Ed55D2B4bCaFc597Bb669Ce4B99",
+ "parentGatewayRouter": "0x0a4671a34D411868852be59cCa137D5f251dEe52",
+ "parentMultiCall": "0x73465577E9FD7Cd585E4270F23A9eBa99B92b6eD",
+ "parentProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "parentWeth": "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
+ "parentWethGateway": "0x8a3f580894fF2C51E202Da7712f5550533a956B1",
+ "childCustomGateway": "0xA7E44Ce807F488791c6Bc8877c9CA7b36c68B9C0",
+ "childErc20Gateway": "0xc9F79584303fDcb2cf5d147D7Dc79c38EA3BEC11",
+ "childGatewayRouter": "0x52a0A8a9A65F90E160940972A0de15491172db87",
+ "childMultiCall": "0xA569f0e5e284A45F6155cbc4C904ad3cae0a82b0",
+ "childProxyAdmin": "0x0000000000000000000000000000000000000000",
+ "childWeth": "0x1738E5247c85f96c9D35FE55800557C5479b7063",
+ "childWethGateway": "0xc260574cD5F7469d9a840f85A6648F74b7Bd4097"
+ },
+ "bridgeUiConfig": {
+ "color": "#F43B3A",
+ "network": {
+ "name": "Plume Devnet",
+ "logo": "/images/PlumeDevnet_Logo.png",
+ "description": "Bringing the real world onchain. Optimized for real world assets."
+ }
+ }
}
]
}
diff --git a/packages/arb-token-bridge-ui/src/util/teleports/helpers.ts b/packages/arb-token-bridge-ui/src/util/teleports/helpers.ts
index dbab4fd3bf..af7da8a792 100644
--- a/packages/arb-token-bridge-ui/src/util/teleports/helpers.ts
+++ b/packages/arb-token-bridge-ui/src/util/teleports/helpers.ts
@@ -10,7 +10,7 @@ import { MergedTransaction } from '../../state/app/state'
import { FetchEthTeleportsFromSubgraphResult } from './fetchEthTeleportsFromSubgraph'
import { TeleportFromSubgraph } from './fetchTeleports'
import { AssetType } from '../../hooks/arbTokenBridge.types'
-import { Transaction } from '../../hooks/useTransactions'
+import { Transaction } from '../../types/Transactions'
import { transformDeposit } from '../../state/app/utils'
import { updateAdditionalDepositData } from '../deposits/helpers'
import { fetchErc20Data } from '../TokenUtils'
@@ -70,14 +70,7 @@ export async function transformTeleportFromSubgraph(
childChainId: Number(tx.childChainId)
} as Transaction
- const childProvider = getProviderForChainId(Number(tx.childChainId))
- return transformDeposit(
- await updateAdditionalDepositData({
- depositTx,
- parentProvider,
- childProvider
- })
- )
+ return transformDeposit(await updateAdditionalDepositData(depositTx))
}
// Erc20 transfers
@@ -112,12 +105,5 @@ export async function transformTeleportFromSubgraph(
childChainId: l3ChainId
} as Transaction
- const childProvider = getProviderForChainId(l3ChainId)
- return transformDeposit(
- await updateAdditionalDepositData({
- depositTx,
- parentProvider,
- childProvider
- })
- )
+ return transformDeposit(await updateAdditionalDepositData(depositTx))
}
diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts
index ad75742cc3..172e185d3c 100644
--- a/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts
+++ b/packages/arb-token-bridge-ui/src/util/wagmi/getWagmiChain.ts
@@ -13,7 +13,8 @@ import {
baseSepolia,
base
} from './wagmiAdditionalNetworks'
-import { ChainId, getCustomChainFromLocalStorageById } from '../networks'
+import { getCustomChainFromLocalStorageById } from '../networks'
+import { ChainId } from '../../types/ChainId'
import { orbitChains } from '../orbitChainsList'
export function getWagmiChain(chainId: number): Chain {
diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts
index 4b748a2080..179f8ead9b 100644
--- a/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts
+++ b/packages/arb-token-bridge-ui/src/util/wagmi/setup.ts
@@ -17,7 +17,8 @@ import {
baseSepolia
} from './wagmiAdditionalNetworks'
import { isTestingEnvironment } from '../CommonUtils'
-import { getCustomChainsFromLocalStorage, ChainId, rpcURLs } from '../networks'
+import { getCustomChainsFromLocalStorage, rpcURLs } from '../networks'
+import { ChainId } from '../../types/ChainId'
import { getOrbitChains } from '../orbitChainsList'
import { getWagmiChain } from './getWagmiChain'
import { customInfuraProvider } from '../infura'
@@ -148,14 +149,13 @@ export function getProps(targetChainKey: string | null) {
chains
})
+ wallets[0]?.wallets.push(okxWallet({ chains, projectId }))
+
const connectors = connectorsForWallets([
...wallets,
{
groupName: 'More',
- wallets: [
- trustWallet({ chains, projectId }),
- okxWallet({ chains, projectId })
- ]
+ wallets: [trustWallet({ chains, projectId })]
}
])
diff --git a/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts b/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts
index 8c9228e5cd..0d0e867606 100644
--- a/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts
+++ b/packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts
@@ -1,7 +1,8 @@
import { Chain, sepolia as sepoliaDefault } from 'wagmi'
import { ether } from '../../constants'
-import { ChainId, ChainWithRpcUrl, explorerUrls, rpcURLs } from '../networks'
+import { ChainWithRpcUrl, explorerUrls, rpcURLs } from '../networks'
+import { ChainId } from '../../types/ChainId'
import { getBridgeUiConfigForChain } from '../bridgeUiConfig'
import { NativeCurrencyBase } from '../../hooks/useNativeCurrency'
diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts
index a9955e6dc8..6550370a86 100644
--- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts
+++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchETHWithdrawalsFromEventLogs.ts
@@ -5,7 +5,7 @@ import { ChildToParentMessageReader } from '@arbitrum/sdk'
* Fetches initiated ETH withdrawals from event logs in range of [fromBlock, toBlock].
*
* @param query Query params
- * @param query.receiver Address that will receive the funds
+ * @param query.receiver Address that received the funds
* @param query.fromBlock Start at this block number (including)
* @param query.toBlock Stop at this block number (including)
* @param query.l2Provider Provider for the L2 network
@@ -22,9 +22,10 @@ export function fetchETHWithdrawalsFromEventLogs({
l2Provider: Provider
}) {
if (typeof receiver === 'undefined') {
- return []
+ return Promise.resolve([])
}
- // funds sent by this address
+
+ // funds received by this address
return ChildToParentMessageReader.getChildToParentEvents(
l2Provider,
{ fromBlock, toBlock },
diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts
index 0b3d9531e3..8296e2085f 100644
--- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts
+++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogs.ts
@@ -10,6 +10,15 @@ function dedupeEvents(
return [...new Map(events.map(item => [item.txHash, item])).values()]
}
+export type FetchTokenWithdrawalsFromEventLogsParams = {
+ sender?: string
+ receiver?: string
+ fromBlock: BlockTag
+ toBlock: BlockTag
+ l2Provider: Provider
+ l2GatewayAddresses?: string[]
+}
+
/**
* Fetches initiated token withdrawals from event logs in range of [fromBlock, toBlock].
*
@@ -28,14 +37,7 @@ export async function fetchTokenWithdrawalsFromEventLogs({
toBlock,
l2Provider,
l2GatewayAddresses = []
-}: {
- sender?: string
- receiver?: string
- fromBlock: BlockTag
- toBlock: BlockTag
- l2Provider: Provider
- l2GatewayAddresses?: string[]
-}) {
+}: FetchTokenWithdrawalsFromEventLogsParams) {
const erc20Bridger = await Erc20Bridger.fromProvider(l2Provider)
const promises: ReturnType[] = []
diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts
new file mode 100644
index 0000000000..3e421ca077
--- /dev/null
+++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchTokenWithdrawalsFromEventLogsSequentially.ts
@@ -0,0 +1,115 @@
+import { constants } from 'ethers'
+import { Provider, BlockTag } from '@ethersproject/providers'
+import { Erc20Bridger } from '@arbitrum/sdk'
+
+import {
+ fetchTokenWithdrawalsFromEventLogs,
+ FetchTokenWithdrawalsFromEventLogsParams
+} from './fetchTokenWithdrawalsFromEventLogs'
+
+import { backOff, wait } from '../ExponentialBackoffUtils'
+
+type FetchTokenWithdrawalsFromEventLogsQuery = {
+ params: FetchTokenWithdrawalsFromEventLogsParams
+ priority: number
+}
+
+export type Query = {
+ sender?: string
+ receiver?: string
+ gateways?: string[]
+}
+
+export type FetchTokenWithdrawalsFromEventLogsSequentiallyParams = {
+ sender?: string
+ receiver?: string
+ provider: Provider
+ fromBlock?: BlockTag
+ toBlock?: BlockTag
+ /**
+ * How long to delay in-between queries of different priority. Defaults to 0.
+ */
+ delayMs?: number
+ queries: Query[]
+}
+
+export type FetchTokenWithdrawalsFromEventLogsSequentiallyResult = Awaited<
+ ReturnType
+>
+
+export async function fetchTokenWithdrawalsFromEventLogsSequentially({
+ provider,
+ fromBlock = 0,
+ toBlock = 'latest',
+ delayMs = 0,
+ queries: queriesProp
+}: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise {
+ // keep track of priority; increment as queries are added
+ let priority = 0
+
+ // keep track of queries
+ const queries: FetchTokenWithdrawalsFromEventLogsQuery[] = []
+
+ // helper function to reuse common params
+ function buildQueryParams({
+ sender,
+ receiver,
+ gateways = []
+ }: Query): FetchTokenWithdrawalsFromEventLogsQuery['params'] {
+ return {
+ sender,
+ receiver,
+ fromBlock,
+ toBlock,
+ l2Provider: provider,
+ l2GatewayAddresses: gateways
+ }
+ }
+
+ // for sanitizing, adding queries and incrementing priority
+ function addQuery(params: FetchTokenWithdrawalsFromEventLogsQuery['params']) {
+ const gateways = params.l2GatewayAddresses ?? []
+ const gatewaysSanitized = gateways.filter(g => g !== constants.AddressZero)
+
+ if (gatewaysSanitized.length === 0) {
+ return
+ }
+
+ queries.push({
+ params: { ...params, l2GatewayAddresses: gatewaysSanitized },
+ priority: ++priority
+ })
+ }
+
+ queriesProp.forEach(query => {
+ addQuery(buildQueryParams(query))
+ })
+
+ // for iterating through all priorities in the while loop below
+ let currentPriority = 1
+
+ // final result
+ const result: FetchTokenWithdrawalsFromEventLogsSequentiallyResult = []
+
+ while (currentPriority <= priority) {
+ const currentPriorityQueries = queries.filter(
+ query => query.priority === currentPriority
+ )
+
+ const currentPriorityResults = await Promise.all(
+ currentPriorityQueries.map(query =>
+ backOff(() => fetchTokenWithdrawalsFromEventLogs(query.params))
+ )
+ )
+
+ currentPriorityResults.forEach(r => {
+ result.push(...r)
+ })
+
+ await wait(delayMs)
+
+ currentPriority++
+ }
+
+ return result
+}
diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts
index 624182bdae..aba40e7207 100644
--- a/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts
+++ b/packages/arb-token-bridge-ui/src/util/withdrawals/fetchWithdrawals.ts
@@ -7,11 +7,41 @@ import {
fetchWithdrawalsFromSubgraph
} from './fetchWithdrawalsFromSubgraph'
import { fetchLatestSubgraphBlockNumber } from '../SubgraphUtils'
-import { fetchTokenWithdrawalsFromEventLogs } from './fetchTokenWithdrawalsFromEventLogs'
-import { fetchL2Gateways } from '../fetchL2Gateways'
+
import { Withdrawal } from '../../hooks/useTransactionHistory'
import { attachTimestampToTokenWithdrawal } from './helpers'
import { WithdrawalInitiated } from '../../hooks/arbTokenBridge.types'
+import {
+ Query,
+ fetchTokenWithdrawalsFromEventLogsSequentially
+} from './fetchTokenWithdrawalsFromEventLogsSequentially'
+import { backOff, wait } from '../ExponentialBackoffUtils'
+import { isAlchemyChain } from '../networks'
+import { getArbitrumNetwork } from '@arbitrum/sdk'
+import { fetchL2Gateways } from '../fetchL2Gateways'
+import { constants } from 'ethers'
+import { getNonce } from '../AddressUtils'
+
+async function getGateways(provider: Provider): Promise<{
+ standardGateway: string
+ wethGateway: string
+ customGateway: string
+ otherGateways: string[]
+}> {
+ const network = await getArbitrumNetwork(provider)
+
+ const standardGateway = network.tokenBridge?.childErc20Gateway
+ const customGateway = network.tokenBridge?.childCustomGateway
+ const wethGateway = network.tokenBridge?.childWethGateway
+ const otherGateways = await fetchL2Gateways(provider)
+
+ return {
+ standardGateway: standardGateway ?? constants.AddressZero,
+ wethGateway: wethGateway ?? constants.AddressZero,
+ customGateway: customGateway ?? constants.AddressZero,
+ otherGateways
+ }
+}
export type FetchWithdrawalsParams = {
sender?: string
@@ -43,8 +73,6 @@ export async function fetchWithdrawals({
const l1ChainID = (await l1Provider.getNetwork()).chainId
const l2ChainID = (await l2Provider.getNetwork()).chainId
- const l2GatewayAddresses = await fetchL2Gateways(l2Provider)
-
if (!fromBlock) {
fromBlock = 0
}
@@ -85,23 +113,69 @@ export async function fetchWithdrawals({
console.log('Error fetching withdrawals from subgraph', error)
}
- const [ethWithdrawalsFromEventLogs, tokenWithdrawalsFromEventLogs] =
- await Promise.all([
- fetchETHWithdrawalsFromEventLogs({
- receiver,
- fromBlock: toBlock + 1,
- toBlock: 'latest',
- l2Provider: l2Provider
- }),
- fetchTokenWithdrawalsFromEventLogs({
- sender,
- receiver,
- fromBlock: toBlock + 1,
- toBlock: 'latest',
- l2Provider: l2Provider,
- l2GatewayAddresses
- })
- ])
+ const gateways = await getGateways(l2Provider)
+ const senderNonce = await getNonce(sender, { provider: l2Provider })
+
+ const queries: Query[] = []
+
+ // alchemy as a raas has a global rate limit across their chains, so we have to fetch sequentially and wait in-between requests to work around this
+ const isAlchemy = isAlchemyChain(l2ChainID)
+ const delayMs = isAlchemy ? 2_000 : 0
+
+ const allGateways = [
+ gateways.standardGateway,
+ gateways.wethGateway,
+ gateways.customGateway,
+ ...gateways.otherGateways
+ ]
+
+ // sender queries; only add if nonce > 0
+ if (senderNonce > 0) {
+ if (isAlchemy) {
+ // for alchemy, fetch sequentially
+ queries.push({ sender, gateways: [gateways.standardGateway] })
+ queries.push({ sender, gateways: [gateways.wethGateway] })
+ queries.push({ sender, gateways: [gateways.customGateway] })
+ queries.push({ sender, gateways: gateways.otherGateways })
+ } else {
+ // for other chains, fetch in parallel
+ queries.push({ sender, gateways: allGateways })
+ }
+ }
+
+ if (isAlchemy) {
+ // for alchemy, fetch sequentially
+ queries.push({ receiver, gateways: [gateways.standardGateway] })
+ queries.push({ receiver, gateways: [gateways.wethGateway] })
+ queries.push({ receiver, gateways: [gateways.customGateway] })
+ queries.push({ receiver, gateways: gateways.otherGateways })
+ } else {
+ // for other chains, fetch in parallel
+ queries.push({ receiver, gateways: allGateways })
+ }
+
+ const ethWithdrawalsFromEventLogs = await backOff(() =>
+ fetchETHWithdrawalsFromEventLogs({
+ receiver,
+ // not sure why eslint is treating "toBlock" as "number | undefined" here
+ // even though typescript recognizes it as "number"
+ fromBlock: toBlock ?? 0 + 1,
+ toBlock: 'latest',
+ l2Provider: l2Provider
+ })
+ )
+
+ await wait(delayMs)
+
+ const tokenWithdrawalsFromEventLogs =
+ await fetchTokenWithdrawalsFromEventLogsSequentially({
+ sender,
+ receiver,
+ fromBlock: toBlock + 1,
+ toBlock: 'latest',
+ provider: l2Provider,
+ queries
+ })
const mappedEthWithdrawalsFromEventLogs: Withdrawal[] =
ethWithdrawalsFromEventLogs.map(tx => {
diff --git a/packages/arb-token-bridge-ui/src/util/withdrawals/helpers.ts b/packages/arb-token-bridge-ui/src/util/withdrawals/helpers.ts
index 89ab0369be..dd069b4201 100644
--- a/packages/arb-token-bridge-ui/src/util/withdrawals/helpers.ts
+++ b/packages/arb-token-bridge-ui/src/util/withdrawals/helpers.ts
@@ -33,20 +33,6 @@ export type EthWithdrawal = L2ToL1EventResult & {
childChainId: number
}
-export const updateAdditionalWithdrawalData = async (
- withdrawalTx: L2ToL1EventResultPlus,
- l1Provider: Provider,
- l2Provider: Provider
-) => {
- const l2toL1TxWithDeadline = await attachNodeBlockDeadlineToEvent(
- withdrawalTx as L2ToL1EventResultPlus,
- l1Provider,
- l2Provider
- )
-
- return l2toL1TxWithDeadline
-}
-
export async function attachTimestampToTokenWithdrawal({
withdrawal,
l2Provider
@@ -128,55 +114,6 @@ export async function getOutgoingMessageState(
}
}
-export async function attachNodeBlockDeadlineToEvent(
- event: L2ToL1EventResultPlus,
- l1Provider: Provider,
- l2Provider: Provider
-) {
- if (
- event.outgoingMessageState === OutgoingMessageState.EXECUTED ||
- event.outgoingMessageState === OutgoingMessageState.CONFIRMED
- ) {
- return event
- }
-
- const messageReader = ChildToParentMessageReader.fromEvent(l1Provider, event)
-
- try {
- const firstExecutableBlock = await messageReader.getFirstExecutableBlock(
- l2Provider
- )
-
- return { ...event, nodeBlockDeadline: firstExecutableBlock?.toNumber() }
- } catch (e) {
- const expectedError = "batch doesn't exist"
- const expectedError2 = 'CALL_EXCEPTION'
-
- const err = e as Error & { error: Error }
- const errorMessage = err && (err.message || err.error?.message)
-
- if (errorMessage.includes(expectedError)) {
- const nodeBlockDeadline: NodeBlockDeadlineStatus =
- NodeBlockDeadlineStatusTypes.NODE_NOT_CREATED
- return {
- ...event,
- nodeBlockDeadline
- }
- } else if (errorMessage.includes(expectedError2)) {
- // in classic we simulate `executeTransaction` in `hasExecuted`
- // which might revert if the L2 to L1 call fail
- const nodeBlockDeadline: NodeBlockDeadlineStatus =
- NodeBlockDeadlineStatusTypes.EXECUTE_CALL_EXCEPTION
- return {
- ...event,
- nodeBlockDeadline
- }
- } else {
- throw e
- }
- }
-}
-
export function isTokenWithdrawal(
withdrawal: WithdrawalInitiated | EthWithdrawal
): withdrawal is WithdrawalInitiated {
diff --git a/packages/arb-token-bridge-ui/src/util/xErc20Utils.ts b/packages/arb-token-bridge-ui/src/util/xErc20Utils.ts
index 267763edaf..203a5e1059 100644
--- a/packages/arb-token-bridge-ui/src/util/xErc20Utils.ts
+++ b/packages/arb-token-bridge-ui/src/util/xErc20Utils.ts
@@ -1,6 +1,6 @@
import { getProviderForChainId } from '@/token-bridge-sdk/utils'
import { fetchErc20L2GatewayAddress } from './TokenUtils'
-import { ChainId } from './networks'
+import { ChainId } from '../types/ChainId'
import { TokenWithdrawalApprovalParams } from './L2ApprovalUtils'
export const xErc20Gateways: {
diff --git a/packages/arb-token-bridge-ui/synpress.config.ts b/packages/arb-token-bridge-ui/synpress.config.ts
index 84a332c1b0..31ae417ba1 100644
--- a/packages/arb-token-bridge-ui/synpress.config.ts
+++ b/packages/arb-token-bridge-ui/synpress.config.ts
@@ -226,7 +226,8 @@ export default defineConfig({
},
baseUrl: 'http://localhost:3000',
specPattern: tests,
- supportFile: 'tests/support/index.ts'
+ supportFile: 'tests/support/index.ts',
+ defaultCommandTimeout: 20_000
}
})
diff --git a/packages/arb-token-bridge-ui/tailwind.config.js b/packages/arb-token-bridge-ui/tailwind.config.js
index 687d267831..355dd9a77c 100644
--- a/packages/arb-token-bridge-ui/tailwind.config.js
+++ b/packages/arb-token-bridge-ui/tailwind.config.js
@@ -32,6 +32,11 @@ module.exports = {
'orange-dark': '#60461F',
'lime-dark': '#31572A',
+ // TRANSACTION STATUS COLORS
+ claim: '#6AD28A',
+ retry: '#CD0000',
+ pending: '#CCB069',
+
// NEUTRAL (GRAYS)
'gray-1': '#191919',
'gray-2': '#E5E5E5',
diff --git a/packages/arb-token-bridge-ui/tests/e2e/cypress.d.ts b/packages/arb-token-bridge-ui/tests/e2e/cypress.d.ts
index 267a499bf2..af0f75e815 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/cypress.d.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/cypress.d.ts
@@ -16,7 +16,7 @@ import {
findGasFeeSummary,
findGasFeeForChain,
findMoveFundsButton,
- startTransfer,
+ clickMoveFundsButton,
findSelectTokenButton,
openTransactionDetails,
closeTransactionDetails,
@@ -25,8 +25,9 @@ import {
findClaimButton,
selectTransactionsPanelTab,
confirmSpending,
- closeTransactionHistoryPanel,
- claimCctp
+ claimCctp,
+ switchToTransferPanelTab,
+ switchToTransactionHistoryTab
} from '../support/commands'
import { NetworkType, NetworkName } from '../support/common'
@@ -65,11 +66,12 @@ declare global {
findGasFeeForChain: typeof findGasFeeForChain
findGasFeeSummary: typeof findGasFeeSummary
findMoveFundsButton: typeof findMoveFundsButton
- startTransfer: typeof startTransfer
+ clickMoveFundsButton: typeof clickMoveFundsButton
findSelectTokenButton: typeof findSelectTokenButton
openTransactionDetails: typeof openTransactionDetails
closeTransactionDetails: typeof closeTransactionDetails
- closeTransactionHistoryPanel: typeof closeTransactionHistoryPanel
+ switchToTransferPanelTab: typeof switchToTransferPanelTab
+ switchToTransactionHistoryTab: typeof switchToTransactionHistoryTab
findTransactionDetailsCustomDestinationAddress: typeof findTransactionDetailsCustomDestinationAddress
findTransactionInTransactionHistory: typeof findTransactionInTransactionHistory
findClaimButton: typeof findClaimButton
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/approveToken.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/approveToken.cy.ts
index c96ceb903c..d3d90a3861 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/approveToken.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/approveToken.cy.ts
@@ -39,7 +39,7 @@ describe('Approve token for deposit', () => {
timeout: 50000,
interval: 500
})
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton({ shouldConfirmInMetamask: false })
cy.findByText(/pay a one-time approval fee/).click()
cy.findByRole('button', {
name: /Pay approval fee of/
@@ -50,7 +50,7 @@ describe('Approve token for deposit', () => {
* If confirm spending fails, test is still considered to be passing by Cypress
* We add another check to make sure the test fails if needed
*/
- cy.wait(10_000)
+ cy.wait(25_000)
cy.rejectMetamaskTransaction()
})
})
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/batchDeposit.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/batchDeposit.cy.ts
index b8661d2da5..0850de87f2 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/batchDeposit.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/batchDeposit.cy.ts
@@ -131,7 +131,7 @@ describe('Batch Deposit', () => {
}
context('should deposit successfully', () => {
- cy.startTransfer()
+ cy.clickMoveFundsButton()
cy.findTransactionInTransactionHistory({
...txData,
duration: depositTime
@@ -141,38 +141,40 @@ describe('Batch Deposit', () => {
context('deposit should complete successfully', () => {
cy.selectTransactionsPanelTab('settled')
- cy.waitUntil(() => cy.findTransactionInTransactionHistory(txData), {
- errorMsg: 'Could not find settled ERC20 Batch Deposit transaction',
- timeout: 60_000,
- interval: 500
- })
+ cy.findTransactionInTransactionHistory(txData)
cy.findTransactionInTransactionHistory({
duration: 'a few seconds ago',
...txData
})
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
})
context('funds should reach destination account successfully', () => {
// should have more funds on destination chain
- cy.findByLabelText(`${ERC20TokenSymbol} balance amount on childChain`)
- .invoke('text')
- .then(parseFloat)
- .should('be.gt', Number(parentErc20Balance))
- cy.findByLabelText(`${nativeTokenSymbol} balance amount on childChain`)
- .invoke('text')
- .then(parseFloat)
- .should(
- 'be.gt',
+ cy.findByLabelText(
+ `${ERC20TokenSymbol} balance amount on childChain`
+ ).should($el => {
+ const currentBalance = parseFloat($el.text())
+ expect(currentBalance).to.be.gt(Number(parentErc20Balance))
+ })
+
+ cy.findByLabelText(
+ `${nativeTokenSymbol} balance amount on childChain`
+ ).should($el => {
+ const currentBalance = parseFloat($el.text())
+ expect(currentBalance).to.be.gt(
Number(parentNativeTokenBalance) + nativeCurrencyAmountToSend
)
+ })
// the balance on the source chain should not be the same as before
- cy.findByLabelText(`${ERC20TokenSymbol} balance amount on parentChain`)
- .invoke('text')
- .then(parseFloat)
- .should('be.lt', Number(parentErc20Balance))
+ cy.findByLabelText(
+ `${ERC20TokenSymbol} balance amount on parentChain`
+ ).should($el => {
+ const currentBalance = parseFloat($el.text())
+ expect(currentBalance).to.be.lt(Number(parentErc20Balance))
+ })
})
context('transfer panel amount should be reset', () => {
@@ -236,7 +238,7 @@ describe('Batch Deposit', () => {
}
context('should deposit successfully', () => {
- cy.startTransfer()
+ cy.clickMoveFundsButton()
cy.findTransactionInTransactionHistory({
...txData,
duration: depositTime
@@ -251,11 +253,7 @@ describe('Batch Deposit', () => {
context('deposit should complete successfully', () => {
cy.selectTransactionsPanelTab('settled')
- cy.waitUntil(() => cy.findTransactionInTransactionHistory(txData), {
- errorMsg: 'Could not find settled ERC20 Batch Deposit transaction',
- timeout: 60_000,
- interval: 500
- })
+ cy.findTransactionInTransactionHistory(txData)
cy.findTransactionInTransactionHistory({
duration: 'a few seconds ago',
@@ -266,7 +264,7 @@ describe('Batch Deposit', () => {
Cypress.env('CUSTOM_DESTINATION_ADDRESS')
)
cy.closeTransactionDetails()
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
})
context('transfer panel amount should be reset', () => {
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/depositCctp.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/depositCctp.cy.ts
index f655a787ce..ff663af7a0 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/depositCctp.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/depositCctp.cy.ts
@@ -86,7 +86,7 @@ describe('Deposit USDC through CCTP', () => {
})
it('should initiate depositing USDC to the same address through CCTP successfully', () => {
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton().click()
confirmAndApproveCctpDeposit()
cy.confirmSpending(USDCAmountToSend.toString())
@@ -113,7 +113,6 @@ describe('Deposit USDC through CCTP', () => {
it('should claim deposit', () => {
cy.claimCctp(0.00014, { accept: false })
- cy.closeTransactionHistoryPanel()
cy.claimCctp(0.00015, { accept: false })
})
@@ -123,7 +122,7 @@ describe('Deposit USDC through CCTP', () => {
*/
it.skip('should initiate depositing USDC to custom destination address through CCTP successfully', () => {
cy.fillCustomDestinationAddress()
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton().click()
confirmAndApproveCctpDeposit()
cy.confirmSpending(USDCAmountToSend.toString())
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/depositERC20.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/depositERC20.cy.ts
index 27894707c3..7deaf23462 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/depositERC20.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/depositERC20.cy.ts
@@ -89,7 +89,7 @@ describe('Deposit Token', () => {
})
context('should deposit successfully', () => {
- cy.startTransfer()
+ cy.clickMoveFundsButton()
cy.findTransactionInTransactionHistory({
duration: depositTime,
amount: ERC20AmountToSend,
@@ -98,7 +98,7 @@ describe('Deposit Token', () => {
})
context('transfer panel amount should be reset', () => {
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.findAmountInput().should('have.value', '')
cy.findMoveFundsButton().should('be.disabled')
})
@@ -130,7 +130,7 @@ describe('Deposit Token', () => {
})
context('should deposit successfully', () => {
- cy.startTransfer()
+ cy.clickMoveFundsButton()
const txData = {
amount: ERC20AmountToSend,
symbol: testCase.symbol
@@ -150,20 +150,11 @@ describe('Deposit Token', () => {
// switch to settled transactions
cy.selectTransactionsPanelTab('settled')
- //wait for some time for tx to go through and find the new amount in settled transactions
- cy.waitUntil(
- () =>
- cy.findTransactionInTransactionHistory({
- duration: 'a few seconds ago',
- amount: ERC20AmountToSend,
- symbol: testCase.symbol
- }),
- {
- errorMsg: 'Could not find settled ERC20 Deposit transaction',
- timeout: 60_000,
- interval: 500
- }
- )
+ cy.findTransactionInTransactionHistory({
+ duration: 'a few seconds ago',
+ amount: ERC20AmountToSend,
+ symbol: testCase.symbol
+ })
// open the tx details popup
const txData = {
amount: ERC20AmountToSend,
@@ -182,7 +173,7 @@ describe('Deposit Token', () => {
context('funds should reach destination account successfully', () => {
// close transaction history
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
// the custom destination address should now have some balance greater than zero
cy.findByLabelText(`${testCase.symbol} balance amount on childChain`)
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/depositNativeToken.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/depositNativeToken.cy.ts
index 7a57a14504..65afe0f894 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/depositNativeToken.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/depositNativeToken.cy.ts
@@ -31,13 +31,13 @@ describe('Deposit native token', () => {
cy.findGasFeeSummary(zeroToLessThanOneEth)
cy.findGasFeeForChain(getL1NetworkName(), zeroToLessThanOneEth)
cy.findGasFeeForChain(getL2NetworkName(), zeroToLessThanOneNativeToken)
- cy.startTransfer()
+ cy.clickMoveFundsButton()
cy.findTransactionInTransactionHistory({
duration: depositTime,
amount: ETHAmountToDeposit,
symbol: nativeTokenSymbol
})
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.findAmountInput().should('have.value', '')
cy.findMoveFundsButton().should('be.disabled')
})
@@ -53,7 +53,7 @@ describe('Deposit native token', () => {
cy.findGasFeeSummary(zeroToLessThanOneEth)
cy.findGasFeeForChain(getL1NetworkName(), zeroToLessThanOneEth)
cy.findGasFeeForChain(getL2NetworkName(), zeroToLessThanOneNativeToken)
- cy.startTransfer()
+ cy.clickMoveFundsButton()
const txData = {
amount: ETHAmountToDeposit,
@@ -75,7 +75,7 @@ describe('Deposit native token', () => {
)
cy.closeTransactionDetails()
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.findAmountInput().should('have.value', '')
cy.findMoveFundsButton().should('be.disabled')
})
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/readClassicDeposits.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/readClassicDeposits.cy.ts
index 727778240c..fc06ea750a 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/readClassicDeposits.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/readClassicDeposits.cy.ts
@@ -46,11 +46,8 @@ describe('Read classic deposit messages', () => {
context('User has classic native token deposit transaction', () => {
it('can read successful native token deposit', () => {
- // log in to metamask
- cy.login({
- networkType: 'parentChain',
- networkName: 'mainnet'
- })
+ cy.visit('/')
+
window.localStorage.setItem(
`arbitrum:bridge:deposits-${Cypress.env('ADDRESS').toLowerCase()}`,
JSON.stringify([
@@ -61,7 +58,13 @@ describe('Read classic deposit messages', () => {
])
)
- cy.openTransactionsPanel('settled')
+ // log in to metamask
+ cy.login({
+ networkType: 'parentChain',
+ networkName: 'mainnet'
+ })
+
+ cy.switchToTransactionHistoryTab('settled')
const destinationTxHash =
'0xd3ff2a70a115411e1ae4917351dca49281368684394d0dcac136fa08d9d9b436'
@@ -75,11 +78,8 @@ describe('Read classic deposit messages', () => {
context('User has classic ERC-20 deposit transaction', () => {
it('can read successful ERC-20 deposit', () => {
- // log in to metamask
- cy.login({
- networkType: 'parentChain',
- networkName: 'mainnet'
- })
+ cy.visit('/')
+
window.localStorage.setItem(
`arbitrum:bridge:deposits-${Cypress.env('ADDRESS').toLowerCase()}`,
JSON.stringify([
@@ -92,7 +92,13 @@ describe('Read classic deposit messages', () => {
])
)
- cy.openTransactionsPanel('settled')
+ // log in to metamask
+ cy.login({
+ networkType: 'parentChain',
+ networkName: 'mainnet'
+ })
+
+ cy.switchToTransactionHistoryTab('settled')
const destinationTxHash =
'0x6cecd3bfc3ec73181c4ac0253d3f51e5aa8d26157ca7439ff9ab465de14a436f'
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/redeemRetryable.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/redeemRetryable.cy.ts
index 4aea7f5971..0473ee9391 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/redeemRetryable.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/redeemRetryable.cy.ts
@@ -69,7 +69,10 @@ describe('Redeem ERC20 Deposit', () => {
context('deposit should be redeemed', () => {
// open transaction history and wait for deposit to fetch data
- cy.openTransactionsPanel('pending')
+ cy.switchToTransactionHistoryTab('pending')
+
+ // give ci more time to fetch the transactions
+ cy.wait(15_000)
// find the Retry button and the amount in the row
cy.findTransactionInTransactionHistory({
@@ -94,7 +97,7 @@ describe('Redeem ERC20 Deposit', () => {
symbol: 'WETH'
})
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
// wait for the destination balance to update
cy.wait(5_000)
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/txHistory.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/txHistory.cy.ts
index c9f1c0c53a..e1608e2962 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/txHistory.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/txHistory.cy.ts
@@ -13,7 +13,7 @@ describe('Transaction History', () => {
})
// open tx history panel
context('open transactions history panel', () => {
- cy.openTransactionsPanel('pending')
+ cy.switchToTransactionHistoryTab('pending')
cy.findAllByTestId(CLAIMABLE_ROW_IDENTIFIER)
.its('length')
.should('be.gt', 0)
@@ -30,7 +30,7 @@ describe('Transaction History', () => {
}
})
context('open transactions history panel', () => {
- cy.openTransactionsPanel('settled')
+ cy.switchToTransactionHistoryTab('settled')
cy.findAllByTestId(CLAIMABLE_ROW_IDENTIFIER)
.its('length')
.should('be.gt', 0)
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawCctp.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawCctp.cy.ts
index e1e062f1c4..15591ee460 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawCctp.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawCctp.cy.ts
@@ -72,7 +72,7 @@ describe('Withdraw USDC through CCTP', () => {
'be.visible'
)
cy.findGasFeeForChain(/You'll have to pay Sepolia gas fee upon claiming./i)
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton().click()
confirmAndApproveCctpWithdrawal()
cy.confirmSpending(USDCAmountToSend.toString())
@@ -97,7 +97,6 @@ describe('Withdraw USDC through CCTP', () => {
it('should claim deposit', () => {
cy.changeMetamaskNetwork('sepolia')
cy.claimCctp(0.00012, { accept: true })
- cy.closeTransactionHistoryPanel()
cy.claimCctp(0.00013, { accept: true })
})
@@ -110,7 +109,7 @@ describe('Withdraw USDC through CCTP', () => {
)
cy.findGasFeeForChain(/You'll have to pay Sepolia gas fee upon claiming./i)
cy.fillCustomDestinationAddress()
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton().click()
confirmAndApproveCctpWithdrawal()
cy.confirmSpending(USDCAmountToSend.toString())
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawERC20.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawERC20.cy.ts
index bbc0ff696f..5355a5fa71 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawERC20.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawERC20.cy.ts
@@ -103,7 +103,7 @@ describe('Withdraw ERC20 Token', () => {
})
context('should show clickable withdraw button', () => {
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton({ shouldConfirmInMetamask: false })
})
context('should withdraw successfully', () => {
@@ -142,7 +142,7 @@ describe('Withdraw ERC20 Token', () => {
})
context('transfer panel amount should be reset', () => {
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.findAmountInput().should('have.value', '')
cy.findMoveFundsButton().should('be.disabled')
})
@@ -153,9 +153,7 @@ describe('Withdraw ERC20 Token', () => {
cy.login({ networkType: 'parentChain' }) // login to L1 to claim the funds (otherwise would need to change network after clicking on claim)
- cy.findByLabelText('Open Transaction History')
- .should('be.visible')
- .click()
+ cy.switchToTransactionHistoryTab('pending')
cy.findClaimButton(
formatAmount(ERC20AmountToSend, {
@@ -175,7 +173,7 @@ describe('Withdraw ERC20 Token', () => {
})}`
).should('be.visible')
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.searchAndSelectToken({
tokenName: testCase.symbol,
@@ -220,7 +218,7 @@ describe('Withdraw ERC20 Token', () => {
})
context('should show clickable withdraw button', () => {
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton({ shouldConfirmInMetamask: false })
})
context('should initiate withdrawal successfully', () => {
@@ -265,7 +263,7 @@ describe('Withdraw ERC20 Token', () => {
// close popup
cy.closeTransactionDetails()
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
// the balance on the source chain should not be the same as before
cy.findByLabelText(`${testCase.symbol} balance amount on childChain`)
diff --git a/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawNativeToken.cy.ts b/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawNativeToken.cy.ts
index 6bb2fd751d..21259a3d93 100644
--- a/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawNativeToken.cy.ts
+++ b/packages/arb-token-bridge-ui/tests/e2e/specs/withdrawNativeToken.cy.ts
@@ -61,7 +61,7 @@ describe('Withdraw native token', () => {
ETHToWithdraw = Number((Math.random() * 0.001).toFixed(5)) // generate a new withdrawal amount for each test-run attempt so that findAllByText doesn't stall coz of prev transactions
cy.login({ networkType: 'childChain' })
cy.typeAmount(ETHToWithdraw)
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton({ shouldConfirmInMetamask: false })
cy.findByText(/Arbitrum’s bridge/i).should('be.visible')
// the Continue withdrawal button should be disabled at first
@@ -96,7 +96,7 @@ describe('Withdraw native token', () => {
})
context('transfer panel amount should be reset', () => {
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.findAmountInput().should('have.value', '')
cy.findMoveFundsButton().should('be.disabled')
})
@@ -106,9 +106,7 @@ describe('Withdraw native token', () => {
// increase the timeout for this test as claim button can take ~(20 blocks *10 blocks/sec) to activate
cy.login({ networkType: 'parentChain' }) // login to L1 to claim the funds (otherwise would need to change network after clicking on claim)
- cy.findByLabelText('Open Transaction History')
- .should('be.visible')
- .click()
+ cy.switchToTransactionHistoryTab('pending')
cy.findClaimButton(
formatAmount(ETHToWithdraw, {
@@ -128,7 +126,7 @@ describe('Withdraw native token', () => {
})}`
).should('be.visible')
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
// the balance on the destination chain should not be the same as before
cy.findByLabelText(
@@ -148,7 +146,7 @@ describe('Withdraw native token', () => {
cy.typeAmount(ETHToWithdraw)
cy.fillCustomDestinationAddress()
- cy.findMoveFundsButton().click()
+ cy.clickMoveFundsButton({ shouldConfirmInMetamask: false })
cy.findByText(/Arbitrum’s bridge/i).should('be.visible')
// the Continue withdrawal button should be disabled at first
@@ -194,7 +192,7 @@ describe('Withdraw native token', () => {
cy.closeTransactionDetails()
context('transfer panel amount should be reset', () => {
- cy.closeTransactionHistoryPanel()
+ cy.switchToTransferPanelTab()
cy.findAmountInput().should('have.value', '')
cy.findMoveFundsButton().should('be.disabled')
})
diff --git a/packages/arb-token-bridge-ui/tests/support/commands.ts b/packages/arb-token-bridge-ui/tests/support/commands.ts
index 7010ca34d3..64f4367fbe 100644
--- a/packages/arb-token-bridge-ui/tests/support/commands.ts
+++ b/packages/arb-token-bridge-ui/tests/support/commands.ts
@@ -108,31 +108,6 @@ export const selectTransactionsPanelTab = (tab: 'pending' | 'settled') => {
.and('equal', 'selected')
}
-export const openTransactionsPanel = (tab: 'pending' | 'settled') => {
- cy.log(`opening transactions panel on ${tab}`)
- cy.findByRole('button', { name: /account header button/i })
- .should('be.visible')
- .click()
- cy.findByRole('button', { name: /transactions/i })
- .should('be.visible')
- .click()
-
- cy.selectTransactionsPanelTab(tab)
-
- // Waiting for transactions to be fetched
- return cy.waitUntil(
- () =>
- cy
- .findByText(/Showing \d+ \w+ transactions made in/)
- .should('be.visible'),
- {
- errorMsg: 'Failed to fetch transactions.',
- timeout: 120_000,
- interval: 500
- }
- )
-}
-
export const searchAndSelectToken = ({
tokenName,
tokenAddress
@@ -247,11 +222,17 @@ export function findMoveFundsButton(): Cypress.Chainable> {
.should('be.visible')
}
-export function startTransfer() {
+export function clickMoveFundsButton({
+ shouldConfirmInMetamask = true
+}: {
+ shouldConfirmInMetamask?: boolean
+} = {}) {
cy.wait(5_000)
cy.findMoveFundsButton().click()
cy.wait(15_000)
- cy.confirmMetamaskTransaction()
+ if (shouldConfirmInMetamask) {
+ cy.confirmMetamaskTransaction()
+ }
}
export function findSelectTokenButton(
@@ -263,8 +244,20 @@ export function findSelectTokenButton(
.should('have.text', text)
}
-export function closeTransactionHistoryPanel() {
- cy.findByLabelText('Close side panel').click()
+export function switchToTransferPanelTab() {
+ return cy.findByLabelText('Switch to Bridge Tab').click()
+}
+
+export function switchToTransactionHistoryTab(tab: 'pending' | 'settled') {
+ cy.log(`opening transactions panel on ${tab}`)
+
+ cy.findByLabelText('Switch to Transaction History Tab').click()
+
+ cy.selectTransactionsPanelTab(tab)
+
+ cy.findByText(/Showing \d+ \w+ transactions made in/, {
+ timeout: 120_000
+ }).should('be.visible')
}
export function openTransactionDetails({
@@ -317,6 +310,8 @@ export function findTransactionInTransactionHistory({
amount2?: number
duration?: string
}) {
+ const timeout = 120_000
+
// Replace . with \.
const parsedAmount = amount.toString().replace(/\./g, '\\.')
@@ -326,15 +321,18 @@ export function findTransactionInTransactionHistory({
}`
)
- cy.findByTestId(rowId).as('row')
+ cy.findByTestId(rowId, { timeout }).as('row')
if (duration) {
- cy.get('@row').findAllByText(duration).first().should('be.visible')
+ cy.get('@row', { timeout })
+ .findAllByText(duration, { timeout })
+ .first()
+ .should('be.visible', { timeout })
}
- cy.get('@row')
- .findByLabelText('Transaction details button')
- .should('be.visible')
- return cy.get('@row')
+ cy.get('@row', { timeout })
+ .findByLabelText('Transaction details button', { timeout })
+ .should('be.visible', { timeout })
+ return cy.get('@row', { timeout })
}
export function findClaimButton(
@@ -372,7 +370,7 @@ export function claimCctp(amount: number, options: { accept: boolean }) {
const formattedAmount = formatAmount(amount, {
symbol: 'USDC'
})
- cy.openTransactionsPanel('pending')
+ cy.switchToTransactionHistoryTab('pending')
cy.findTransactionInTransactionHistory({
amount,
symbol: 'USDC'
@@ -391,7 +389,6 @@ Cypress.Commands.addAll({
connectToApp,
login,
logout,
- openTransactionsPanel,
selectTransactionsPanelTab,
searchAndSelectToken,
fillCustomDestinationAddress,
@@ -404,9 +401,10 @@ Cypress.Commands.addAll({
findGasFeeForChain,
findGasFeeSummary,
findMoveFundsButton,
- startTransfer,
+ clickMoveFundsButton,
findSelectTokenButton,
- closeTransactionHistoryPanel,
+ switchToTransferPanelTab,
+ switchToTransactionHistoryTab,
openTransactionDetails,
closeTransactionDetails,
findTransactionInTransactionHistory,
diff --git a/packages/scripts/package.json b/packages/scripts/package.json
index 13cb924a31..9e7591a891 100644
--- a/packages/scripts/package.json
+++ b/packages/scripts/package.json
@@ -17,7 +17,7 @@
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/github": "^6.0.0",
- "@arbitrum/sdk": "^4.0.1",
+ "@arbitrum/sdk": "^4.0.2",
"@octokit/rest": "^21.0.2",
"axios": "^1.7.7",
"commander": "^12.1.0",
diff --git a/packages/scripts/src/addOrbitChain/provider.ts b/packages/scripts/src/addOrbitChain/provider.ts
index c29faa0d4f..d7287dedb7 100644
--- a/packages/scripts/src/addOrbitChain/provider.ts
+++ b/packages/scripts/src/addOrbitChain/provider.ts
@@ -6,13 +6,21 @@ export const getProvider = (chainInfo: {
name: string;
chainId: number;
}) => {
+ const THROTTLE_LIMIT = 10;
+
const connection: ConnectionInfo = {
url: chainInfo.rpcUrl,
- timeout: 30000,
+ timeout: 300000,
allowGzip: true,
skipFetchSetup: true,
- throttleLimit: 3,
- throttleSlotInterval: 1000,
+ throttleLimit: THROTTLE_LIMIT,
+ throttleSlotInterval: 3000,
+ throttleCallback: async (attempt: number) => {
+ // Always retry until we hit the THROTTLE_LIMIT
+ // Otherwise, it only throttles for specific response codes
+ // Return true to continue retrying, false to stop
+ return attempt <= THROTTLE_LIMIT;
+ },
headers: {
Accept: "*/*",
"Accept-Encoding": "gzip, deflate, br",
diff --git a/packages/scripts/src/addOrbitChain/schemas.ts b/packages/scripts/src/addOrbitChain/schemas.ts
index 532e8a1d6e..f18adf2c69 100644
--- a/packages/scripts/src/addOrbitChain/schemas.ts
+++ b/packages/scripts/src/addOrbitChain/schemas.ts
@@ -36,6 +36,13 @@ export const getParentChainInfo = (parentChainId: number) => {
chainId: 42161,
name: "Arbitrum One",
};
+ case 42170: // Arbitrum Nova
+ return {
+ rpcUrl: "https://nova.arbitrum.io/rpc",
+ blockExplorer: "https://nova.arbiscan.io",
+ chainId: 42170,
+ name: "Arbitrum Nova",
+ };
case 11155111: // Sepolia
return {
rpcUrl: INFURA_KEY
diff --git a/yarn.lock b/yarn.lock
index c1346b3d9a..23414ead7c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -78,17 +78,6 @@
tslib "^2.3.0"
zen-observable-ts "^1.2.5"
-"@arbitrum/sdk@^4.0.1":
- version "4.0.1"
- resolved "https://registry.npmjs.org/@arbitrum/sdk/-/sdk-4.0.1.tgz"
- integrity sha512-uW0Pe/oICbmlHpIpYOaHHWsNQRG+3UbCa3s0SJsp2O1Kt9b0M0CX/fEdFOFLyAi3OxHonNEfzhfvQrALy9C3Yw==
- dependencies:
- "@ethersproject/address" "^5.0.8"
- "@ethersproject/bignumber" "^5.1.1"
- "@ethersproject/bytes" "^5.0.8"
- async-mutex "^0.4.0"
- ethers "^5.1.0"
-
"@arbitrum/sdk@^4.0.2":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@arbitrum/sdk/-/sdk-4.0.2.tgz#23555858f49e2b237b94a65bd486c65edb7b1690"
@@ -428,13 +417,6 @@
dependencies:
regenerator-runtime "^0.13.11"
-"@babel/runtime@^7.23.1":
- version "7.23.4"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz"
- integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==
- dependencies:
- regenerator-runtime "^0.14.0"
-
"@babel/runtime@^7.23.2":
version "7.23.5"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz"
@@ -1184,12 +1166,12 @@
resolved "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz"
integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==
-"@hapi/hoek@^9.0.0":
+"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
version "9.3.0"
resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz"
integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==
-"@hapi/topo@^5.0.0":
+"@hapi/topo@^5.0.0", "@hapi/topo@^5.1.0":
version "5.1.0"
resolved "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz"
integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==
@@ -1651,7 +1633,7 @@
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
-"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0":
version "1.5.0"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
@@ -1786,10 +1768,10 @@
"@motionone/dom" "^10.16.2"
tslib "^2.3.1"
-"@next/env@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.14.tgz#08f5175dab727102da02301ba61f7239773670fa"
- integrity sha512-/0hWQfiaD5//LvGNgc8PjvyqV50vGK0cADYzaoOOGN8fxzBn3iAiaq3S0tCRnFBldq0LVveLcxCTi41ZoYgAgg==
+"@next/env@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.22.tgz#8898ae47595badbfacebfc1585f42a4e06a97301"
+ integrity sha512-EQ6y1QeNQglNmNIXvwP/Bb+lf7n9WtgcWvtoFsHquVLCJUuxRs+6SfZ5EK0/EqkkLex4RrDySvKgKNN7PXip7Q==
"@next/eslint-plugin-next@14.2.5":
version "14.2.5"
@@ -1805,50 +1787,50 @@
dependencies:
glob "7.1.7"
-"@next/swc-darwin-arm64@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.14.tgz#6dde2dac699dfe948b527385f2b350b3151989f4"
- integrity sha512-bsxbSAUodM1cjYeA4o6y7sp9wslvwjSkWw57t8DtC8Zig8aG8V6r+Yc05/9mDzLKcybb6EN85k1rJDnMKBd9Gw==
-
-"@next/swc-darwin-x64@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.14.tgz#25800213c4dc0f8cd765c88073d28a3144698e31"
- integrity sha512-cC9/I+0+SK5L1k9J8CInahduTVWGMXhQoXFeNvF0uNs3Bt1Ub0Azb8JzTU9vNCr0hnaMqiWu/Z0S1hfKc3+dww==
-
-"@next/swc-linux-arm64-gnu@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.14.tgz#9c66bd1287d0c3633e7bf354f9c01e1b79747615"
- integrity sha512-RMLOdA2NU4O7w1PQ3Z9ft3PxD6Htl4uB2TJpocm+4jcllHySPkFaUIFacQ3Jekcg6w+LBaFvjSPthZHiPmiAUg==
-
-"@next/swc-linux-arm64-musl@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.14.tgz#da2ae16a24bb2b2a46447154e95da85c557ab09a"
- integrity sha512-WgLOA4hT9EIP7jhlkPnvz49iSOMdZgDJVvbpb8WWzJv5wBD07M2wdJXLkDYIpZmCFfo/wPqFsFR4JS4V9KkQ2A==
-
-"@next/swc-linux-x64-gnu@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.14.tgz#635c62109b9cf0464e6322955a36931ebb9ed3e2"
- integrity sha512-lbn7svjUps1kmCettV/R9oAvEW+eUI0lo0LJNFOXoQM5NGNxloAyFRNByYeZKL3+1bF5YE0h0irIJfzXBq9Y6w==
-
-"@next/swc-linux-x64-musl@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.14.tgz#1565caf6fa77c3280d8b05ffc8c542ff144a4855"
- integrity sha512-7TcQCvLQ/hKfQRgjxMN4TZ2BRB0P7HwrGAYL+p+m3u3XcKTraUFerVbV3jkNZNwDeQDa8zdxkKkw2els/S5onQ==
-
-"@next/swc-win32-arm64-msvc@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.14.tgz#8df4feb3c9280155e9299f3cdfa32f3cface336a"
- integrity sha512-8i0Ou5XjTLEje0oj0JiI0Xo9L/93ghFtAUYZ24jARSeTMXLUx8yFIdhS55mTExq5Tj4/dC2fJuaT4e3ySvXU1A==
-
-"@next/swc-win32-ia32-msvc@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.14.tgz#1f0a2bafbb63147c8db102ca1524db9ffa959d0c"
- integrity sha512-2u2XcSaDEOj+96eXpyjHjtVPLhkAFw2nlaz83EPeuK4obF+HmtDJHqgR1dZB7Gb6V/d55FL26/lYVd0TwMgcOQ==
-
-"@next/swc-win32-x64-msvc@14.2.14":
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.14.tgz#9d6446b3a8d5e67e199049d59ce7c0b8bd33ab51"
- integrity sha512-MZom+OvZ1NZxuRovKt1ApevjiUJTcU2PmdJKL66xUPaJeRywnbGGRWUlaAOwunD6dX+pm83vj979NTC8QXjGWg==
+"@next/swc-darwin-arm64@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.22.tgz#2b3fcb42247ba951b19a48fc03f1d6fe65629baa"
+ integrity sha512-HUaLiehovgnqY4TMBZJ3pDaOsTE1spIXeR10pWgdQVPYqDGQmHJBj3h3V6yC0uuo/RoY2GC0YBFRkOX3dI9WVQ==
+
+"@next/swc-darwin-x64@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.22.tgz#11ecc609e9530b3edf8ddfd1fd3bd6aca4e1bfda"
+ integrity sha512-ApVDANousaAGrosWvxoGdLT0uvLBUC+srqOcpXuyfglA40cP2LBFaGmBjhgpxYk5z4xmunzqQvcIgXawTzo2uQ==
+
+"@next/swc-linux-arm64-gnu@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.22.tgz#4c08dd223e50c348f561af2285e27fb326ffabbf"
+ integrity sha512-3O2J99Bk9aM+d4CGn9eEayJXHuH9QLx0BctvWyuUGtJ3/mH6lkfAPRI4FidmHMBQBB4UcvLMfNf8vF0NZT7iKw==
+
+"@next/swc-linux-arm64-musl@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.22.tgz#0b285336f145887d421b3762f3d7c75f847ec1b3"
+ integrity sha512-H/hqfRz75yy60y5Eg7DxYfbmHMjv60Dsa6IWHzpJSz4MRkZNy5eDnEW9wyts9bkxwbOVZNPHeb3NkqanP+nGPg==
+
+"@next/swc-linux-x64-gnu@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.22.tgz#a936b6cfea0364571102f0389c6368d6acf3e294"
+ integrity sha512-LckLwlCLcGR1hlI5eiJymR8zSHPsuruuwaZ3H2uudr25+Dpzo6cRFjp/3OR5UYJt8LSwlXv9mmY4oI2QynwpqQ==
+
+"@next/swc-linux-x64-musl@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.22.tgz#0359497840d0b7d8c095d0d9735bc6aec68cef5d"
+ integrity sha512-qGUutzmh0PoFU0fCSu0XYpOfT7ydBZgDfcETIeft46abPqP+dmePhwRGLhFKwZWxNWQCPprH26TjaTxM0Nv8mw==
+
+"@next/swc-win32-arm64-msvc@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.22.tgz#9fd249d49ffccf3388400ab24472c432cdd04c24"
+ integrity sha512-K6MwucMWmIvMb9GlvT0haYsfIPxfQD8yXqxwFy4uLFMeXIb2TcVYQimxkaFZv86I7sn1NOZnpOaVk5eaxThGIw==
+
+"@next/swc-win32-ia32-msvc@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.22.tgz#70d8d5a48e78c7382c3e0544af28c2788ca6b551"
+ integrity sha512-5IhDDTPEbzPR31ZzqHe90LnNe7BlJUZvC4sA1thPJV6oN5WmtWjZ0bOYfNsyZx00FJt7gggNs6SrsX0UEIcIpA==
+
+"@next/swc-win32-x64-msvc@14.2.22":
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.22.tgz#b034f544c1346093a235f6bba46497a1ba344fc1"
+ integrity sha512-nvRaB1PyG4scn9/qNzlkwEwLzuoPH3Gjp7Q/pLuwUgOTt1oPMlnCI3A3rgkt+eZnU71emOiEv/mR201HoURPGg==
"@noble/curves@1.2.0", "@noble/curves@~1.2.0":
version "1.2.0"
@@ -2087,10 +2069,10 @@
dependencies:
"@octokit/openapi-types" "^22.2.0"
-"@offchainlabs/cobalt@^0.3.11":
- version "0.3.11"
- resolved "https://registry.yarnpkg.com/@offchainlabs/cobalt/-/cobalt-0.3.11.tgz#6d6ec1c81bf77f897952cbd33f151e1a7cb596a1"
- integrity sha512-xczC0CkMzAkbIFnvtX8EqKRUq3FPT/7MtP0sXBkbcaHvcgxNYs/fafmvn8/zmQxM+RBOJ/no17UNL4I3Cp9s+w==
+"@offchainlabs/cobalt@^0.3.12":
+ version "0.3.12"
+ resolved "https://registry.yarnpkg.com/@offchainlabs/cobalt/-/cobalt-0.3.12.tgz#f841028f0e698b57adbaa75c2225aec59baef821"
+ integrity sha512-ULbCD0DfxO8xmrPOmHcB4HuW+c81qAdbvXw5it5jMilb2bVjPoE4gtCALbVppkGbcft0P3FgEpKHbtfS7sEfeg==
"@parcel/watcher-android-arm64@2.4.1":
version "2.4.1"
@@ -2470,6 +2452,13 @@
dependencies:
"@hapi/hoek" "^9.0.0"
+"@sideway/address@^4.1.5":
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5"
+ integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==
+ dependencies:
+ "@hapi/hoek" "^9.0.0"
+
"@sideway/formula@^3.0.1":
version "3.0.1"
resolved "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz"
@@ -2801,7 +2790,7 @@
lz-string "^1.5.0"
pretty-format "^27.0.2"
-"@testing-library/react@^14.0.0", "@testing-library/react@^14.2.1":
+"@testing-library/react@^14.0.0":
version "14.2.1"
resolved "https://registry.npmjs.org/@testing-library/react/-/react-14.2.1.tgz"
integrity sha512-sGdjws32ai5TLerhvzThYFbpnF9XtL65Cjf+gB0Dhr29BGqK+mAeN7SURSdu+eqgET4ANcWoC7FQpkaiGvBr+A==
@@ -2810,6 +2799,13 @@
"@testing-library/dom" "^9.0.0"
"@types/react-dom" "^18.0.0"
+"@testing-library/react@^16.1.0":
+ version "16.1.0"
+ resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-16.1.0.tgz#aa0c61398bac82eaf89776967e97de41ac742d71"
+ integrity sha512-Q2ToPvg0KsVL0ohND9A3zLJWcOXXcO8IDu3fj11KhNt0UlCWyFyvnCIBkd12tidB2lkiVRG8VFqdhcqhqnAQtg==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+
"@tippyjs/react@^4.2.6":
version "4.2.6"
resolved "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz"
@@ -5311,12 +5307,7 @@ camelize@^1.0.0:
resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz"
integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==
-caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503:
- version "1.0.30001503"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz"
- integrity sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==
-
-caniuse-lite@^1.0.30001579:
+caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503, caniuse-lite@^1.0.30001579:
version "1.0.30001643"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz"
integrity sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==
@@ -5782,6 +5773,11 @@ core-js@^2.4.0:
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
+core-js@^3.38.1:
+ version "3.39.0"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83"
+ integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==
+
core-js@^3.6.4:
version "3.31.0"
resolved "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz"
@@ -5843,6 +5839,11 @@ css-color-keywords@^1.0.0:
resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz"
integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==
+css-gradient-parser@^0.0.16:
+ version "0.0.16"
+ resolved "https://registry.yarnpkg.com/css-gradient-parser/-/css-gradient-parser-0.0.16.tgz#5735da0822aef39da9b1960b314792ab542d9bb5"
+ integrity sha512-3O5QdqgFRUbXvK1x5INf1YkBz1UKSWqrd63vWsum8MNHDBYD5urm3QtxZbKU259OrEXNM26lP/MPY3d1IGkBgA==
+
css-in-js-utils@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz"
@@ -5921,10 +5922,10 @@ cssstyle@^2.3.0:
dependencies:
cssom "~0.3.6"
-csstype@^3.0.2, csstype@^3.0.6, csstype@^3.0.7:
- version "3.1.2"
- resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
- integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
+csstype@^3.0.2, csstype@^3.0.7, csstype@^3.1.2:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+ integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
cypress-terminal-report@^5.3.10:
version "5.3.10"
@@ -6016,10 +6017,10 @@ dayjs@1.11.12:
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz"
integrity sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==
-dayjs@^1.10.4, dayjs@^1.11.8:
- version "1.11.8"
- resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz"
- integrity sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ==
+dayjs@^1.10.4, dayjs@^1.11.13:
+ version "1.11.13"
+ resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
+ integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
debug@2.6.9:
version "2.6.9"
@@ -6028,12 +6029,12 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
-debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
- version "4.3.4"
- resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
- integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+debug@4, debug@4.4.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
+ integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
- ms "2.1.2"
+ ms "^2.1.3"
debug@4.3.5:
version "4.3.5"
@@ -7556,6 +7557,11 @@ expect@^29.0.0, expect@^29.5.0:
jest-message-util "^29.5.0"
jest-util "^29.5.0"
+exponential-backoff@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
+ integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==
+
express@^4.17.3:
version "4.21.0"
resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915"
@@ -7665,6 +7671,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9:
merge2 "^1.3.0"
micromatch "^4.0.4"
+fast-glob@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
+ integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
@@ -7675,11 +7692,6 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
-fast-loops@^1.1.3:
- version "1.1.4"
- resolved "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.4.tgz"
- integrity sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==
-
fast-redact@^3.0.0:
version "3.2.0"
resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz"
@@ -8287,18 +8299,6 @@ glob@10.3.10:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry "^1.10.1"
-glob@7.1.6:
- version "7.1.6"
- resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
- integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
glob@7.1.7:
version "7.1.7"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz"
@@ -8311,6 +8311,18 @@ glob@7.1.7:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^10.3.10:
+ version "10.4.5"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
+ integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
+ dependencies:
+ foreground-child "^3.1.0"
+ jackspeak "^3.1.2"
+ minimatch "^9.0.4"
+ minipass "^7.1.2"
+ package-json-from-dist "^1.0.0"
+ path-scurry "^1.11.1"
+
glob@^7.0.3, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
@@ -8435,10 +8447,10 @@ graphql-tag@^2.12.6:
dependencies:
tslib "^2.1.0"
-graphql@^16.8.1:
- version "16.8.1"
- resolved "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz"
- integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==
+graphql@^16.9.0:
+ version "16.9.0"
+ resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f"
+ integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==
h3@^1.10.2, h3@^1.11.1:
version "1.11.1"
@@ -8912,13 +8924,12 @@ ini@~1.3.0:
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-inline-style-prefixer@^6.0.0:
- version "6.0.4"
- resolved "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz"
- integrity sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==
+inline-style-prefixer@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz#9310f3cfa2c6f3901d1480f373981c02691781e8"
+ integrity sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==
dependencies:
css-in-js-utils "^3.1.0"
- fast-loops "^1.1.3"
internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5:
version "1.0.5"
@@ -9495,6 +9506,15 @@ jackspeak@^2.3.5:
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"
+jackspeak@^3.1.2:
+ version "3.4.3"
+ resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
+ integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
+ dependencies:
+ "@isaacs/cliui" "^8.0.2"
+ optionalDependencies:
+ "@pkgjs/parseargs" "^0.11.0"
+
jayson@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz"
@@ -9888,12 +9908,7 @@ jest@^29.4.0:
import-local "^3.0.2"
jest-cli "^29.5.0"
-jiti@^1.18.2:
- version "1.18.2"
- resolved "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz"
- integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==
-
-jiti@^1.21.0:
+jiti@^1.21.0, jiti@^1.21.6:
version "1.21.6"
resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz"
integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
@@ -9903,6 +9918,17 @@ jju@^1.4.0:
resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz"
integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
+joi@^17.13.3:
+ version "17.13.3"
+ resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec"
+ integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==
+ dependencies:
+ "@hapi/hoek" "^9.3.0"
+ "@hapi/topo" "^5.1.0"
+ "@sideway/address" "^4.1.5"
+ "@sideway/formula" "^3.0.1"
+ "@sideway/pinpoint" "^2.0.0"
+
joi@^17.7.0:
version "17.9.2"
resolved "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz"
@@ -10201,10 +10227,10 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-lilconfig@^2.0.5, lilconfig@^2.1.0:
- version "2.1.0"
- resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz"
- integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
+lilconfig@^3.0.0, lilconfig@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4"
+ integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==
linebreak@^1.1.0:
version "1.1.0"
@@ -10266,14 +10292,7 @@ lit-element@^3.3.0:
"@lit/reactive-element" "^1.3.0"
lit-html "^2.7.0"
-lit-html@^2.7.0:
- version "2.7.4"
- resolved "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz"
- integrity sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g==
- dependencies:
- "@types/trusted-types" "^2.0.2"
-
-lit-html@^2.8.0:
+lit-html@^2.7.0, lit-html@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.8.0.tgz#96456a4bb4ee717b9a7d2f94562a16509d39bffa"
integrity sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==
@@ -10581,7 +10600,7 @@ methods@~1.1.2:
resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
-micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
+micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8:
version "4.0.8"
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
@@ -10655,7 +10674,7 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
-minimatch@^9.0.1:
+minimatch@^9.0.1, minimatch@^9.0.4:
version "9.0.5"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
@@ -10667,7 +10686,7 @@ minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6, minimist@^1.2.7, minimist@^1.
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-"minipass@^5.0.0 || ^6.0.2 || ^7.0.0":
+"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
version "7.1.2"
resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz"
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
@@ -10714,7 +10733,7 @@ ms@2.1.2:
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-ms@2.1.3, ms@^2.0.0, ms@^2.1.1:
+ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -10741,29 +10760,24 @@ mz@^2.7.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
-nano-css@^5.3.1:
- version "5.3.5"
- resolved "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz"
- integrity sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==
+nano-css@^5.6.2:
+ version "5.6.2"
+ resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.6.2.tgz#584884ddd7547278f6d6915b6805069742679a32"
+ integrity sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==
dependencies:
+ "@jridgewell/sourcemap-codec" "^1.4.15"
css-tree "^1.1.2"
- csstype "^3.0.6"
+ csstype "^3.1.2"
fastest-stable-stringify "^2.0.2"
- inline-style-prefixer "^6.0.0"
- rtl-css-js "^1.14.0"
- sourcemap-codec "^1.4.8"
+ inline-style-prefixer "^7.0.1"
+ rtl-css-js "^1.16.1"
stacktrace-js "^2.0.2"
- stylis "^4.0.6"
-
-nanoid@^3.3.6:
- version "3.3.6"
- resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz"
- integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
+ stylis "^4.3.0"
-nanoid@^3.3.7:
- version "3.3.7"
- resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"
- integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
+nanoid@^3.3.6, nanoid@^3.3.7:
+ version "3.3.8"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
+ integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
napi-build-utils@^1.0.1:
version "1.0.2"
@@ -10797,12 +10811,12 @@ next-query-params@^5.0.0:
dependencies:
tslib "^2.0.3"
-next@^14.2.12:
- version "14.2.14"
- resolved "https://registry.yarnpkg.com/next/-/next-14.2.14.tgz#115f29443dfb96d23b4b5ab5c4547de339202ba7"
- integrity sha512-Q1coZG17MW0Ly5x76shJ4dkC23woLAhhnDnw+DfTc7EpZSGuWrlsZ3bZaO8t6u1Yu8FVfhkqJE+U8GC7E0GLPQ==
+next@^14.2.21:
+ version "14.2.22"
+ resolved "https://registry.yarnpkg.com/next/-/next-14.2.22.tgz#0cd664916ef4c725f31fa812d870348cffd0115b"
+ integrity sha512-Ps2caobQ9hlEhscLPiPm3J3SYhfwfpMqzsoCMZGWxt9jBRK9hoBZj2A37i8joKhsyth2EuVKDVJCTF5/H4iEDw==
dependencies:
- "@next/env" "14.2.14"
+ "@next/env" "14.2.22"
"@swc/helpers" "0.5.5"
busboy "1.6.0"
caniuse-lite "^1.0.30001579"
@@ -10810,15 +10824,15 @@ next@^14.2.12:
postcss "8.4.31"
styled-jsx "5.1.1"
optionalDependencies:
- "@next/swc-darwin-arm64" "14.2.14"
- "@next/swc-darwin-x64" "14.2.14"
- "@next/swc-linux-arm64-gnu" "14.2.14"
- "@next/swc-linux-arm64-musl" "14.2.14"
- "@next/swc-linux-x64-gnu" "14.2.14"
- "@next/swc-linux-x64-musl" "14.2.14"
- "@next/swc-win32-arm64-msvc" "14.2.14"
- "@next/swc-win32-ia32-msvc" "14.2.14"
- "@next/swc-win32-x64-msvc" "14.2.14"
+ "@next/swc-darwin-arm64" "14.2.22"
+ "@next/swc-darwin-x64" "14.2.22"
+ "@next/swc-linux-arm64-gnu" "14.2.22"
+ "@next/swc-linux-arm64-musl" "14.2.22"
+ "@next/swc-linux-x64-gnu" "14.2.22"
+ "@next/swc-linux-x64-musl" "14.2.22"
+ "@next/swc-win32-arm64-msvc" "14.2.22"
+ "@next/swc-win32-ia32-msvc" "14.2.22"
+ "@next/swc-win32-x64-msvc" "14.2.22"
no-case@^3.0.4:
version "3.0.4"
@@ -11361,6 +11375,11 @@ package-hash@^4.0.0:
lodash.flattendeep "^4.4.0"
release-zalgo "^1.0.0"
+package-json-from-dist@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
+ integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
+
pako@^0.2.5:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
@@ -11495,7 +11514,7 @@ path-parse@^1.0.7:
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
-path-scurry@^1.10.1:
+path-scurry@^1.10.1, path-scurry@^1.11.1:
version "1.11.1"
resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz"
integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
@@ -11550,10 +11569,10 @@ picocolors@^1.0.0:
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-picocolors@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz"
- integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==
+picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
version "2.3.1"
@@ -11678,25 +11697,25 @@ postcss-js@^4.0.1:
dependencies:
camelcase-css "^2.0.1"
-postcss-load-config@^4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz"
- integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==
+postcss-load-config@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3"
+ integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==
dependencies:
- lilconfig "^2.0.5"
- yaml "^2.1.1"
+ lilconfig "^3.0.0"
+ yaml "^2.3.4"
-postcss-nested@^6.0.1:
- version "6.0.1"
- resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz"
- integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==
+postcss-nested@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131"
+ integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==
dependencies:
- postcss-selector-parser "^6.0.11"
+ postcss-selector-parser "^6.1.1"
-postcss-selector-parser@^6.0.11:
- version "6.0.13"
- resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz"
- integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==
+postcss-selector-parser@^6.1.1, postcss-selector-parser@^6.1.2:
+ version "6.1.2"
+ resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de"
+ integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
@@ -11706,7 +11725,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
-postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31:
+postcss@8.4.31:
version "8.4.31"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz"
integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
@@ -11715,23 +11734,24 @@ postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31:
picocolors "^1.0.0"
source-map-js "^1.0.2"
-postcss@^8.4.43:
- version "8.4.47"
- resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz"
- integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
+postcss@^8.4.43, postcss@^8.4.47, postcss@^8.4.49:
+ version "8.4.49"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19"
+ integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
dependencies:
nanoid "^3.3.7"
- picocolors "^1.1.0"
+ picocolors "^1.1.1"
source-map-js "^1.2.1"
-posthog-js@^1.155.4:
- version "1.155.4"
- resolved "https://registry.npmjs.org/posthog-js/-/posthog-js-1.155.4.tgz"
- integrity sha512-suxwAsmZGqMDXJe/RaCKI3PaDEHiuMDDhKcJklgGAg7eDnywieRkr5CoPcOOvnqTDMnuOPETr98jpYBXKUwGFQ==
+posthog-js@^1.200.0:
+ version "1.200.0"
+ resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.200.0.tgz#46e89f85dc7ac7536ac3ce15b182ad3cec6ae9db"
+ integrity sha512-NuS9PF8whpxdG084XHzb/jE4WNRw7doej5fKzlTarzynbcblKiYbP/g9SMWCYcCAA63srIQzNOhbiaYDY7+y1A==
dependencies:
+ core-js "^3.38.1"
fflate "^0.4.8"
preact "^10.19.3"
- web-vitals "^4.0.1"
+ web-vitals "^4.2.0"
postinstall-postinstall@^2.1.0:
version "2.1.0"
@@ -12196,10 +12216,10 @@ react-universal-interface@^0.6.2:
resolved "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz"
integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==
-react-use@^17.2.4:
- version "17.4.0"
- resolved "https://registry.npmjs.org/react-use/-/react-use-17.4.0.tgz"
- integrity sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==
+react-use@^17.6.0:
+ version "17.6.0"
+ resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.6.0.tgz#2101a3a79dc965a25866b21f5d6de4b128488a14"
+ integrity sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==
dependencies:
"@types/js-cookie" "^2.2.6"
"@xobotyi/scrollbar-width" "^1.9.5"
@@ -12207,7 +12227,7 @@ react-use@^17.2.4:
fast-deep-equal "^3.1.3"
fast-shallow-equal "^1.0.0"
js-cookie "^2.2.1"
- nano-css "^5.3.1"
+ nano-css "^5.6.2"
react-universal-interface "^0.6.2"
resize-observer-polyfill "^1.5.1"
screenfull "^5.1.0"
@@ -12433,7 +12453,7 @@ resolve.exports@^2.0.0:
resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz"
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2:
+resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1:
version "1.22.2"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
@@ -12442,7 +12462,7 @@ resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-resolve@^1.22.4:
+resolve@^1.22.4, resolve@^1.22.8:
version "1.22.8"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
@@ -12547,9 +12567,9 @@ rpc-websockets@^7.5.1:
bufferutil "^4.0.1"
utf-8-validate "^5.0.2"
-rtl-css-js@^1.14.0:
+rtl-css-js@^1.16.1:
version "1.16.1"
- resolved "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz"
+ resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.16.1.tgz#4b48b4354b0ff917a30488d95100fbf7219a3e80"
integrity sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==
dependencies:
"@babel/runtime" "^7.1.2"
@@ -12575,7 +12595,7 @@ rxjs@^6.6.3:
dependencies:
tslib "^1.9.0"
-rxjs@^7.5.1, rxjs@^7.8.0:
+rxjs@^7.5.1, rxjs@^7.8.0, rxjs@^7.8.1:
version "7.8.1"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz"
integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
@@ -12631,14 +12651,15 @@ safe-stable-stringify@^2.1.0:
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-satori@^0.10.11:
- version "0.10.11"
- resolved "https://registry.yarnpkg.com/satori/-/satori-0.10.11.tgz#4d198beef405668120566d29a554411c534d8a5d"
- integrity sha512-yLm1xPRPZUaKcBZJ6nmezoJjHB4MqV8x7Mu0PyZUJodRWRDD27UbeMwzuY9LEGG57WYLO4CQsGPlbHWV1Ex9TQ==
+satori@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/satori/-/satori-0.12.0.tgz#6ffd11daedbf63fc6a68411639894da128b7a99f"
+ integrity sha512-e0e+qQyeFwEszujN7SpWpRtZgww7Nh8lSO3bUn2spHZ5JpqEl3zJ3P14/JlWruxEwdgREs35ZnavrPrWaRVFDg==
dependencies:
"@shuding/opentype.js" "1.4.0-beta.0"
css-background-parser "^0.1.0"
css-box-shadow "1.0.0-3"
+ css-gradient-parser "^0.0.16"
css-to-react-native "^3.0.0"
emoji-regex "^10.2.1"
escape-html "^1.0.3"
@@ -13071,11 +13092,6 @@ source-map@^0.7.3:
resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz"
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
-sourcemap-codec@^1.4.8:
- version "1.4.8"
- resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz"
- integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
-
space-separated-tokens@^1.0.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899"
@@ -13213,19 +13229,19 @@ stacktrace-js@^2.0.2:
stack-generator "^2.0.5"
stacktrace-gps "^3.0.4"
-start-server-and-test@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.0.tgz"
- integrity sha512-UqKLw0mJbfrsG1jcRLTUlvuRi9sjNuUiDOLI42r7R5fA9dsFoywAy9DoLXNYys9B886E4RCKb+qM1Gzu96h7DQ==
+start-server-and-test@^2.0.9:
+ version "2.0.9"
+ resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-2.0.9.tgz#a58160fa95e072aeb41e104472dea01b052b7443"
+ integrity sha512-DDceIvc4wdpr+z3Aqkot2QMho8TcUBh5qH0wEHDpEexBTzlheOcmh53d3dExABY4J5C7qS2UbSXqRWLtxpbWIQ==
dependencies:
arg "^5.0.2"
bluebird "3.7.2"
check-more-types "2.24.0"
- debug "4.3.4"
+ debug "4.4.0"
execa "5.1.1"
lazy-ass "1.6.0"
ps-tree "1.2.0"
- wait-on "7.0.1"
+ wait-on "8.0.1"
statuses@2.0.1:
version "2.0.1"
@@ -13537,19 +13553,19 @@ styled-tools@^1.7.2:
resolved "https://registry.npmjs.org/styled-tools/-/styled-tools-1.7.2.tgz"
integrity sha512-IjLxzM20RMwAsx8M1QoRlCG/Kmq8lKzCGyospjtSXt/BTIIcvgTonaxQAsKnBrsZNwhpHzO9ADx5te0h76ILVg==
-stylis@^4.0.6:
- version "4.2.0"
- resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz"
- integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
+stylis@^4.3.0:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.4.tgz#ca5c6c4a35c4784e4e93a2a24dc4e9fa075250a4"
+ integrity sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==
-sucrase@^3.32.0:
- version "3.32.0"
- resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz"
- integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==
+sucrase@^3.35.0:
+ version "3.35.0"
+ resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"
+ integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==
dependencies:
"@jridgewell/gen-mapping" "^0.3.2"
commander "^4.0.0"
- glob "7.1.6"
+ glob "^10.3.10"
lines-and-columns "^1.1.6"
mz "^2.7.0"
pirates "^4.0.1"
@@ -13591,12 +13607,13 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
-swr@^2.1.2:
- version "2.1.5"
- resolved "https://registry.npmjs.org/swr/-/swr-2.1.5.tgz"
- integrity sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw==
+swr@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/swr/-/swr-2.3.0.tgz#66fa45023efd4199f4e7ce608c255709a135943d"
+ integrity sha512-NyZ76wA4yElZWBHzSgEJc28a0u6QZvhb6w0azeL2k7+Q1gAzVK+IqQYXhVOC/mzi+HZIozrZvBVeSeOZNR2bqA==
dependencies:
- use-sync-external-store "^1.2.0"
+ dequal "^2.0.3"
+ use-sync-external-store "^1.4.0"
symbol-observable@^4.0.0:
version "4.0.0"
@@ -13632,41 +13649,38 @@ table@^6.0.9:
string-width "^4.2.3"
strip-ansi "^6.0.1"
-tailwind-merge@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.0.0.tgz"
- integrity sha512-WO8qghn9yhsldLSg80au+3/gY9E4hFxIvQ3qOmlpXnqpDKoMruKfi/56BbbMg6fHTQJ9QD3cc79PoWqlaQE4rw==
- dependencies:
- "@babel/runtime" "^7.23.1"
+tailwind-merge@^2.5.5:
+ version "2.5.5"
+ resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.5.5.tgz#98167859b856a2a6b8d2baf038ee171b9d814e39"
+ integrity sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==
-tailwindcss@^3.2.4:
- version "3.3.2"
- resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz"
- integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==
+tailwindcss@^3.4.16:
+ version "3.4.16"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.16.tgz#35a7c3030844d6000fc271878db4096b6a8d2ec9"
+ integrity sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==
dependencies:
"@alloc/quick-lru" "^5.2.0"
arg "^5.0.2"
- chokidar "^3.5.3"
+ chokidar "^3.6.0"
didyoumean "^1.2.2"
dlv "^1.1.3"
- fast-glob "^3.2.12"
+ fast-glob "^3.3.2"
glob-parent "^6.0.2"
is-glob "^4.0.3"
- jiti "^1.18.2"
- lilconfig "^2.1.0"
- micromatch "^4.0.5"
+ jiti "^1.21.6"
+ lilconfig "^3.1.3"
+ micromatch "^4.0.8"
normalize-path "^3.0.0"
object-hash "^3.0.0"
- picocolors "^1.0.0"
- postcss "^8.4.23"
+ picocolors "^1.1.1"
+ postcss "^8.4.47"
postcss-import "^15.1.0"
postcss-js "^4.0.1"
- postcss-load-config "^4.0.1"
- postcss-nested "^6.0.1"
- postcss-selector-parser "^6.0.11"
- postcss-value-parser "^4.2.0"
- resolve "^1.22.2"
- sucrase "^3.32.0"
+ postcss-load-config "^4.0.2"
+ postcss-nested "^6.2.0"
+ postcss-selector-parser "^6.1.2"
+ resolve "^1.22.8"
+ sucrase "^3.35.0"
tapable@^1.1.3:
version "1.1.3"
@@ -13966,10 +13980,10 @@ ts-invariant@^0.10.3:
dependencies:
tslib "^2.1.0"
-ts-node@^10.9.1:
- version "10.9.1"
- resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz"
- integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
+ts-node@^10.9.2:
+ version "10.9.2"
+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f"
+ integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==
dependencies:
"@cspotcode/source-map-support" "^0.8.0"
"@tsconfig/node10" "^1.0.7"
@@ -14357,6 +14371,11 @@ use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0:
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+use-sync-external-store@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
+ integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==
+
user-home@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz"
@@ -14554,7 +14573,18 @@ wagmi@^0.12.18:
abitype "^0.3.0"
use-sync-external-store "^1.2.0"
-wait-on@7.0.1, wait-on@^7.0.1:
+wait-on@8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-8.0.1.tgz#13c8ec77115517f8fbc2d670521a444201f03f53"
+ integrity sha512-1wWQOyR2LVVtaqrcIL2+OM+x7bkpmzVROa0Nf6FryXkS+er5Sa1kzFGjzZRqLnHa3n1rACFLeTwUqE1ETL9Mig==
+ dependencies:
+ axios "^1.7.7"
+ joi "^17.13.3"
+ lodash "^4.17.21"
+ minimist "^1.2.8"
+ rxjs "^7.8.1"
+
+wait-on@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/wait-on/-/wait-on-7.0.1.tgz"
integrity sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==
@@ -14579,10 +14609,10 @@ wbuf@^1.1.0, wbuf@^1.7.3:
dependencies:
minimalistic-assert "^1.0.0"
-web-vitals@^4.0.1:
- version "4.2.3"
- resolved "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.3.tgz"
- integrity sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==
+web-vitals@^4.2.0:
+ version "4.2.4"
+ resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-4.2.4.tgz#1d20bc8590a37769bd0902b289550936069184b7"
+ integrity sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==
webidl-conversions@^3.0.0:
version "3.0.1"
@@ -14892,15 +14922,10 @@ yallist@^4.0.0:
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-yaml@^2.1.1:
- version "2.3.1"
- resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz"
- integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
-
-yaml@^2.2.2:
- version "2.3.4"
- resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz"
- integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==
+yaml@^2.2.2, yaml@^2.3.4:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773"
+ integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==
yargs-parser@^18.1.2:
version "18.1.3"
@@ -14985,24 +15010,12 @@ zen-observable@0.8.15:
resolved "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz"
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
-zod@^3.22.4:
- version "3.22.4"
- resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz"
- integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==
-
-zod@^3.23.8:
- version "3.23.8"
- resolved "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz"
- integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
-
-zustand@^4.3.1:
- version "4.3.8"
- resolved "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz"
- integrity sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==
- dependencies:
- use-sync-external-store "1.2.0"
+zod@^3.23.8, zod@^3.24.1:
+ version "3.24.1"
+ resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.1.tgz#27445c912738c8ad1e9de1bea0359fa44d9d35ee"
+ integrity sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==
-zustand@^4.3.9:
+zustand@^4.3.1, zustand@^4.3.9:
version "4.3.9"
resolved "https://registry.npmjs.org/zustand/-/zustand-4.3.9.tgz"
integrity sha512-Tat5r8jOMG1Vcsj8uldMyqYKC5IZvQif8zetmLHs9WoZlntTHmIoNM8TpLRY31ExncuUvUOXehd0kvahkuHjDw==