Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
spsjvc committed Dec 17, 2024
1 parent 246cb6f commit 312cf06
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 28 deletions.
16 changes: 15 additions & 1 deletion packages/arb-token-bridge-ui/src/util/networks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StaticJsonRpcProvider } from '@ethersproject/providers'
import { Provider, StaticJsonRpcProvider } from '@ethersproject/providers'
import {
ArbitrumNetwork,
getChildrenForNetwork,
Expand All @@ -11,6 +11,7 @@ import { loadEnvironmentVariableWithFallback } from './index'
import { getBridgeUiConfigForChain } from './bridgeUiConfig'
import { chainIdToInfuraUrl } from './infura'
import { fetchErc20Data } from './TokenUtils'
import orbitChainsData from './orbitChainsData.json'

export enum ChainId {
// L1
Expand Down Expand Up @@ -581,6 +582,19 @@ export function getSupportedChainIds({
})
}

export async function isAlchemyChain(provider: Provider) {
const { chainId } = await getArbitrumNetwork(provider)

const chains = [...orbitChainsData.mainnet, ...orbitChainsData.testnet]
const chain = chains.find(chain => chain.chainId === chainId)

if (typeof chain === 'undefined') {
return false
}

return chain.rpcUrl.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
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ type TokenWithdrawalQuery = {
priority: number
}

export type BuildQueryParamsParams = {
sender?: string
receiver?: string
gateways?: string[]
}

export type FetchTokenWithdrawalsFromEventLogsSequentiallyParams = {
sender?: string
receiver?: string
Expand All @@ -46,22 +52,23 @@ export type FetchTokenWithdrawalsFromEventLogsSequentiallyParams = {
* How long to delay in-between queries of different priority.
*/
delayMs?: number
queries: BuildQueryParamsParams[]
}

export type FetchTokenWithdrawalsFromEventLogsSequentiallyResult = Awaited<
ReturnType<Erc20Bridger['getWithdrawalEvents']>
>

export async function fetchTokenWithdrawalsFromEventLogsSequentially({
sender,
receiver,
provider,
fromBlock = 0,
toBlock = 'latest',
delayMs = 2_000
delayMs = 2_000,
queries: queriesProp
}: FetchTokenWithdrawalsFromEventLogsSequentiallyParams): Promise<FetchTokenWithdrawalsFromEventLogsSequentiallyResult> {
// keep track of priority; increment as queries are added
let priority = 0

// keep track of queries
const queries: TokenWithdrawalQuery[] = []

Expand All @@ -70,11 +77,7 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({
sender,
receiver,
gateways = []
}: {
sender?: string
receiver?: string
gateways?: string[]
}): TokenWithdrawalQuery['params'] {
}: BuildQueryParamsParams): TokenWithdrawalQuery['params'] {
return {
sender,
receiver,
Expand All @@ -100,22 +103,9 @@ export async function fetchTokenWithdrawalsFromEventLogsSequentially({
})
}

const gateways = await getGateways(provider)
const senderNonce = await backOff(() => getNonce(sender, { provider }))

// sender queries; only add if nonce > 0
if (senderNonce > 0) {
addQuery(buildQueryParams({ sender, gateways: [gateways.standardGateway] }))
addQuery(buildQueryParams({ sender, gateways: [gateways.wethGateway] }))
addQuery(buildQueryParams({ sender, gateways: [gateways.customGateway] }))
addQuery(buildQueryParams({ sender, gateways: gateways.otherGateways }))
}

// receiver queries
addQuery(buildQueryParams({ receiver, gateways: [gateways.standardGateway] }))
addQuery(buildQueryParams({ receiver, gateways: [gateways.wethGateway] }))
addQuery(buildQueryParams({ receiver, gateways: [gateways.customGateway] }))
addQuery(buildQueryParams({ receiver, gateways: gateways.otherGateways }))
queriesProp.forEach(query => {
addQuery(buildQueryParams(query))
})

// for iterating through all priorities in the while loop below
let currentPriority = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,37 @@ import { fetchLatestSubgraphBlockNumber } from '../SubgraphUtils'
import { Withdrawal } from '../../hooks/useTransactionHistory'
import { attachTimestampToTokenWithdrawal } from './helpers'
import { WithdrawalInitiated } from '../../hooks/arbTokenBridge.types'
import { fetchTokenWithdrawalsFromEventLogsSequentially } from './fetchTokenWithdrawalsFromEventLogsSequentially'
import {
BuildQueryParamsParams,
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
Expand Down Expand Up @@ -84,6 +113,47 @@ export async function fetchWithdrawals({
console.log('Error fetching withdrawals from subgraph', error)
}

const gateways = await getGateways(l2Provider)
const senderNonce = await getNonce(sender, { provider: l2Provider })

const queries: BuildQueryParamsParams[] = []

// alchemy has a global rate limit across all their chains, so we have to fetch sequentially and wait in-between requests
const isAlchemy = await isAlchemyChain(l2Provider)
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,
Expand All @@ -95,15 +165,16 @@ export async function fetchWithdrawals({
})
)

await wait(2_000)
await wait(delayMs)

const tokenWithdrawalsFromEventLogs =
await fetchTokenWithdrawalsFromEventLogsSequentially({
sender,
receiver,
fromBlock: toBlock + 1,
toBlock: 'latest',
provider: l2Provider
provider: l2Provider,
queries: []
})

const mappedEthWithdrawalsFromEventLogs: Withdrawal[] =
Expand Down

0 comments on commit 312cf06

Please sign in to comment.