diff --git a/package.json b/package.json
index ba36c41e6..0bc0cfba9 100644
--- a/package.json
+++ b/package.json
@@ -166,7 +166,7 @@
"@types/wcag-contrast": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
- "@uniswap/default-token-list": "^4.1.0",
+ "@uniswap/default-token-list": "^9.0.0",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
diff --git a/src/assets/svg/bnb-logo.svg b/src/assets/svg/bnb-logo.svg
new file mode 100644
index 000000000..c5b47602a
--- /dev/null
+++ b/src/assets/svg/bnb-logo.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/components/Logo/hooks.ts b/src/components/Logo/hooks.ts
index 9367de474..e4ee50030 100644
--- a/src/components/Logo/hooks.ts
+++ b/src/components/Logo/hooks.ts
@@ -33,7 +33,7 @@ export function useLogo(currency: LogoTableInput | undefined) {
const invalidateSrc = useCallback(() => {
const nextSrc = entry?.invalidateSrc()
- nextSrc && setSrc(nextSrc.getUri())
+ setSrc(nextSrc?.getUri())
}, [entry])
return { src, invalidateSrc }
diff --git a/src/components/Logo/util.ts b/src/components/Logo/util.ts
index 1705d7989..2b761310f 100644
--- a/src/components/Logo/util.ts
+++ b/src/components/Logo/util.ts
@@ -2,11 +2,12 @@ import { SupportedChainId } from 'constants/chains'
import { isAddress } from 'utils'
import EthereumLogo from '../../assets/images/ethereum-logo.png'
+import BnbLogo from '../../assets/svg/bnb-logo.svg'
import CeloLogo from '../../assets/svg/celo_logo.svg'
import MaticLogo from '../../assets/svg/matic-token-icon.svg'
import { LogoTableInput } from './LogoTable'
-type Network = 'ethereum' | 'arbitrum' | 'optimism' | 'polygon' | 'celo'
+type Network = 'ethereum' | 'arbitrum' | 'optimism' | 'polygon' | 'celo' | 'binance'
function chainIdToNetworkName(networkId: SupportedChainId): Network | undefined {
switch (networkId) {
@@ -20,6 +21,8 @@ function chainIdToNetworkName(networkId: SupportedChainId): Network | undefined
return 'polygon'
case SupportedChainId.CELO:
return 'celo'
+ case SupportedChainId.BNB:
+ return 'binance'
default:
return 'ethereum'
}
@@ -46,6 +49,8 @@ export function getNativeLogoURI(chainId: SupportedChainId = SupportedChainId.MA
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
return CeloLogo
+ case SupportedChainId.BNB:
+ return BnbLogo
default:
return EthereumLogo
}
diff --git a/src/constants/chainInfo.ts b/src/constants/chainInfo.ts
index b32bec0b3..d98069641 100644
--- a/src/constants/chainInfo.ts
+++ b/src/constants/chainInfo.ts
@@ -1,5 +1,6 @@
import ethereumLogoUrl from 'assets/images/ethereum-logo.png'
import arbitrumLogoUrl from 'assets/svg/arbitrum_logo.svg'
+import bnbLogo from 'assets/svg/bnb-logo.svg'
import celoLogo from 'assets/svg/celo_logo.svg'
import optimismLogoUrl from 'assets/svg/optimism_logo.svg'
import polygonMaticLogo from 'assets/svg/polygon-matic-logo.svg'
@@ -223,6 +224,19 @@ const CHAIN_INFO: ChainInfoMap = {
color: '#35D07F',
backgroundColor: '#34d07f1f',
},
+ [SupportedChainId.BNB]: {
+ networkType: NetworkType.L1,
+ blockWaitMsBeforeWarning: ms`10m`,
+ bridge: 'https://cbridge.celer.network/1/56',
+ docs: 'https://docs.bnbchain.org/',
+ explorer: 'https://bscscan.com/',
+ infoLink: 'https://info.uniswap.org/#/bnb/',
+ label: 'BNB Chain',
+ logoUrl: bnbLogo,
+ nativeCurrency: { name: 'BNB', symbol: 'BNB', decimals: 18 },
+ color: '#F0B90B',
+ backgroundColor: '#F0B90B',
+ },
}
export function getChainInfo(chainId: SupportedL1ChainId): L1ChainInfo
diff --git a/src/constants/chains.ts b/src/constants/chains.ts
index b36a673b8..cf530f941 100644
--- a/src/constants/chains.ts
+++ b/src/constants/chains.ts
@@ -19,6 +19,8 @@ export enum SupportedChainId {
CELO = 42220,
CELO_ALFAJORES = 44787,
+
+ BNB = 56,
}
export enum ChainName {
@@ -35,6 +37,7 @@ export enum ChainName {
POLYGON_MUMBAI = 'polygon-mumbai',
CELO = 'celo',
CELO_ALFAJORES = 'celo-alfajores',
+ BNB = 'bnb',
}
export const CHAIN_NAMES_TO_IDS: { [chainName: string]: SupportedChainId } = {
@@ -51,6 +54,7 @@ export const CHAIN_NAMES_TO_IDS: { [chainName: string]: SupportedChainId } = {
[ChainName.OPTIMISM_GOERLI]: SupportedChainId.OPTIMISM_GOERLI,
[ChainName.CELO]: SupportedChainId.CELO,
[ChainName.CELO_ALFAJORES]: SupportedChainId.CELO_ALFAJORES,
+ [ChainName.BNB]: SupportedChainId.BNB,
}
/**
@@ -66,6 +70,7 @@ export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.CELO,
+ SupportedChainId.BNB,
]
/**
diff --git a/src/constants/jsonRpcEndpoints.ts b/src/constants/jsonRpcEndpoints.ts
index 143c32798..7c7e97561 100644
--- a/src/constants/jsonRpcEndpoints.ts
+++ b/src/constants/jsonRpcEndpoints.ts
@@ -74,4 +74,16 @@ export const JSON_RPC_FALLBACK_ENDPOINTS: Record = {
// "Safe" URLs
'https://alfajores-forno.celo-testnet.org',
],
+ [SupportedChainId.BNB]: [
+ // "Safe" URLs
+ 'https://endpoints.omniatech.io/v1/bsc/mainnet/public',
+ 'https://bsc-mainnet.gateway.pokt.network/v1/lb/6136201a7bad1500343e248d',
+ 'https://1rpc.io/bnb',
+ 'https://bsc-dataseed3.binance.org',
+ 'https://bsc-dataseed2.defibit.io',
+ 'https://bsc-dataseed1.ninicoin.io',
+ 'https://binance.nodereal.io',
+ 'https://bsc-dataseed4.defibit.io',
+ 'https://rpc.ankr.com/bsc',
+ ],
}
diff --git a/src/constants/routing.ts b/src/constants/routing.ts
index 02192581b..1336fe771 100644
--- a/src/constants/routing.ts
+++ b/src/constants/routing.ts
@@ -23,10 +23,12 @@ import {
sETH2,
SWISE,
TRIBE,
+ USDC_BNB_CHAIN,
USDC_MAINNET,
USDC_POLYGON,
USDT,
USDT_ARBITRUM_ONE,
+ USDT_BNB_CHAIN,
USDT_OPTIMISM,
USDT_POLYGON,
WBTC,
@@ -84,6 +86,12 @@ export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
PORTAL_USDC_CELO,
PORTAL_ETH_CELO,
],
+ [SupportedChainId.BNB]: [
+ nativeOnChain(SupportedChainId.BNB),
+ USDC_BNB_CHAIN,
+ USDT_BNB_CHAIN,
+ ...WRAPPED_NATIVE_CURRENCIES_ONLY[SupportedChainId.BNB],
+ ],
}
export const ADDITIONAL_BASES: { [chainId: number]: { [tokenAddress: string]: Token[] } } = {
[SupportedChainId.MAINNET]: {
diff --git a/src/constants/tokens.ts b/src/constants/tokens.ts
index 615e5b3b3..df853c490 100644
--- a/src/constants/tokens.ts
+++ b/src/constants/tokens.ts
@@ -123,6 +123,13 @@ export const DAI_OPTIMISM = new Token(
'DAI',
'Dai stable coin'
)
+export const USDC_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',
+ 18,
+ 'USDC',
+ 'USDC'
+)
export const USDC: { [chainId in SupportedChainId]: Token } = {
[SupportedChainId.MAINNET]: USDC_MAINNET,
[SupportedChainId.ARBITRUM_ONE]: USDC_ARBITRUM,
@@ -137,6 +144,7 @@ export const USDC: { [chainId in SupportedChainId]: Token } = {
[SupportedChainId.RINKEBY]: USDC_RINKEBY,
[SupportedChainId.KOVAN]: USDC_KOVAN,
[SupportedChainId.ROPSTEN]: USDC_ROPSTEN,
+ [SupportedChainId.BNB]: USDC_BNB_CHAIN,
}
export const DAI_POLYGON = new Token(
SupportedChainId.POLYGON,
@@ -335,6 +343,91 @@ export const CEUR_CELO_ALFAJORES = new Token(
'CEUR',
'Celo Euro Stablecoin'
)
+export const USDT_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x55d398326f99059fF775485246999027B3197955',
+ 18,
+ 'USDT',
+ 'USDT'
+)
+
+export const ETH_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x2170Ed0880ac9A755fd29B2688956BD959F933F8',
+ 18,
+ 'ETH',
+ 'Ethereum'
+)
+
+export const MATIC_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0xCC42724C6683B7E57334c4E856f4c9965ED682bD',
+ 18,
+ 'MATIC',
+ 'Matic'
+)
+
+export const FRAX_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x90C97F71E18723b0Cf0dfa30ee176Ab653E89F40',
+ 18,
+ 'FRAX',
+ 'FRAX'
+)
+
+export const BTC_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c',
+ 18,
+ 'BTCB',
+ 'BTCB'
+)
+
+export const CAKE_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82',
+ 18,
+ 'CAKE',
+ 'Cake'
+)
+
+export const BUSD_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
+ 18,
+ 'BUSD',
+ 'BUSD'
+)
+
+export const DAI_BNB_CHAIN = new Token(
+ SupportedChainId.BNB,
+ '0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3',
+ 18,
+ 'DAI',
+ 'DAI'
+)
+
+function isBnbChain(chainId: number): chainId is SupportedChainId.BNB {
+ return chainId === SupportedChainId.BNB
+}
+
+class BnbChainNativeCurrency extends NativeCurrency {
+ equals(other: Currency): boolean {
+ return other.isNative && other.chainId === this.chainId
+ }
+
+ get wrapped(): Token {
+ if (!isBnbChain(this.chainId)) throw new Error('Not BNB Chain')
+ const wrapped = WRAPPED_NATIVE_CURRENCY[this.chainId]
+ invariant(wrapped instanceof Token)
+ return wrapped
+ }
+
+ public constructor(chainId: number) {
+ if (!isBnbChain(chainId)) throw new Error('Not BNB Chain')
+ super(chainId, 18, 'BNB', 'BNB')
+ }
+}
export const UNI: { [chainId: number]: Token } = {
[SupportedChainId.MAINNET]: new Token(SupportedChainId.MAINNET, UNI_ADDRESS[1], 18, 'UNI', 'Uniswap'),
@@ -390,6 +483,13 @@ export const WRAPPED_NATIVE_CURRENCY: { [chainId: number]: Token | undefined } =
'WMATIC',
'Wrapped MATIC'
),
+ [SupportedChainId.BNB]: new Token(
+ SupportedChainId.BNB,
+ '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
+ 18,
+ 'WBNB',
+ 'Wrapped BNB'
+ ),
}
export function isCelo(chainId: number): chainId is SupportedChainId.CELO | SupportedChainId.CELO_ALFAJORES {
@@ -451,6 +551,8 @@ export function nativeOnChain(chainId: number): NativeCurrency | Token {
nativeCurrency = new MaticNativeCurrency(chainId)
} else if (isCelo(chainId)) {
nativeCurrency = getCeloNativeCurrency(chainId)
+ } else if (isBnbChain(chainId)) {
+ nativeCurrency = new BnbChainNativeCurrency(chainId)
} else {
nativeCurrency = ExtendedEther.onChain(chainId)
}
diff --git a/src/hooks/web3/useJsonRpcUrlsMap.tsx b/src/hooks/web3/useJsonRpcUrlsMap.tsx
index 43cb31392..3cea0ce7d 100644
--- a/src/hooks/web3/useJsonRpcUrlsMap.tsx
+++ b/src/hooks/web3/useJsonRpcUrlsMap.tsx
@@ -31,6 +31,7 @@ function toJsonRpcMap(getChainConnections: (chainId: SupportedChainId) => T):
[SupportedChainId.OPTIMISM_GOERLI]: getChainConnections(SupportedChainId.OPTIMISM_GOERLI),
[SupportedChainId.CELO]: getChainConnections(SupportedChainId.CELO),
[SupportedChainId.CELO_ALFAJORES]: getChainConnections(SupportedChainId.CELO_ALFAJORES),
+ [SupportedChainId.BNB]: getChainConnections(SupportedChainId.BNB),
}
}
diff --git a/src/state/routing/slice.ts b/src/state/routing/slice.ts
index ae6e64e9b..c53d62c3b 100644
--- a/src/state/routing/slice.ts
+++ b/src/state/routing/slice.ts
@@ -82,7 +82,6 @@ export const routing = createApi({
protocols,
})
if (typeof quote === 'string') return { data: quote as TradeQuoteResult }
-
const tradeResult = transformQuoteToTradeResult(args, quote)
return { data: tradeResult }
} catch (error: any) {
diff --git a/src/utils/getExplorerLink.test.ts b/src/utils/getExplorerLink.test.ts
index 03cfe8778..97a0da36e 100644
--- a/src/utils/getExplorerLink.test.ts
+++ b/src/utils/getExplorerLink.test.ts
@@ -36,4 +36,7 @@ describe('#getExplorerLink', () => {
it('enum', () => {
expect(getExplorerLink(4, 'abc', ExplorerDataType.ADDRESS)).toEqual('https://rinkeby.etherscan.io/address/abc')
})
+ it('bnb chain', () => {
+ expect(getExplorerLink(56, 'abc', ExplorerDataType.ADDRESS)).toEqual('https://bscscan.com/address/abc')
+ })
})
diff --git a/src/utils/getExplorerLink.ts b/src/utils/getExplorerLink.ts
index 3f8f5e62e..4ad6ab6c4 100644
--- a/src/utils/getExplorerLink.ts
+++ b/src/utils/getExplorerLink.ts
@@ -12,6 +12,7 @@ const ETHERSCAN_PREFIXES: { [chainId: number]: string } = {
[SupportedChainId.POLYGON]: 'https://polygonscan.com',
[SupportedChainId.CELO]: 'https://celoscan.io',
[SupportedChainId.CELO_ALFAJORES]: 'https://alfajores.celoscan.io',
+ [SupportedChainId.BNB]: 'https://bscscan.com',
}
export enum ExplorerDataType {
diff --git a/yarn.lock b/yarn.lock
index 741fd11f6..d33795d4b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3528,10 +3528,10 @@
resolved "https://registry.yarnpkg.com/@uniswap/default-token-list/-/default-token-list-2.2.0.tgz#d85a5c2520f57f4920bd989dfc9f01e1b701a567"
integrity sha512-vFPWoGzDjHP4i2l7yLaober/lZMmzOZXXirVF8XNyfNzRxgmYCWKO6SzKtfEUwxpd3/KUebgdK55II4Mnak62A==
-"@uniswap/default-token-list@^4.1.0":
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/@uniswap/default-token-list/-/default-token-list-4.1.0.tgz#bbda8b946096f248b92809f71b77b4d407768796"
- integrity sha512-NxFW4OhYpnAunD37CKDRadG5ujp3r6cYnfBzTD1Eq4jwdr3ULt01xGqGljq0SuGAGhTsD+bmR46vPg3TdDwW0g==
+"@uniswap/default-token-list@^9.0.0":
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/@uniswap/default-token-list/-/default-token-list-9.0.0.tgz#35e070095ac24d24ef03877842c5d46807b59c87"
+ integrity sha512-a62uqv5ApULDVEXCOursXIaEoxP4MtlzdNSiQikYl1x9RfsUAZXl9dBtCo2d1Ne+iS1THic1oCJMshNtT9Z0EQ==
"@uniswap/lib@^4.0.1-alpha":
version "4.0.1-alpha"