From ff8f824ab91a4a82fa43c2bf041386bcb10dea6e Mon Sep 17 00:00:00 2001 From: John Feras Date: Tue, 30 Jan 2024 16:09:36 -0500 Subject: [PATCH] Change from infura to generic RPC URLS (#636) * Changed unfuraUrl to rpcUrlFromChain in UmbraJs * Switched to use env vars for RPC URLs instead of infura URLs * Switch to RPC URLs for CNS resolution related calls * Updated UmbraJS Umbra.ts with env var names matching frontend usage for consistency * Update .env.example and README.md files for both frontend and umbra-js --------- Co-authored-by: Ben DiFrancesco --- frontend/.env.example | 4 ++++ frontend/README.md | 9 +++++++-- frontend/src/components/models.ts | 22 +++++++++++++++------- frontend/src/utils/address.ts | 27 +++++++++++++++++++++++++-- frontend/src/utils/constants.ts | 4 ++++ frontend/src/utils/payment-links.ts | 3 ++- umbra-js/.env.example | 6 ++++++ umbra-js/README.md | 10 ++++++---- umbra-js/src/classes/Umbra.ts | 22 ++++++++++------------ umbra-js/src/utils/utils.ts | 22 ++++++++++++++++++---- 10 files changed, 97 insertions(+), 32 deletions(-) diff --git a/frontend/.env.example b/frontend/.env.example index 4ec0303b9..c34d8ac41 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -10,6 +10,10 @@ PORTIS_API_KEY=yourKeyHere MAINNET_RPC_URL=yourRpcUrlHere POLYGON_RPC_URL=yourRpcUrlHere +OPTIMISM_RPC_URL=yourRpcUrlHere +GNOSIS_CHAIN_RPC_URL=yourRpcUrlHere +ARBITRUM_ONE_RPC_URL=yourRpcUrlHere +SEPOLIA_RPC_URL=yourSepoliaRpcUrl WALLET_CONNECT_PROJECT_ID=yourId LOG_LEVEL=DEBUG diff --git a/frontend/README.md b/frontend/README.md index efafcf43d..6bc7d5324 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -12,8 +12,13 @@ cp .env.example .env The required parameters are: -`INFURA_ID` - A valid Infura App Identifier
-`BLOCKNATIVE_API_KEY` - A Blocknative API key +`BLOCKNATIVE_API_KEY` - A Blocknative API key
+`MAINNET_RPC_URL` - Network RPC URLs
+`POLYGON_RPC_URL`
+`OPTIMISM_RPC_URL`
+`GNOSIS_CHAIN_RPC_URL`
+`ARBITRUM_ONE_RPC_URL`
+`SEPOLIA_RPC_URL`
Optional parameters are: diff --git a/frontend/src/components/models.ts b/frontend/src/components/models.ts index ad0da1395..8b1800a39 100644 --- a/frontend/src/components/models.ts +++ b/frontend/src/components/models.ts @@ -2,7 +2,15 @@ import { BigNumber } from 'src/utils/ethers'; import { JsonRpcSigner, Web3Provider } from 'src/utils/ethers'; import type { TokenList, TokenInfo } from '@uniswap/token-lists/dist/types'; import { UmbraLogger } from 'components/logger'; -import { ETH_NETWORK_LOGO } from 'src/utils/constants'; +import { + ETH_NETWORK_LOGO, + MAINNET_RPC_URL, + POLYGON_RPC_URL, + OPTIMISM_RPC_URL, + SEPOLIA_RPC_URL, + ARBITRUM_ONE_RPC_URL, + GNOSIS_CHAIN_RPC_URL, +} from 'src/utils/constants'; export type { TokenList, TokenInfo } from '@uniswap/token-lists/dist/types'; export { BigNumber } from 'src/utils/ethers'; @@ -50,7 +58,7 @@ export const supportedChains: Array = [ decimals: 18, logoURI: ETH_NETWORK_LOGO, }, - rpcUrls: [`https://mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`], + rpcUrls: [MAINNET_RPC_URL], blockExplorerUrls: ['https://etherscan.io'], iconUrls: [ETH_NETWORK_LOGO], logoURI: ETH_NETWORK_LOGO, @@ -65,7 +73,7 @@ export const supportedChains: Array = [ decimals: 18, logoURI: ETH_NETWORK_LOGO, }, - rpcUrls: [`https://sepolia.infura.io/v3/${String(process.env.INFURA_ID)}`], + rpcUrls: [SEPOLIA_RPC_URL], blockExplorerUrls: ['https://sepolia.etherscan.io'], iconUrls: [ETH_NETWORK_LOGO], logoURI: ETH_NETWORK_LOGO, @@ -80,7 +88,7 @@ export const supportedChains: Array = [ decimals: 18, logoURI: ETH_NETWORK_LOGO, }, - rpcUrls: ['https://mainnet.optimism.io', `https://optimism-mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`], + rpcUrls: ['https://mainnet.optimism.io', OPTIMISM_RPC_URL], blockExplorerUrls: ['https://optimistic.etherscan.io'], iconUrls: ['/networks/optimism.svg'], logoURI: '/networks/optimism.svg', @@ -95,7 +103,7 @@ export const supportedChains: Array = [ decimals: 18, logoURI: 'https://docs.gnosischain.com/img/tokens/xdai.png', }, - rpcUrls: ['https://rpc.ankr.com/gnosis'], + rpcUrls: ['https://rpc.ankr.com/gnosis', GNOSIS_CHAIN_RPC_URL], blockExplorerUrls: ['https://gnosisscan.io'], iconUrls: ['/networks/gnosis.svg'], logoURI: '/networks/gnosis.svg', @@ -110,7 +118,7 @@ export const supportedChains: Array = [ decimals: 18, logoURI: '/tokens/polygon.png', }, - rpcUrls: ['https://polygon-rpc.com/', `https://polygon-mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`], + rpcUrls: ['https://polygon-rpc.com/', POLYGON_RPC_URL], blockExplorerUrls: ['https://polygonscan.com'], iconUrls: ['/networks/polygon.svg'], logoURI: '/networks/polygon.svg', @@ -125,7 +133,7 @@ export const supportedChains: Array = [ decimals: 18, logoURI: ETH_NETWORK_LOGO, }, - rpcUrls: ['https://arb1.arbitrum.io/rpc', `https://arbitrum-mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`], + rpcUrls: ['https://arb1.arbitrum.io/rpc', ARBITRUM_ONE_RPC_URL], blockExplorerUrls: ['https://arbiscan.io'], iconUrls: ['/networks/arbitrum.svg'], logoURI: '/networks/arbitrum.svg', diff --git a/frontend/src/utils/address.ts b/frontend/src/utils/address.ts index c6ba05974..307822416 100644 --- a/frontend/src/utils/address.ts +++ b/frontend/src/utils/address.ts @@ -16,7 +16,14 @@ import { import { getChainById, jsonFetch } from 'src/utils/utils'; import { tc } from '../boot/i18n'; import Resolution from '@unstoppabledomains/resolution'; -import { MAINNET_PROVIDER, POLYGON_PROVIDER, MULTICALL_ABI, MULTICALL_ADDRESS } from 'src/utils/constants'; +import { + MAINNET_PROVIDER, + POLYGON_PROVIDER, + MULTICALL_ABI, + MULTICALL_ADDRESS, + MAINNET_RPC_URL, + POLYGON_RPC_URL, +} from 'src/utils/constants'; import { AddressZero, defaultAbiCoder } from 'src/utils/ethers'; import { UmbraApi } from 'src/utils/umbra-api'; @@ -49,7 +56,23 @@ export const lookupEnsName = async (address: string, provider: Provider | Static export const lookupCnsName = async (address: string) => { try { // Send request to get names - const resolution = Resolution.infura(String(process.env.INFURA_ID)); + + const resolution = new Resolution({ + sourceConfig: { + uns: { + locations: { + Layer1: { + url: MAINNET_RPC_URL, + network: 'mainnet', + }, + Layer2: { + url: POLYGON_RPC_URL, + network: 'polygon-mainnet', + }, + }, + }, + }, + }); const domain = await resolution.reverse(address); return domain; } catch (err) { diff --git a/frontend/src/utils/constants.ts b/frontend/src/utils/constants.ts index 12074ca68..1be1d2ab3 100644 --- a/frontend/src/utils/constants.ts +++ b/frontend/src/utils/constants.ts @@ -4,6 +4,10 @@ export const MAINNET_RPC_URL = String(process.env.MAINNET_RPC_URL); export const MAINNET_PROVIDER = new StaticJsonRpcProvider(MAINNET_RPC_URL); export const POLYGON_RPC_URL = String(process.env.POLYGON_RPC_URL); export const POLYGON_PROVIDER = new StaticJsonRpcProvider(POLYGON_RPC_URL); +export const OPTIMISM_RPC_URL = String(process.env.OPTIMISM_RPC_URL); +export const ARBITRUM_ONE_RPC_URL = String(process.env.ARBITRUM_ONE_RPC_URL); +export const SEPOLIA_RPC_URL = String(process.env.SEPOLIA_RPC_URL); +export const GNOSIS_CHAIN_RPC_URL = String(process.env.GNOSIS_CHAIN_RPC_URL); console.log(`MAINNET_RPC_URL ${MAINNET_RPC_URL}`); diff --git a/frontend/src/utils/payment-links.ts b/frontend/src/utils/payment-links.ts index 080ec9047..05e463af1 100644 --- a/frontend/src/utils/payment-links.ts +++ b/frontend/src/utils/payment-links.ts @@ -5,12 +5,13 @@ import { providerExport as provider, relayerExport as relayer, tokensExport as t import { notifyUser } from 'src/utils/alerts'; import { BigNumber, StaticJsonRpcProvider } from 'src/utils/ethers'; import { UmbraApi } from 'src/utils/umbra-api'; +import { MAINNET_RPC_URL } from 'src/utils/constants'; /** * @notice Returns a provider, falling back to a mainnet provider if user's wallet is not connected */ function getProvider() { - return provider || new StaticJsonRpcProvider(`https://mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`); + return provider || new StaticJsonRpcProvider(MAINNET_RPC_URL); } /** diff --git a/umbra-js/.env.example b/umbra-js/.env.example index 2db3b6a31..703db851c 100644 --- a/umbra-js/.env.example +++ b/umbra-js/.env.example @@ -4,3 +4,9 @@ POLYGONSCAN_API_KEY=yourPolygonscanApiKey ARBISCAN_API_KEY=yourArbiscanApiKey GNOSISSCAN_API_KEY=yourGnosisSafeScanApiKey INFURA_ID=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz +MAINNET_RPC_URL=yourMainnetRpcUrl +OPTIMISM_RPC_URL=yourOptimismRpcUrl +GNOSIS_CHAIN_RPC_URL=yourGnosisChainRpcUrl +POLYGON_RPC_URL=yourPolygonRpcUrl +ARBITRUM_ONE_RPC_URL=yourArbitrumOneRpcUrl +SEPOLIA_RPC_URL=yourSepoliaRpcUrl diff --git a/umbra-js/README.md b/umbra-js/README.md index 7eacc60bd..6306272ac 100644 --- a/umbra-js/README.md +++ b/umbra-js/README.md @@ -222,9 +222,11 @@ the resulting `umbra-js/docs/index.html` file in your browser to view the docume ## Development -1. Create a file in this directory called `.env` that looks like the one below. - ```bash - INFURA_ID=yourInfuraId - ``` +1. Copy the `.env.example` to `.env` and populate it with your own configuration parameters. + +```bash +cp .env.example .env +``` + 2. Run `yarn` to install packages 3. Run `yarn test` to run all tests. diff --git a/umbra-js/src/classes/Umbra.ts b/umbra-js/src/classes/Umbra.ts index c9806f6b8..e51bd9318 100644 --- a/umbra-js/src/classes/Umbra.ts +++ b/umbra-js/src/classes/Umbra.ts @@ -119,18 +119,18 @@ const isEth = (token: string) => { }; /** - * @notice Returns the Infura RPC URL for the provided chainId and Infura ID + * @notice Returns an RPC URL for the provided chainId */ -const infuraUrl = (chainId: BigNumberish, infuraId: string) => { +const rpcUrlFromChain = (chainId: BigNumberish) => { chainId = BigNumber.from(chainId).toNumber(); // For Hardhat, we just use the mainnet chain ID to avoid errors in tests, but this doesn't affect anything. - if (chainId === 1 || chainId === 1337) return `https://mainnet.infura.io/v3/${infuraId}`; - if (chainId === 10) return `https://optimism-mainnet.infura.io/v3/${infuraId}`; - if (chainId === 100) return 'https://rpc.ankr.com/gnosis'; - if (chainId === 137) return `https://polygon-mainnet.infura.io/v3/${infuraId}`; - if (chainId === 42161) return `https://arbitrum-mainnet.infura.io/v3/${infuraId}`; - if (chainId === 11155111) return `https://sepolia.infura.io/v3/${infuraId}`; - throw new Error(`No Infura URL for chainId ${chainId}.`); + if (chainId === 1 || chainId === 1337) return String(process.env.MAINNET_RPC_URL); + if (chainId === 10) return String(process.env.OPTIMISM_RPC_URL); + if (chainId === 100) return String(process.env.GNOSIS_CHAIN_RPC_URL); + if (chainId === 137) return String(process.env.POLYGON_RPC_URL); + if (chainId === 42161) return String(process.env.ARBITRUM_ONE_RPC_URL); + if (chainId === 11155111) return String(process.env.SEPOLIA_RPC_URL); + throw new Error(`No RPC URL for chainId ${chainId}.`); }; export class Umbra { @@ -154,9 +154,7 @@ export class Umbra { if (this.chainConfig.batchSendAddress) { this.batchSendContract = new Contract(this.chainConfig.batchSendAddress, UMBRA_BATCH_SEND_ABI, provider); } - this.fallbackProvider = new StaticJsonRpcProvider( - infuraUrl(this.chainConfig.chainId, String(process.env.INFURA_ID)) - ); + this.fallbackProvider = new StaticJsonRpcProvider(rpcUrlFromChain(this.chainConfig.chainId)); } // ==================================== CONTRACT INTERACTION ===================================== diff --git a/umbra-js/src/utils/utils.ts b/umbra-js/src/utils/utils.ts index 16b1214c4..617d0ce88 100644 --- a/umbra-js/src/utils/utils.ts +++ b/umbra-js/src/utils/utils.ts @@ -329,7 +329,22 @@ export function isDomain(name: string) { */ function getResolutionInstance() { - return Resolution.infura(String(process.env.INFURA_ID)); + return new Resolution({ + sourceConfig: { + uns: { + locations: { + Layer1: { + url: String(process.env.MAINNET_RPC_URL), + network: 'mainnet', + }, + Layer2: { + url: String(process.env.POLYGON_RPC_URL), + network: 'polygon-mainnet', + }, + }, + }, + }, + }); } /** @@ -345,8 +360,7 @@ async function resolveEns(name: string, provider: EthersProvider) { // and overriding with a mainnet provider otherwise. This ensures ENS resolution is always done // against L1, as explained here: https://twitter.com/makoto_inoue/status/1453737962110275598 const { chainId } = await provider.getNetwork(); - if (chainId !== 1) - provider = new StaticJsonRpcProvider(`https://mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`); + if (chainId !== 1) provider = new StaticJsonRpcProvider(String(process.env.MAINNET_RPC_URL)); const address = await provider.resolveName(name); return address || null; } catch (e) { @@ -536,7 +550,7 @@ export async function checkSupportedAddresses(recipientIds: string[]) { // If there are a lot of ENS or CNS names here this will send too many RPC requests and trigger // errors. The current use case of this method takes addresses, so this should not be a problem. // If it becomes a problem, add a batched version of toAddress. - const provider = new StaticJsonRpcProvider(`https://mainnet.infura.io/v3/${String(process.env.INFURA_ID)}`); + const provider = new StaticJsonRpcProvider(String(process.env.MAINNET_RPC_URL)); const addresses = await Promise.all(recipientIds.map((recipientId) => toAddress(recipientId, provider))); // Initialize output, start by assuming all are supported.