Skip to content

Commit

Permalink
Merge branch 'master' into eth-custom-dest-4
Browse files Browse the repository at this point in the history
  • Loading branch information
brtkx authored Oct 22, 2024
2 parents 02b4a3d + e3af561 commit 746ba52
Show file tree
Hide file tree
Showing 31 changed files with 721 additions and 152 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/add-layerleap-request.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Add Layer Leap Request
description: File a request to have your Orbit chain support Layer Leap transfers
title: "[feat]: enable Layer Leap for <Orbit Chain>"
labels: ["feat", "triage"]
labels: ["Type: Add LayerLeap"]
body:
- type: markdown
attributes:
Expand Down
12 changes: 3 additions & 9 deletions .github/ISSUE_TEMPLATE/add-orbit-chain-request.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Add Orbit Chain Request
description: File a request to have your Orbit chain added to the bridge
title: "[feat]: Add Orbit chain "
labels: ["feat", "triage"]
labels: ["Type: Add Orbit Chain"]
body:
- type: markdown
attributes:
Expand Down Expand Up @@ -71,6 +71,8 @@ body:
- "421614"
- "11155111"
- "17000"
- "8453"
- "84532"
validations:
required: true

Expand Down Expand Up @@ -170,10 +172,6 @@ body:
attributes:
value: |
## Parent chain token bridge contract addresses
- type: markdown
attributes:
value: |
You can find this information under the `"l2Contracts" : {...}` key.
- type: input
id: parent-custom-gateway
attributes:
Expand Down Expand Up @@ -222,10 +220,6 @@ body:
attributes:
value: |
## Orbit chain token bridge contract addresses
- type: markdown
attributes:
value: |
You can find this information under the `"l3Contracts" : {...}` key.
- type: input
id: child-custom-gateway
attributes:
Expand Down
10 changes: 9 additions & 1 deletion audit-ci.jsonc
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
{
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
"low": true,
"allowlist": []
"allowlist": [
// https://github.com/advisories/GHSA-fc9h-whq2-v747
// Valid ECDSA signatures erroneously rejected in Elliptic
// Legitimate transactions or communications may be incorrectly flagged as invalid.
// No patched version available yet
// from: arb-token-bridge-ui>@unstoppabledomains/resolution>elliptic
// from: arb-token-bridge-ui>ethers>@ethersproject/signing-key>elliptic
"GHSA-fc9h-whq2-v747"
]
}
3 changes: 3 additions & 0 deletions packages/arb-token-bridge-ui/.env.local.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ NEXT_PUBLIC_INFURA_KEY_SEPOLIA=

# L2
NEXT_PUBLIC_INFURA_KEY_ARBITRUM_ONE=
NEXT_PUBLIC_INFURA_KEY_BASE=
# L2 Testnet
NEXT_PUBLIC_INFURA_KEY_ARBITRUM_SEPOLIA=
NEXT_PUBLIC_INFURA_KEY_BASE_SEPOLIA=

NEXT_PUBLIC_SENTRY_DSN=

Expand All @@ -26,5 +28,6 @@ SELF_HOSTED_SUBGRAPH_API_KEY=

SCREENING_API_ENDPOINT=
SCREENING_API_KEY=
NEXT_PUBLIC_SCREENING_API_ENDPOINT=

