Skip to content
This repository has been archived by the owner on Apr 20, 2024. It is now read-only.

Commit

Permalink
feat: arbitrum
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewlilley committed May 30, 2021
1 parent bb15fa8 commit 8f2db6c
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 103 deletions.
1 change: 1 addition & 0 deletions docs/INTRODUCTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Introduction
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@reduxjs/toolkit": "^1.5.1",
"@sushiswap/core": "^2.0.0-canary.0",
"@sushiswap/default-token-list": "^6.14.0",
"@sushiswap/sdk": "^5.0.0-canary.11",
"@sushiswap/sdk": "^5.0.0-canary.12",
"@sushiswap/sushi-data": "^1.0.24",
"@transak/transak-sdk": "^1.0.28",
"@uniswap/governance": "^1.0.2",
Expand Down
2 changes: 2 additions & 0 deletions src/components/CurrencyLogo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const logo: { readonly [chainId in ChainId]?: string } = {
[ChainId.HARMONY_TESTNET]: HarmonyLogo,
[ChainId.OKEX]: OKExLogo,
[ChainId.OKEX_TESTNET]: OKExLogo,
[ChainId.ARBITRUM]: EthereumLogo,
[ChainId.ARBITRUM_TESTNET]: EthereumLogo,
}

interface CurrencyLogoProps {
Expand Down
69 changes: 53 additions & 16 deletions src/components/NetworkModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { NETWORK_ICON, NETWORK_LABEL } from '../../constants/networks'
import { useModalOpen, useNetworkModalToggle } from '../../state/application/hooks'
import {
useModalOpen,
useNetworkModalToggle,
} from '../../state/application/hooks'

import { ApplicationModal } from '../../state/application/actions'
import { ChainId } from '@sushiswap/sdk'
Expand Down Expand Up @@ -120,6 +123,17 @@ const PARAMS: {
rpcUrls: ['https://exchainrpc.okex.org'],
blockExplorerUrls: ['https://www.oklink.com/okexchain'],
},
[ChainId.ARBITRUM]: {
chainId: '0xA4B1',
chainName: 'Arbitrum',
nativeCurrency: {
name: 'Ethereum',
symbol: 'ETH',
decimals: 18,
},
rpcUrls: ['https://arb1.arbitrum.io/rpc'],
blockExplorerUrls: ['https://mainnet-arb-explorer.netlify.app'],
},
}

