marketsAndNetworksConfig.ts
1 import { ChainId, ChainIdToNetwork } from '@aave/contract-helpers'; 2 import { StaticJsonRpcProvider } from '@ethersproject/providers'; 3 import { ProviderWithSend } from 'src/components/transactions/GovVote/temporary/VotingMachineService'; 4 5 import { 6 CustomMarket, 7 MarketDataType, 8 marketsData as _marketsData, 9 } from '../ui-config/marketsConfig'; 10 import { 11 BaseNetworkConfig, 12 ExplorerLinkBuilderConfig, 13 ExplorerLinkBuilderProps, 14 NetworkConfig, 15 networkConfigs as _networkConfigs, 16 } from '../ui-config/networksConfig'; 17 import { RotationProvider } from './rotationProvider'; 18 import { ServerJsonRpcProvider } from './ServerJsonRpcProvider'; 19 20 export type Pool = { 21 address: string; 22 }; 23 24 export const STAGING_ENV = process.env.NEXT_PUBLIC_ENV === 'staging'; 25 export const PROD_ENV = !process.env.NEXT_PUBLIC_ENV || process.env.NEXT_PUBLIC_ENV === 'prod'; 26 export const ENABLE_TESTNET = 27 PROD_ENV && global?.window?.localStorage.getItem('testnetsEnabled') === 'true'; 28 29 // determines if forks should be shown 30 export const FORK_ENABLED = 31 !!process.env.NEXT_PUBLIC_FORK_URL_RPC || 32 global?.window?.localStorage.getItem('forkEnabled') === 'true'; 33 // specifies which network was forked 34 export const FORK_BASE_CHAIN_ID = 35 Number(process.env.NEXT_PUBLIC_FORK_BASE_CHAIN_ID) || 36 Number(global?.window?.localStorage.getItem('forkBaseChainId') || 1); 37 // specifies on which chainId the fork is running 38 export const FORK_CHAIN_ID = 39 Number(process.env.NEXT_PUBLIC_FORK_CHAIN_ID) || 40 Number(global?.window?.localStorage.getItem('forkNetworkId') || 3030); 41 export const FORK_RPC_URL = 42 process.env.NEXT_PUBLIC_FORK_URL_RPC || 43 global?.window?.localStorage.getItem('forkRPCUrl') || 44 'http://127.0.0.1:8545'; 45 46 /** 47 * Generates network configs based on networkConfigs & fork settings. 48 * Forks will have a rpcOnly clone of their underlying base network config. 49 */ 50 export const networkConfigs = Object.keys(_networkConfigs).reduce((acc, value) => { 51 acc[value] = _networkConfigs[value]; 52 if (FORK_ENABLED && Number(value) === FORK_BASE_CHAIN_ID) { 53 acc[FORK_CHAIN_ID] = { 54 ..._networkConfigs[value], 55 name: `${_networkConfigs[value].name} Fork`, 56 isFork: true, 57 publicJsonRPCUrl: [FORK_RPC_URL], 58 underlyingChainId: FORK_BASE_CHAIN_ID, 59 }; 60 } 61 return acc; 62 }, {} as { [key: string]: BaseNetworkConfig }); 63 64 /** 65 * Generates network configs based on marketsData & fork settings. 66 * Fork markets are generated for all markets on the underlying base chain. 67 */ 68 69 export const marketsData = Object.keys(_marketsData).reduce((acc, value) => { 70 acc[value] = _marketsData[value as keyof typeof CustomMarket]; 71 if ( 72 FORK_ENABLED && 73 _marketsData[value as keyof typeof CustomMarket].chainId === FORK_BASE_CHAIN_ID 74 ) { 75 acc[`fork_${value}`] = { 76 ..._marketsData[value as keyof typeof CustomMarket], 77 chainId: FORK_CHAIN_ID, 78 isFork: true, 79 }; 80 } 81 return acc; 82 }, {} as { [key: string]: MarketDataType }); 83 84 export function getDefaultChainId() { 85 return marketsData[availableMarkets[0]].chainId; 86 } 87 88 export function getSupportedChainIds(): number[] { 89 return Array.from( 90 Object.keys(marketsData) 91 .filter((value) => { 92 const isTestnet = 93 networkConfigs[marketsData[value as keyof typeof CustomMarket].chainId].isTestnet; 94 95 // If this is a staging environment, or the testnet toggle is on, only show testnets 96 if (STAGING_ENV || ENABLE_TESTNET) { 97 return isTestnet; 98 } 99 100 return !isTestnet; 101 }) 102 .reduce( 103 (acc, value) => acc.add(marketsData[value as keyof typeof CustomMarket].chainId), 104 new Set<number>() 105 ) 106 ); 107 } 108 109 /** 110 * selectable markets (markets in a available network + forks when enabled) 111 */ 112 113 export const availableMarkets = Object.keys(marketsData).filter((key) => 114 getSupportedChainIds().includes(marketsData[key as keyof typeof CustomMarket].chainId) 115 ) as CustomMarket[]; 116 117 const linkBuilder = 118 ({ baseUrl, addressPrefix = 'address', txPrefix = 'tx' }: ExplorerLinkBuilderConfig) => 119 ({ tx, address }: ExplorerLinkBuilderProps): string => { 120 if (tx) { 121 return `${baseUrl}/${txPrefix}/${tx}`; 122 } 123 if (address) { 124 return `${baseUrl}/${addressPrefix}/${address}`; 125 } 126 return baseUrl; 127 }; 128 129 export function getNetworkConfig(chainId: ChainId): NetworkConfig { 130 const config = networkConfigs[chainId]; 131 if (!config) { 132 // this case can only ever occure when a wallet is connected with a unknown chainId which will not allow interaction 133 const name = ChainIdToNetwork[chainId]; 134 return { 135 name: name || `unknown chainId: ${chainId}`, 136 } as unknown as NetworkConfig; 137 } 138 return { 139 ...config, 140 explorerLinkBuilder: linkBuilder({ baseUrl: config.explorerLink }), 141 }; 142 } 143 144 export const isFeatureEnabled = { 145 faucet: (data: MarketDataType) => data.enabledFeatures?.faucet, 146 governance: (data: MarketDataType) => data.enabledFeatures?.governance, 147 staking: (data: MarketDataType) => data.enabledFeatures?.staking, 148 liquiditySwap: (data: MarketDataType) => data.enabledFeatures?.liquiditySwap, 149 collateralRepay: (data: MarketDataType) => data.enabledFeatures?.collateralRepay, 150 permissions: (data: MarketDataType) => data.enabledFeatures?.permissions, 151 debtSwitch: (data: MarketDataType) => data.enabledFeatures?.debtSwitch, 152 withdrawAndSwitch: (data: MarketDataType) => data.enabledFeatures?.withdrawAndSwitch, 153 switch: (data: MarketDataType) => data.enabledFeatures?.switch, 154 }; 155 156 const providers: { [network: string]: ProviderWithSend } = {}; 157 158 /** 159 * Created a fallback rpc provider in which providers are prioritized from private to public and in case there are multiple public ones, from top to bottom. 160 * @param chainId 161 * @returns provider or fallbackprovider in case multiple rpcs are configured 162 */ 163 export const getProvider = (chainId: ChainId): ProviderWithSend => { 164 if (!providers[chainId]) { 165 const config = getNetworkConfig(chainId); 166 if ( 167 (FORK_ENABLED && FORK_BASE_CHAIN_ID === chainId) || 168 process.env.NEXT_PUBLIC_PRIVATE_RPC_ENABLED !== 'true' 169 ) { 170 // No private RPC or there is a fork configured, use public ones directly 171 const chainProviders: string[] = []; 172 if (config.publicJsonRPCUrl.length) { 173 config.publicJsonRPCUrl.map((rpc) => chainProviders.push(rpc)); 174 } 175 if (!chainProviders.length) { 176 throw new Error(`${chainId} has no jsonRPCUrl configured`); 177 } 178 if (chainProviders.length === 1) { 179 providers[chainId] = new StaticJsonRpcProvider(chainProviders[0], chainId); 180 } else { 181 providers[chainId] = new RotationProvider(chainProviders, chainId); 182 } 183 } else { 184 providers[chainId] = new ServerJsonRpcProvider(chainId); 185 } 186 } 187 return providers[chainId]; 188 }; 189 190 export const getENSProvider = () => { 191 const chainId = 1; 192 const config = getNetworkConfig(chainId); 193 return new StaticJsonRpcProvider(config.publicJsonRPCUrl[0], chainId); 194 }; 195 196 const ammDisableProposal = 'https://governance-v2.aave.com/governance/proposal/44'; 197 const ustDisableProposal = 'https://governance-v2.aave.com/governance/proposal/75'; 198 const kncDisableProposal = 'https://governance-v2.aave.com/governance/proposal/69'; 199 const v2MainnetDisableProposal = 'https://governance-v2.aave.com/governance/proposal/111'; 200 const v2MainnetDisableProposal2 = 'https://governance-v2.aave.com/governance/proposal/125'; 201 const v2PolygonDisableProposal = 'https://governance-v2.aave.com/governance/proposal/124'; 202 203 export const frozenProposalMap: Record<string, string> = { 204 ['UST' + CustomMarket.proto_mainnet]: ustDisableProposal, 205 ['KNC' + CustomMarket.proto_mainnet]: kncDisableProposal, 206 ['UNIDAIUSDC' + CustomMarket.proto_mainnet]: ammDisableProposal, 207 ['UNIWBTCUSDC' + CustomMarket.proto_mainnet]: ammDisableProposal, 208 ['UNIDAIWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 209 ['UNIUSDCWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 210 ['UNIAAVEWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 211 ['UNIBATWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 212 ['UNICRVWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 213 ['UNILINKWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 214 ['UNIMKRWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 215 ['UNIRENWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 216 ['UNISNXWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 217 ['UNIUNIWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 218 ['UNIWBTCWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 219 ['UNIYFIWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 220 ['BPTWBTCWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 221 ['BPTBALWETH' + CustomMarket.proto_mainnet]: ammDisableProposal, 222 ['BAL' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal, 223 ['CVX' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal, 224 ['REN' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal, 225 ['YFI' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 226 ['CRV' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 227 ['ZRX' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 228 ['MANA' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 229 ['1INCH' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 230 ['BAT' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 231 ['SUSD' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 232 ['ENJ' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 233 ['GUSD' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 234 ['AMPL' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 235 ['RAI' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 236 ['USDP' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 237 ['LUSD' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 238 ['XSUSHI' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 239 ['DPI' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 240 ['RENFIL' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 241 ['MKR' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 242 ['ENS' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 243 ['LINK' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 244 ['UNI' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 245 ['SNX' + CustomMarket.proto_mainnet]: v2MainnetDisableProposal2, 246 ['BAL' + CustomMarket.proto_polygon]: v2PolygonDisableProposal, 247 ['CRV' + CustomMarket.proto_polygon]: v2PolygonDisableProposal, 248 ['DPI' + CustomMarket.proto_polygon]: v2PolygonDisableProposal, 249 ['GHST' + CustomMarket.proto_polygon]: v2PolygonDisableProposal, 250 ['LINK' + CustomMarket.proto_polygon]: v2PolygonDisableProposal, 251 ['XSUSHI' + CustomMarket.proto_polygon]: v2PolygonDisableProposal, 252 }; 253 254 // reexport so we can forbit config import 255 export { CustomMarket }; 256 export type { MarketDataType, NetworkConfig };