Skip to content

Commit

Permalink
feat(multichain): Add Polygon and Base (#5165)
Browse files Browse the repository at this point in the history
### Description

Add Polygon and Base to wallet 

### Test plan

builds

everything behind feature gate

### Related issues

- Fixes #ACT-1121

### Backwards compatibility

Yes

### Network scalability

If a new NetworkId and/or Network are added in the future, the changes
in this PR will:

- [X] Continue to work without code changes, OR trigger a compilation
error (guaranteeing we find it when a new network is added)
  • Loading branch information
finnian0826 committed Mar 29, 2024
1 parent 03d2f21 commit a503851
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 2 deletions.
2 changes: 2 additions & 0 deletions locales/base/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,8 @@
"viewOnArbiscan": "View on Arbiscan",
"viewOnOPMainnetExplorer": "View on OP Mainnet Explorer",
"viewOnOPSepoliaExplorer": "View on OP Sepolia Explorer",
"viewOnPolygonPoSScan": "View on PolygonScan",
"viewOnBaseScan": "View on BaseScan",
"sendEnterAmountScreen": {
"title": "Enter Amount",
"selectToken": "Select a Token",
Expand Down
Binary file modified secrets.json.enc
Binary file not shown.
12 changes: 11 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { CachesDirectoryPath } from 'react-native-fs'
import { SpendMerchant } from 'src/fiatExchanges/Spend'
import { LoggerLevel } from 'src/utils/LoggerLevels'
// eslint-disable-next-line import/no-relative-packages
import { TORUS_SAPPHIRE_NETWORK } from '@toruslabs/constants'
import * as secretsFile from '../secrets.json'
import { ONE_HOUR_IN_MILLIS } from './utils/time'
import { TORUS_SAPPHIRE_NETWORK } from '@toruslabs/constants'
export * from 'src/brandingConfig'

// extract secrets from secrets.json
Expand Down Expand Up @@ -122,6 +122,16 @@ export const ALCHEMY_OPTIMISM_API_KEY = keyOrUndefined(
DEFAULT_TESTNET,
'ALCHEMY_OPTIMISM_API_KEY'
)
export const ALCHEMY_POLYGON_POS_API_KEY = keyOrUndefined(
secretsFile,
DEFAULT_TESTNET,
'ALCHEMY_POLYGON_POS_API_KEY'
)
export const ALCHEMY_BASE_API_KEY = keyOrUndefined(
secretsFile,
DEFAULT_TESTNET,
'ALCHEMY_BASE_API_KEY'
)

export const ZENDESK_API_KEY = keyOrUndefined(secretsFile, DEFAULT_TESTNET, 'ZENDESK_API_KEY')
export const STATSIG_API_KEY =
Expand Down
4 changes: 4 additions & 0 deletions src/nfts/NftsInfoCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ export default function NftsInfoCarousel({ route }: Props) {
[NetworkId['arbitrum-sepolia']]: t('viewOnArbiscan'),
[NetworkId['op-mainnet']]: t('viewOnOPMainnetExplorer'),
[NetworkId['op-sepolia']]: t('viewOnOPSepoliaExplorer'),
[NetworkId['polygon-pos-mainnet']]: t('viewOnPolygonPoSScan'),
[NetworkId['polygon-pos-mumbai']]: t('viewOnPolygonPoSScan'),
[NetworkId['base-mainnet']]: t('viewOnBaseScan'),
[NetworkId['base-sepolia']]: t('viewOnBaseScan'),
}

return (
Expand Down
4 changes: 4 additions & 0 deletions src/shared/conts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ export const NETWORK_NAMES: Record<NetworkId, string> = {
[NetworkId['arbitrum-sepolia']]: 'Arbitrum Sepolia',
[NetworkId['op-mainnet']]: 'Optimism',
[NetworkId['op-sepolia']]: 'Optimism Sepolia',
[NetworkId['polygon-pos-mainnet']]: 'Polygon',
[NetworkId['polygon-pos-mumbai']]: 'Polygon Mumbai',
[NetworkId['base-mainnet']]: 'Base',
[NetworkId['base-sepolia']]: 'Base Sepolia',
}
4 changes: 4 additions & 0 deletions src/transactions/feed/TransactionDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ function TransactionDetails({ transaction, title, children, retryHandler }: Prop
[NetworkId['arbitrum-sepolia']]: t('viewOnArbiscan'),
[NetworkId['op-mainnet']]: t('viewOnOPMainnetExplorer'),
[NetworkId['op-sepolia']]: t('viewOnOPSepoliaExplorer'),
[NetworkId['polygon-pos-mainnet']]: t('viewOnPolygonPoSScan'),
[NetworkId['polygon-pos-mumbai']]: t('viewOnPolygonPoSScan'),
[NetworkId['base-mainnet']]: t('viewOnBaseScan'),
[NetworkId['base-sepolia']]: t('viewOnBaseScan'),
}

return (
Expand Down
2 changes: 2 additions & 0 deletions src/transactions/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const WATCHING_DELAY_BY_NETWORK: Record<Network, number> = {
[Network.Ethereum]: 15000,
[Network.Arbitrum]: 2000,
[Network.Optimism]: 2000,
[Network.PolygonPoS]: 2000,
[Network.Base]: 2000,
}
const MIN_WATCHING_DELAY_MS = 2000

Expand Down
6 changes: 6 additions & 0 deletions src/transactions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export enum Network {
Ethereum = 'ethereum',
Arbitrum = 'arbitrum',
Optimism = 'optimism',
PolygonPoS = 'polygon-pos',
Base = 'base',
}

export enum NetworkId {
Expand All @@ -18,6 +20,10 @@ export enum NetworkId {
'arbitrum-sepolia' = 'arbitrum-sepolia',
'op-mainnet' = 'op-mainnet',
'op-sepolia' = 'op-sepolia',
'polygon-pos-mainnet' = 'polygon-pos-mainnet',
'polygon-pos-mumbai' = 'polygon-pos-mumbai',
'base-mainnet' = 'base-mainnet',
'base-sepolia' = 'base-sepolia',
}

export type PendingStandbySwap = {
Expand Down
24 changes: 24 additions & 0 deletions src/viem/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {
ALCHEMY_ARBITRUM_API_KEY,
ALCHEMY_BASE_API_KEY,
ALCHEMY_ETHEREUM_API_KEY,
ALCHEMY_OPTIMISM_API_KEY,
ALCHEMY_POLYGON_POS_API_KEY,
} from 'src/config'
import { Network } from 'src/transactions/types'
import networkConfig from 'src/web3/networkConfig'
Expand Down Expand Up @@ -30,6 +32,20 @@ export const viemTransports: Record<Network, Transport> = {
},
},
}),
[Network.PolygonPoS]: http(networkConfig.alchemyRpcUrl[Network.PolygonPoS], {
fetchOptions: {
headers: {
Authorization: `Bearer ${ALCHEMY_POLYGON_POS_API_KEY}`,
},
},
}),
[Network.Base]: http(networkConfig.alchemyRpcUrl[Network.Base], {
fetchOptions: {
headers: {
Authorization: `Bearer ${ALCHEMY_BASE_API_KEY}`,
},
},
}),
}

export const publicClient = {
Expand All @@ -49,4 +65,12 @@ export const publicClient = {
chain: networkConfig.viemChain.optimism,
transport: viemTransports[Network.Optimism],
}),
[Network.PolygonPoS]: createPublicClient({
chain: networkConfig.viemChain['polygon-pos'],
transport: viemTransports[Network.PolygonPoS],
}),
[Network.Base]: createPublicClient({
chain: networkConfig.viemChain.base,
transport: viemTransports[Network.Base],
}),
}
60 changes: 60 additions & 0 deletions src/web3/networkConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import {
Chain as ViemChain,
arbitrum,
arbitrumSepolia,
base,
baseSepolia,
celo,
celoAlfajores,
mainnet as ethereum,
sepolia as ethereumSepolia,
optimism,
optimismSepolia,
polygon,
polygonMumbai,
} from 'viem/chains'

export enum Testnets {
Expand Down Expand Up @@ -92,6 +96,12 @@ const ALCHEMY_ARBITRUM_RPC_URL_MAINNET = 'https://arb-mainnet.g.alchemy.com/v2/'
const ALCHEMY_OPTIMISM_RPC_URL_STAGING = 'https://opt-sepolia.g.alchemy.com/v2/'
const ALCHEMY_OPTIMISM_RPC_URL_MAINNET = 'https://opt-mainnet.g.alchemy.com/v2/'

const ALCHEMY_POLYGON_POS_RPC_URL_STAGING = 'https://polygon-mumbai.g.alchemy.com/v2/'
const ALCHEMY_POLYGON_POS_RPC_URL_MAINNET = 'https://polygon-mainnet.g.alchemy.com/v2/'

const ALCHEMY_BASE_RPC_URL_STAGING = 'https://base-sepolia.g.alchemy.com/v2/'
const ALCHEMY_BASE_RPC_URL_MAINNET = 'https://base-mainnet.g.alchemy.com/v2/'

export type BlockExplorerUrls = {
[key in NetworkId]: {
baseTxUrl: string
Expand Down Expand Up @@ -244,6 +254,8 @@ const networkConfigs: { [testnet: string]: NetworkConfig } = {
[Network.Ethereum]: NetworkId['ethereum-sepolia'],
[Network.Arbitrum]: NetworkId['arbitrum-sepolia'],
[Network.Optimism]: NetworkId['op-sepolia'],
[Network.PolygonPoS]: NetworkId['polygon-pos-mumbai'],
[Network.Base]: NetworkId['base-sepolia'],
},
defaultNetworkId: NetworkId['celo-alfajores'],
// blockchainApiUrl: 'http://127.0.0.1:8080',
Expand Down Expand Up @@ -297,6 +309,8 @@ const networkConfigs: { [testnet: string]: NetworkConfig } = {
[Network.Ethereum]: ethereumSepolia,
[Network.Arbitrum]: arbitrumSepolia,
[Network.Optimism]: optimismSepolia,
[Network.PolygonPoS]: polygonMumbai,
[Network.Base]: baseSepolia,
},
currencyToTokenId: {
[CiCoCurrency.CELO]: CELO_TOKEN_ID_STAGING,
Expand All @@ -312,6 +326,8 @@ const networkConfigs: { [testnet: string]: NetworkConfig } = {
[Network.Ethereum]: ALCHEMY_ETHEREUM_RPC_URL_STAGING,
[Network.Arbitrum]: ALCHEMY_ARBITRUM_RPC_URL_STAGING,
[Network.Optimism]: ALCHEMY_OPTIMISM_RPC_URL_STAGING,
[Network.PolygonPoS]: ALCHEMY_POLYGON_POS_RPC_URL_STAGING,
[Network.Base]: ALCHEMY_BASE_RPC_URL_STAGING,
},
cusdTokenId: CUSD_TOKEN_ID_STAGING,
ceurTokenId: CEUR_TOKEN_ID_STAGING,
Expand All @@ -327,6 +343,8 @@ const networkConfigs: { [testnet: string]: NetworkConfig } = {
[Network.Ethereum]: NetworkId['ethereum-mainnet'],
[Network.Arbitrum]: NetworkId['arbitrum-one'],
[Network.Optimism]: NetworkId['op-mainnet'],
[Network.PolygonPoS]: NetworkId['polygon-pos-mainnet'],
[Network.Base]: NetworkId['base-mainnet'],
},
defaultNetworkId: NetworkId['celo-mainnet'],
blockchainApiUrl: BLOCKCHAIN_API_MAINNET,
Expand Down Expand Up @@ -379,6 +397,8 @@ const networkConfigs: { [testnet: string]: NetworkConfig } = {
[Network.Ethereum]: ethereum,
[Network.Arbitrum]: arbitrum,
[Network.Optimism]: optimism,
[Network.PolygonPoS]: polygon,
[Network.Base]: base,
},
currencyToTokenId: {
[CiCoCurrency.CELO]: CELO_TOKEN_ID_MAINNET,
Expand All @@ -394,6 +414,8 @@ const networkConfigs: { [testnet: string]: NetworkConfig } = {
[Network.Ethereum]: ALCHEMY_ETHEREUM_RPC_URL_MAINNET,
[Network.Arbitrum]: ALCHEMY_ARBITRUM_RPC_URL_MAINNET,
[Network.Optimism]: ALCHEMY_OPTIMISM_RPC_URL_MAINNET,
[Network.PolygonPoS]: ALCHEMY_POLYGON_POS_RPC_URL_MAINNET,
[Network.Base]: ALCHEMY_BASE_RPC_URL_MAINNET,
},
cusdTokenId: CUSD_TOKEN_ID_MAINNET,
ceurTokenId: CEUR_TOKEN_ID_MAINNET,
Expand All @@ -416,6 +438,12 @@ const ARBISCAN_BASE_URL_SEPOLIA = 'https://sepolia.arbiscan.io'
const OP_MAINNET_EXPLORER_BASE_URL = 'https://optimistic.etherscan.io/'
const OP_SEPOLIA_EXPLORER_BASE_URL = 'https://sepolia-optimism.etherscan.io/'

const POLYGON_POS_BASE_URL_MUMBAI = 'https://mumbai.polygonscan.com/'
const POLYGON_POS_BASE_URL_MAINNET = 'https://polygonscan.com/'

const BASE_BASE_URL_SEPOLIA = 'https://sepolia.basescan.org/'
const BASE_BASE_URL_MAINNET = 'https://basescan.org/'

export const blockExplorerUrls: BlockExplorerUrls = {
[NetworkId['celo-mainnet']]: {
baseTxUrl: `${CELOSCAN_BASE_URL_MAINNET}/tx/`,
Expand Down Expand Up @@ -465,6 +493,30 @@ export const blockExplorerUrls: BlockExplorerUrls = {
baseTokenUrl: `${OP_SEPOLIA_EXPLORER_BASE_URL}/token/`,
baseNftUrl: `${OP_SEPOLIA_EXPLORER_BASE_URL}/token/`,
},
[NetworkId['polygon-pos-mainnet']]: {
baseTxUrl: `${POLYGON_POS_BASE_URL_MAINNET}/tx/`,
baseAddressUrl: `${POLYGON_POS_BASE_URL_MAINNET}/address/`,
baseTokenUrl: `${POLYGON_POS_BASE_URL_MAINNET}/token/`,
baseNftUrl: `${POLYGON_POS_BASE_URL_MAINNET}/token/`,
},
[NetworkId['polygon-pos-mumbai']]: {
baseTxUrl: `${POLYGON_POS_BASE_URL_MUMBAI}/tx/`,
baseAddressUrl: `${POLYGON_POS_BASE_URL_MUMBAI}/address/`,
baseTokenUrl: `${POLYGON_POS_BASE_URL_MUMBAI}/token/`,
baseNftUrl: `${POLYGON_POS_BASE_URL_MUMBAI}/token/`,
},
[NetworkId['base-mainnet']]: {
baseTxUrl: `${BASE_BASE_URL_MAINNET}/tx/`,
baseAddressUrl: `${BASE_BASE_URL_MAINNET}/address/`,
baseTokenUrl: `${BASE_BASE_URL_MAINNET}/token/`,
baseNftUrl: `${BASE_BASE_URL_MAINNET}/token/`,
},
[NetworkId['base-sepolia']]: {
baseTxUrl: `${BASE_BASE_URL_SEPOLIA}/tx/`,
baseAddressUrl: `${BASE_BASE_URL_SEPOLIA}/address/`,
baseTokenUrl: `${BASE_BASE_URL_SEPOLIA}/token/`,
baseNftUrl: `${BASE_BASE_URL_SEPOLIA}/token/`,
},
}

export const networkIdToNetwork: NetworkIdToNetwork = {
Expand All @@ -476,6 +528,10 @@ export const networkIdToNetwork: NetworkIdToNetwork = {
[NetworkId['arbitrum-sepolia']]: Network.Arbitrum,
[NetworkId['op-mainnet']]: Network.Optimism,
[NetworkId['op-sepolia']]: Network.Optimism,
[NetworkId['polygon-pos-mainnet']]: Network.PolygonPoS,
[NetworkId['polygon-pos-mumbai']]: Network.PolygonPoS,
[NetworkId['base-mainnet']]: Network.Base,
[NetworkId['base-sepolia']]: Network.Base,
}

export const networkIdToWalletConnectChainId: Record<NetworkId, string> = {
Expand All @@ -487,6 +543,10 @@ export const networkIdToWalletConnectChainId: Record<NetworkId, string> = {
[NetworkId['arbitrum-sepolia']]: 'eip155:421614',
[NetworkId['op-mainnet']]: 'eip155:10',
[NetworkId['op-sepolia']]: 'eip155:11155420',
[NetworkId['polygon-pos-mainnet']]: 'eip155:137',
[NetworkId['polygon-pos-mumbai']]: 'eip155:80001',
[NetworkId['base-mainnet']]: 'eip155:8453',
[NetworkId['base-sepolia']]: 'eip155:84531',
}

export const walletConnectChainIdToNetworkId: Record<string, NetworkId> = _.invert(
Expand Down
30 changes: 29 additions & 1 deletion test/RootStateSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1608,12 +1608,16 @@
"enum": [
"arbitrum-one",
"arbitrum-sepolia",
"base-mainnet",
"base-sepolia",
"celo-alfajores",
"celo-mainnet",
"ethereum-mainnet",
"ethereum-sepolia",
"op-mainnet",
"op-sepolia"
"op-sepolia",
"polygon-pos-mainnet",
"polygon-pos-mumbai"
],
"type": "string"
},
Expand Down Expand Up @@ -5028,6 +5032,18 @@
},
"type": "array"
},
"base-mainnet": {
"items": {
"$ref": "#/definitions/TokenTransaction"
},
"type": "array"
},
"base-sepolia": {
"items": {
"$ref": "#/definitions/TokenTransaction"
},
"type": "array"
},
"celo-alfajores": {
"items": {
"$ref": "#/definitions/TokenTransaction"
Expand Down Expand Up @@ -5063,6 +5079,18 @@
"$ref": "#/definitions/TokenTransaction"
},
"type": "array"
},
"polygon-pos-mainnet": {
"items": {
"$ref": "#/definitions/TokenTransaction"
},
"type": "array"
},
"polygon-pos-mumbai": {
"items": {
"$ref": "#/definitions/TokenTransaction"
},
"type": "array"
}
},
"type": "object"
Expand Down

0 comments on commit a503851

Please sign in to comment.