export default function NetworkModal(): JSX.Element | null {
Expand All @@ -131,34 +145,48 @@ export default function NetworkModal(): JSX.Element | null {

return (
<Modal isOpen={networkModalOpen} onDismiss={toggleNetworkModal}>
<ModalHeader onClose={toggleNetworkModal} title="Select a Network" />
<div className="text-lg text-primary mb-6">
You are currently browsing <span className="font-bold text-pink">SUSHI</span>
<br /> on the <span className="font-bold text-blue">{NETWORK_LABEL[chainId]}</span> network
<ModalHeader
onClose={toggleNetworkModal}
title="Select a Network"
/>
<div className="mb-6 text-lg text-primary">
You are currently browsing{' '}
<span className="font-bold text-pink">SUSHI</span>
<br /> on the{' '}
<span className="font-bold text-blue">
{NETWORK_LABEL[chainId]}
</span>{' '}
network
</div>

<div className="flex flex-col space-y-5 overflow-y-auto">
{[
ChainId.MAINNET,
ChainId.FANTOM,
ChainId.BSC,
ChainId.MATIC,
ChainId.FANTOM,
ChainId.ARBITRUM,
ChainId.OKEX,
ChainId.HECO,
ChainId.BSC,
ChainId.XDAI,
ChainId.HARMONY,
ChainId.AVALANCHE,
ChainId.OKEX,
].map((key: ChainId, i: number) => {
if (chainId === key) {
return (
<button key={i} className="bg-gradient-to-r from-blue to-pink w-full rounded p-px">
<div className="flex items-center h-full w-full bg-dark-1000 rounded p-3">
<button
key={i}
className="w-full p-px rounded bg-gradient-to-r from-blue to-pink"
>
<div className="flex items-center w-full h-full p-3 rounded bg-dark-1000">
<img
src={NETWORK_ICON[key]}
alt="Switch Network"
className="rounded-md mr-3 w-8 h-8"
className="w-8 h-8 mr-3 rounded-md"
/>
<div className="text-primary font-bold">{NETWORK_LABEL[key]}</div>
<div className="font-bold text-primary">
{NETWORK_LABEL[key]}
</div>
</div>
</button>
)
Expand All @@ -169,12 +197,21 @@ export default function NetworkModal(): JSX.Element | null {
onClick={() => {
toggleNetworkModal()
const params = PARAMS[key]
library?.send('wallet_addEthereumChain', [params, account])
library?.send('wallet_addEthereumChain', [
params,
account,
])
}}
className="flex items-center bg-dark-800 hover:bg-dark-700 w-full rounded p-3 cursor-pointer"
className="flex items-center w-full p-3 rounded cursor-pointer bg-dark-800 hover:bg-dark-700"
>
<img src={NETWORK_ICON[key]} alt="Switch Network" className="rounded-md mr-2 w-8 h-8" />
<div className="text-primary font-bold">{NETWORK_LABEL[key]}</div>
<img
src={NETWORK_ICON[key]}
alt="Switch Network"
className="w-8 h-8 mr-2 rounded-md"
/>
<div className="font-bold text-primary">
{NETWORK_LABEL[key]}
</div>
</button>
)
})}
Expand Down
90 changes: 71 additions & 19 deletions src/connectors/NetworkConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ type AsyncSendable = {
isMetaMask?: boolean
host?: string
path?: string
sendAsync?: (request: any, callback: (error: any, response: any) => void) => void
sendAsync?: (
request: any,
callback: (error: any, response: any) => void
) => void
send?: (request: any, callback: (error: any, response: any) => void) => void
}

Expand Down Expand Up @@ -43,6 +46,7 @@ class MiniRpcProvider implements AsyncSendable {
constructor(chainId: number, url: string, batchWaitTimeMs?: number) {
this.chainId = chainId
this.url = url
console.log({ chainId, url })
const parsed = new URL(url)
this.host = parsed.host
this.path = parsed.pathname
Expand All @@ -59,17 +63,27 @@ class MiniRpcProvider implements AsyncSendable {
try {
response = await fetch(this.url, {
method: 'POST',
headers: { 'content-type': 'application/json', accept: 'application/json' },
headers: {
'content-type': 'application/json',
accept: 'application/json',
},
body: JSON.stringify(batch.map((item) => item.request)),
})
} catch (error) {
batch.forEach(({ reject }) => reject(new Error('Failed to send batch call')))
batch.forEach(({ reject }) =>
reject(new Error('Failed to send batch call'))
)
return
}

if (!response.ok) {
batch.forEach(({ reject }) =>
reject(new RequestError(`${response.status}: ${response.statusText}`, -32000))
reject(
new RequestError(
`${response.status}: ${response.statusText}`,
-32000
)
)
)
return
}
Expand All @@ -78,13 +92,18 @@ class MiniRpcProvider implements AsyncSendable {
try {
json = await response.json()
} catch (error) {
batch.forEach(({ reject }) => reject(new Error('Failed to parse JSON response')))
batch.forEach(({ reject }) =>
reject(new Error('Failed to parse JSON response'))
)
return
}
const byKey = batch.reduce<{ [id: number]: BatchItem }>((memo, current) => {
memo[current.request.id] = current
return memo
}, {})
const byKey = batch.reduce<{ [id: number]: BatchItem }>(
(memo, current) => {
memo[current.request.id] = current
return memo
},
{}
)
for (const result of json) {
const {
resolve,
Expand All @@ -93,24 +112,41 @@ class MiniRpcProvider implements AsyncSendable {
} = byKey[result.id]
if (resolve && reject) {
if ('error' in result) {
reject(new RequestError(result?.error?.message, result?.error?.code, result?.error?.data))
reject(
new RequestError(
result?.error?.message,
result?.error?.code,
result?.error?.data
)
)
} else if ('result' in result) {
resolve(result.result)
} else {
reject(
new RequestError(`Received unexpected JSON-RPC response to ${method} request.`, -32000, result)
new RequestError(
`Received unexpected JSON-RPC response to ${method} request.`,
-32000,
result
)
)
}
}
}
}

public readonly sendAsync = (
request: { jsonrpc: '2.0'; id: number | string | null; method: string; params?: unknown[] | object },
request: {
jsonrpc: '2.0'
id: number | string | null
method: string
params?: unknown[] | object
},
callback: (error: any, response: any) => void
): void => {
this.request(request.method, request.params)
.then((result) => callback(null, { jsonrpc: '2.0', id: request.id, result }))
.then((result) =>
callback(null, { jsonrpc: '2.0', id: request.id, result })
)
.catch((error) => callback(error, null))
}

Expand All @@ -136,7 +172,9 @@ class MiniRpcProvider implements AsyncSendable {
reject,
})
})
this.batchTimeoutId = this.batchTimeoutId ?? setTimeout(this.clearBatch, this.batchWaitTimeMs)
this.batchTimeoutId =
this.batchTimeoutId ??
setTimeout(this.clearBatch, this.batchWaitTimeMs)
return promise
}
}
Expand All @@ -146,12 +184,22 @@ export class NetworkConnector extends AbstractConnector {
private currentChainId: number

constructor({ urls, defaultChainId }: NetworkConnectorArguments) {
invariant(defaultChainId || Object.keys(urls).length === 1, 'defaultChainId is a required argument with >1 url')
super({ supportedChainIds: Object.keys(urls).map((k): number => Number(k)) })
invariant(
defaultChainId || Object.keys(urls).length === 1,
'defaultChainId is a required argument with >1 url'
)
super({
supportedChainIds: Object.keys(urls).map((k): number => Number(k)),
})

this.currentChainId = defaultChainId || Number(Object.keys(urls)[0])
this.providers = Object.keys(urls).reduce<{ [chainId: number]: MiniRpcProvider }>((accumulator, chainId) => {
accumulator[Number(chainId)] = new MiniRpcProvider(Number(chainId), urls[Number(chainId)])
this.providers = Object.keys(urls).reduce<{
[chainId: number]: MiniRpcProvider
}>((accumulator, chainId) => {
accumulator[Number(chainId)] = new MiniRpcProvider(
Number(chainId),
urls[Number(chainId)]
)
return accumulator
}, {})
}
Expand All @@ -161,7 +209,11 @@ export class NetworkConnector extends AbstractConnector {
}

public async activate(): Promise<ConnectorUpdate> {
return { provider: this.providers[this.currentChainId], chainId: this.currentChainId, account: null }
return {
provider: this.providers[this.currentChainId],
chainId: this.currentChainId,
account: null,
}
}

public async getProvider(): Promise<MiniRpcProvider> {
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const RPC = {
[ChainId.HARMONY_TESTNET]: 'https://explorer.pops.one',
[ChainId.OKEX]: 'https://exchainrpc.okex.org',
[ChainId.OKEX_TESTNET]: 'https://exchaintestrpc.okex.org',
[ChainId.ARBITRUM]: 'https://arb1.arbitrum.io/rpc',
}

export const network = new NetworkConnector({
Expand Down Expand Up @@ -84,6 +85,7 @@ export const injected = new InjectedConnector({
1666700000, // harmony testnet
66, // okex testnet
65, // okex testnet
42161, // arbitrum
],
})

Expand Down
3 changes: 2 additions & 1 deletion src/constants/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChainId } from '@sushiswap/sdk'

// TODO: Should be a simple mapping ZAPPER_ADDRESS[chainId]
export const getZapperAddress = (chainId: ChainId | undefined) => {
let address: string | undefined
if (chainId) {
Expand All @@ -13,4 +14,4 @@ export const getZapperAddress = (chainId: ChainId | undefined) => {
}
}
return address
}
}
5 changes: 5 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const WRAPPED_NATIVE_ONLY: ChainTokenList = {
[ChainId.XDAI]: [WETH[ChainId.XDAI]],
[ChainId.BSC]: [WETH[ChainId.BSC]],
[ChainId.BSC_TESTNET]: [WETH[ChainId.BSC_TESTNET]],
[ChainId.ARBITRUM]: [WETH[ChainId.ARBITRUM]],
[ChainId.ARBITRUM_TESTNET]: [WETH[ChainId.ARBITRUM_TESTNET]],
[ChainId.MOONBEAM_TESTNET]: [WETH[ChainId.MOONBEAM_TESTNET]],
[ChainId.AVALANCHE]: [WETH[ChainId.AVALANCHE]],
Expand Down Expand Up @@ -336,6 +337,7 @@ export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
BSC.USDT,
BSC.BTCB,
],
[ChainId.ARBITRUM]: [...WRAPPED_NATIVE_ONLY[ChainId.ARBITRUM]],
}

export const CREAM = new Token(
Expand Down Expand Up @@ -525,6 +527,7 @@ export const SUGGESTED_BASES: ChainTokenList = {
BSC.USDT,
BSC.BTCB,
],
[ChainId.ARBITRUM]: [...WRAPPED_NATIVE_ONLY[ChainId.ARBITRUM]],
}

// used to construct the list of all pairs we consider by default in the frontend
Expand Down Expand Up @@ -560,6 +563,7 @@ export const BASES_TO_TRACK_LIQUIDITY_FOR: ChainTokenList = {
BSC.USDT,
BSC.BTCB,
],
[ChainId.ARBITRUM]: [...WRAPPED_NATIVE_ONLY[ChainId.ARBITRUM]],
}

export const PINNED_PAIRS: {
Expand Down Expand Up @@ -771,4 +775,5 @@ export const ANALYTICS_URL: { [chainId in ChainId]?: string } = {
[ChainId.FANTOM]: 'https://analytics-ftm.sushi.com',
[ChainId.BSC]: 'https://analytics-bsc.sushi.com',
[ChainId.XDAI]: 'https://analytics-xdai.sushi.com',
[ChainId.ARBITRUM]: undefined,
}
3 changes: 2 additions & 1 deletion src/constants/multicall/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const MULTICALL_NETWORKS: { [chainId in ChainId]: string } = {
[ChainId.XDAI]: '0xb5b692a88BDFc81ca69dcB1d924f59f0413A602a',
[ChainId.BSC]: '0xe348b292e8eA5FAB54340656f3D374b259D658b8',
[ChainId.BSC_TESTNET]: '0xe348b292e8eA5FAB54340656f3D374b259D658b8',
[ChainId.ARBITRUM]: '0xF718F2bd590E5621e53f7b89398e52f7Acced8ca',
[ChainId.ARBITRUM_TESTNET]: '0xBEee73F7f7d4848E1700135ff795960F2Aba66DB',
[ChainId.MOONBEAM_TESTNET]: '0x9B7D5fa91b4747031d8E7807DaEC906F0f683E78',
[ChainId.AVALANCHE]: '0x0FB54156B496b5a040b51A71817aED9e2927912E',
Expand All @@ -23,7 +24,7 @@ const MULTICALL_NETWORKS: { [chainId in ChainId]: string } = {
[ChainId.HARMONY]: '0xFE4980f62D708c2A84D3929859Ea226340759320',
[ChainId.HARMONY_TESTNET]: '0xbcd3451992B923531615293Cb2b2c38ba8DE9529',
[ChainId.OKEX]: '0x0769fd68dFb93167989C6f7254cd0D766Fb2841F',
[ChainId.OKEX_TESTNET]: '0x0769fd68dFb93167989C6f7254cd0D766Fb2841F'
[ChainId.OKEX_TESTNET]: '0x0769fd68dFb93167989C6f7254cd0D766Fb2841F',
}

export { MULTICALL_ABI, MULTICALL_NETWORKS }
Loading

0 comments on commit 8f2db6c

Please sign in to comment.