NEXT_PUBLIC_POSTHOG_KEY=
11 changes: 11 additions & 0 deletions packages/arb-token-bridge-ui/public/images/ApeChainLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
144 changes: 144 additions & 0 deletions packages/arb-token-bridge-ui/public/images/ApeTokenLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
3 changes: 3 additions & 0 deletions packages/arb-token-bridge-ui/public/images/BaseWhite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 9 additions & 15 deletions packages/arb-token-bridge-ui/src/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { BalanceUpdater } from '../syncers/BalanceUpdater'
import { TokenListSyncer } from '../syncers/TokenListSyncer'
import { Header } from '../common/Header'
import { HeaderAccountPopover } from '../common/HeaderAccountPopover'
import { getNetworkName, isNetwork } from '../../util/networks'
import { getNetworkName } from '../../util/networks'
import {
ArbQueryParamProvider,
useArbQueryParams
Expand All @@ -41,6 +41,7 @@ import { HeaderConnectWalletButton } from '../common/HeaderConnectWalletButton'
import { onDisconnectHandler } from '../../util/walletConnectUtils'
import { addressIsSmartContract } from '../../util/AddressUtils'
import { useSyncConnectedChainToAnalytics } from './useSyncConnectedChainToAnalytics'
import { isDepositMode } from '../../util/isDepositMode'

declare global {
interface Window {
Expand Down Expand Up @@ -98,30 +99,23 @@ const ArbTokenBridgeStoreSyncWrapper = (): JSX.Element | null => {
// Any time one of those changes
setTokenBridgeParams(null)
actions.app.setConnectionState(ConnectionState.LOADING)

const {
isArbitrum: isConnectedToArbitrum,
isOrbitChain: isConnectedToOrbitChain
} = isNetwork(networks.sourceChain.id)
const isParentChainEthereum = isNetwork(
parentChain.id
).isEthereumMainnetOrTestnet

actions.app.reset(networks.sourceChain.id)
actions.app.setChainIds({
l1NetworkChainId: parentChain.id,
l2NetworkChainId: childChain.id
})

if (
(isParentChainEthereum && isConnectedToArbitrum) ||
isConnectedToOrbitChain
isDepositMode({
sourceChainId: networks.sourceChain.id,
destinationChainId: networks.destinationChain.id
})
) {
console.info('Withdrawal mode detected:')
actions.app.setConnectionState(ConnectionState.L2_CONNECTED)
} else {
console.info('Deposit mode detected:')
actions.app.setConnectionState(ConnectionState.L1_CONNECTED)
} else {
console.info('Withdrawal mode detected:')
actions.app.setConnectionState(ConnectionState.L2_CONNECTED)
}

setTokenBridgeParams({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ import { useActions } from '../../state'
import { useChainIdsForNetworkSelection } from '../../hooks/TransferPanel/useChainIdsForNetworkSelection'
import { useAccountType } from '../../hooks/useAccountType'

type NetworkType = 'core' | 'orbit'
type NetworkType = 'core' | 'other' | 'orbit'

enum ChainGroupName {
core = 'CORE CHAINS',
other = 'OTHER CHAINS',
orbit = 'ORBIT CHAINS'
}

Expand All @@ -48,6 +49,19 @@ const chainGroupInfo: { [key in NetworkType]: ChainGroupInfo } = {
core: {
name: ChainGroupName.core
},
other: {
name: ChainGroupName.other,
description: (
<p className="mt-2 flex gap-1 whitespace-normal rounded bg-orange-dark px-2 py-1 text-xs text-orange">
<ShieldExclamationIcon className="h-4 w-4 shrink-0" />
<span>
Independent projects using non-Arbitrum technology. These chains have
varying degrees of decentralization.{' '}
<span className="font-semibold">Bridge at your own risk.</span>
</span>
</p>
)
},
orbit: {
name: ChainGroupName.orbit,
description: (
Expand All @@ -71,15 +85,15 @@ function ChainTypeInfoRow({
style: CSSProperties
}) {
const { name, description } = chainGroup
const isCoreGroup = chainGroup.name === ChainGroupName.core
const isOrbitGroup = chainGroup.name === ChainGroupName.orbit

return (
<div
key={name}
style={style}
className={twMerge(
'px-4 py-3',
!isCoreGroup &&
!isOrbitGroup &&
'before:-mt-3 before:mb-3 before:block before:h-[1px] before:w-full before:bg-white/30 before:content-[""]'
)}
>
Expand Down Expand Up @@ -236,14 +250,19 @@ function NetworksPanel({
}

const coreNetworks = chainIds.filter(
chainId => !isNetwork(chainId).isOrbitChain
chainId => isNetwork(chainId).isCoreChain
)
const otherNetworks = chainIds.filter(
chainId =>
!isNetwork(chainId).isCoreChain && !isNetwork(chainId).isOrbitChain
)
const orbitNetworks = chainIds.filter(
chainId => isNetwork(chainId).isOrbitChain
)

return {
core: coreNetworks,
other: otherNetworks,
orbit: orbitNetworks
}
}, [debouncedNetworkSearched, chainIds])
Expand All @@ -262,6 +281,10 @@ function NetworksPanel({
groupedNetworks.push(ChainGroupName.core, ...networksToShow.core)
}

if (networksToShow.other.length > 0) {
groupedNetworks.push(ChainGroupName.other, ...networksToShow.other)
}

if (networksToShow.orbit.length > 0) {
groupedNetworks.push(ChainGroupName.orbit, ...networksToShow.orbit)
}
Expand Down Expand Up @@ -302,6 +325,12 @@ function NetworksPanel({
)
}

if (networkOrChainTypeName === ChainGroupName.other) {
return (
<ChainTypeInfoRow chainGroup={chainGroupInfo.other} style={style} />
)
}

if (networkOrChainTypeName === ChainGroupName.orbit) {
return (
<ChainTypeInfoRow chainGroup={chainGroupInfo.orbit} style={style} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ describe('sanitizeQueryParams', () => {
})
})
})
describe('when `destinationChainId` is valid but has no paired source chains and `sourceChainId` is undefined', () => {
it('should set `sourceChainId` to Ethereum and `destinationChainId` to Arbitrum One', () => {
const result = sanitizeQueryParams({
sourceChainId: undefined,
destinationChainId: ChainId.Holesky
})
expect(result).toEqual({
sourceChainId: ChainId.Ethereum,
destinationChainId: ChainId.ArbitrumOne
})
})
})

describe('when `destinationChainId` is invalid and `sourceChainId` is valid', () => {
it('should set `destinationChainId` based on `sourceChainId`', () => {
Expand Down Expand Up @@ -207,4 +219,16 @@ describe('sanitizeQueryParams', () => {
})
})
})
describe('when `destinationChainId` is undefined and `sourceChainId` is valid but has no paired destination chains', () => {
it('should set `sourceChainId` to Ethereum and `destinationChainId` to Arbitrum One', () => {
const result = sanitizeQueryParams({
sourceChainId: ChainId.Holesky,
destinationChainId: undefined
})
expect(result).toEqual({
sourceChainId: ChainId.Ethereum,
destinationChainId: ChainId.ArbitrumOne
})
})
})
})
49 changes: 34 additions & 15 deletions packages/arb-token-bridge-ui/src/hooks/useAccountIsBlocked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,48 @@ import { useMemo } from 'react'
import { useAccount } from 'wagmi'
import useSWRImmutable from 'swr/immutable'

import { ApiResponseSuccess } from '../pages/api/screenings'
import { trackEvent } from '../util/AnalyticsUtils'
import { Address } from '../util/AddressUtils'
import { captureSentryErrorWithExtraData } from '../util/SentryUtils'

/**
* Checks if an address is blocked using the external Screenings API service.
* @param {Address} address - The address to check.
* @returns {Promise<boolean>} true if blocked or the request fails
*/
async function isBlocked(address: Address): Promise<boolean> {
if (
process.env.NODE_ENV !== 'production' ||
process.env.NEXT_PUBLIC_IS_E2E_TEST
) {
return false
}
try {
if (
process.env.NODE_ENV !== 'production' ||
process.env.NEXT_PUBLIC_IS_E2E_TEST
) {
return false
}

const url = new URL(process.env.NEXT_PUBLIC_SCREENING_API_ENDPOINT ?? '')
url.searchParams.set('address', address)

const searchParams = new URLSearchParams({ address })
const response = await fetch('/api/screenings?' + searchParams, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
const response = await fetch(url, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}

const { blocked } = await response.json()
return blocked
} catch (error) {
console.error('Failed to check if address is blocked', error)
captureSentryErrorWithExtraData({
error,
originFunction: 'isBlocked',
additionalData: { address }
})

if (!response.ok) {
return false
}

return ((await response.json()) as ApiResponseSuccess).blocked
}

async function fetcher(address: Address): Promise<boolean> {
Expand Down
Loading

0 comments on commit 746ba52

Please sign in to comment.