diff --git a/aggregators/zrx/index.ts b/aggregators/zrx/index.ts index 774f6db5ef..b3bdee0c23 100644 --- a/aggregators/zrx/index.ts +++ b/aggregators/zrx/index.ts @@ -1,5 +1,6 @@ import { GraphQLClient, gql } from 'graphql-request'; import { getUniqStartOfTodayTimestamp } from '../../helpers/getUniSubgraphVolume'; +import { getEnv } from '../../helpers/env'; const CHAINS = [ 'Arbitrum', @@ -15,10 +16,7 @@ const CHAINS = [ const graphQLClient = new GraphQLClient('https://api.0x.org/data/v0'); const getGQLClient = () => { - graphQLClient.setHeader( - '0x-api-key', - process.env.ZEROx_API_KEY ?? '' - ); + graphQLClient.setHeader('0x-api-key', getEnv('ZEROX_API_KEY')); return graphQLClient; }; diff --git a/dexs/0x/index.ts b/dexs/0x/index.ts index 42534b9006..09a50f2b0f 100644 --- a/dexs/0x/index.ts +++ b/dexs/0x/index.ts @@ -1,6 +1,7 @@ import { gql, GraphQLClient } from "graphql-request"; import { BreakdownAdapter, Fetch, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; +import { getEnv } from "../../helpers/env"; const chains = [CHAIN.ETHEREUM, CHAIN.POLYGON] @@ -32,7 +33,7 @@ const getHistoricalDataQuery = (timestamp: number) => { const graphQLClient = new GraphQLClient("https://api.0x.org/data/v0"); const getGQLClient = () => { - graphQLClient.setHeader("0x-api-key", process.env.ZEROx_API_KEY ?? process.env.ZEROX_API_KEY ?? '') + graphQLClient.setHeader("0x-api-key", getEnv('ZEROX_API_KEY')) return graphQLClient } diff --git a/dexs/SmarDex/index.ts b/dexs/SmarDex/index.ts index 5a08b1fc18..fe070ffdc6 100644 --- a/dexs/SmarDex/index.ts +++ b/dexs/SmarDex/index.ts @@ -6,8 +6,9 @@ import { } from "../../helpers/getUniSubgraph"; import { CHAIN } from "../../helpers/chains"; import { Chain } from "@defillama/sdk/build/general"; +import { getEnv } from "../../helpers/env"; -const SMARDEX_SUBGRAPH_API_KEY = process.env.SMARDEX_SUBGRAPH_API_KEY; +const SMARDEX_SUBGRAPH_API_KEY = getEnv('SMARDEX_SUBGRAPH_API_KEY'); const SMARDEX_SUBGRAPH_GATEWAY = "https://subgraph.smardex.io/defillama"; // if (!SMARDEX_SUBGRAPH_API_KEY) { diff --git a/dexs/perennial-v2/index.ts b/dexs/perennial-v2/index.ts index ec7092830e..290f0a2e23 100644 --- a/dexs/perennial-v2/index.ts +++ b/dexs/perennial-v2/index.ts @@ -2,8 +2,9 @@ import request, { gql } from 'graphql-request' import { BreakdownAdapter, Fetch, SimpleAdapter } from '../../adapters/types' import { CHAIN } from '../../helpers/chains' import { getUniqStartOfTodayTimestamp } from '../../helpers/getUniSubgraphVolume' +import { getEnv } from '../../helpers/env' -const apiKey = process.env.PERENNIAL_V2_SUBGRAPH_API_KEY +const apiKey = getEnv('PERENNIAL_V2_SUBGRAPH_API_KEY') const graphUrls: { [key: string]: string } = { [CHAIN.ARBITRUM]: `https://subgraph.satsuma-prod.com/${apiKey}/equilibria/perennial-v2-arbitrum/api`, } diff --git a/dexs/serum/index.ts b/dexs/serum/index.ts index abb998a372..727f4e7d88 100644 --- a/dexs/serum/index.ts +++ b/dexs/serum/index.ts @@ -2,6 +2,7 @@ import { DISABLED_ADAPTER_KEY, SimpleAdapter } from "../../adapters/types"; import { getUniqStartOfTodayTimestamp } from "../../helpers/getUniSubgraphVolume"; import { gql, GraphQLClient } from "graphql-request"; import disabledAdapter from "../../helpers/disabledAdapter"; +import { getEnv } from "../../helpers/env"; const endpoint = "https://api.vybenetwork.com/v1/graphql"; @@ -18,7 +19,7 @@ const query = gql` const graphQLClient = new GraphQLClient(endpoint); const getGQLClient = () => { - graphQLClient.setHeader("authorization", process.env.PROD_VYBE_API_KEY ?? '') + graphQLClient.setHeader("authorization", getEnv('PROD_VYBE_API_KEY')) return graphQLClient } diff --git a/fees/SmarDex/index.ts b/fees/SmarDex/index.ts index ef54ac28e7..2f42a7b61c 100644 --- a/fees/SmarDex/index.ts +++ b/fees/SmarDex/index.ts @@ -4,8 +4,9 @@ import { request, gql } from "graphql-request"; import BigNumber from "bignumber.js"; import { getTimestampAtStartOfDayUTC } from "../../utils/date"; +import { getEnv } from "../../helpers/env"; -const SMARDEX_SUBGRAPH_API_KEY = process.env.SMARDEX_SUBGRAPH_API_KEY || ""; +const SMARDEX_SUBGRAPH_API_KEY = getEnv('SMARDEX_SUBGRAPH_API_KEY') const SMARDEX_SUBGRAPH_GATEWAY = "https://subgraph.smardex.io/defillama"; // Headers for GraphQL requests that require an API key diff --git a/fees/cardano.ts b/fees/cardano.ts index 1670c7c79e..247fb855cd 100644 --- a/fees/cardano.ts +++ b/fees/cardano.ts @@ -3,6 +3,7 @@ import { IDate } from "../helpers/bitqueryFees"; import { CHAIN } from "../helpers/chains"; import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; import { httpPost } from "../utils/fetchURL"; +import { getEnv } from "../helpers/env"; interface ITxAda { @@ -28,7 +29,7 @@ const adapterQuery = async (form: string, till: string, network: string): Promis variables: value }); - const headers = {"X-API-KEY": process.env.BIT_QUERY_API_KEY || '', "Content-Type": "application/json"}; + const headers = {"X-API-KEY": getEnv('BIT_QUERY_API_KEY'), "Content-Type": "application/json"}; const result: ITxAda[] = (await httpPost("https://graphql.bitquery.io", body, { headers: headers }))?.data.cardano.transactions; return result; diff --git a/helpers/allium.ts b/helpers/allium.ts index 5fa16d8e66..f2405e1e8b 100644 --- a/helpers/allium.ts +++ b/helpers/allium.ts @@ -1,12 +1,13 @@ import retry from "async-retry"; import { IJSON } from "../adapters/types"; import { httpGet, httpPost } from "../utils/fetchURL"; +import { getEnv } from "./env"; const token = {} as IJSON const HEADERS = { "Content-Type": "application/json", - "X-API-KEY": process.env.ALLIUM_API_KEY!, + "X-API-KEY": getEnv('ALLIUM_API_KEY'), }; export async function startAlliumQuery(sqlQuery: string) { diff --git a/helpers/bitqueryFees.ts b/helpers/bitqueryFees.ts index 8979b425b5..6a72a1d80e 100644 --- a/helpers/bitqueryFees.ts +++ b/helpers/bitqueryFees.ts @@ -1,4 +1,5 @@ import { httpPost } from "../utils/fetchURL"; +import { getEnv } from "./env"; interface IDate { date: string; // ex. 2022-01-01 @@ -29,7 +30,7 @@ const adapterBitqueryFeesEthereumNetwork = async (form: string, till: string, ne variables: value }); - const headers = {"X-API-KEY": process.env.BIT_QUERY_API_KEY || '', "Content-Type": "application/json"}; + const headers = {"X-API-KEY": getEnv('BIT_QUERY_API_KEY'), "Content-Type": "application/json"}; const result: ITx[] = (await httpPost("https://graphql.bitquery.io", body, { headers: headers }))?.data.ethereum.transactions; return result; diff --git a/helpers/dune.ts b/helpers/dune.ts index e85b9faf68..624038a23c 100644 --- a/helpers/dune.ts +++ b/helpers/dune.ts @@ -1,11 +1,11 @@ import retry from "async-retry"; import { IJSON } from "../adapters/types"; import { httpGet, httpPost } from "../utils/fetchURL"; +import { getEnv } from "./env"; const token = {} as IJSON -const API_KEYS = process.env.DUNE_API_KEYS?.split(',') ?? ["L0URsn5vwgyrWbBpQo9yS1E3C1DBJpZh"] +const API_KEYS =getEnv('DUNE_API_KEYS').split(',') ?? ["L0URsn5vwgyrWbBpQo9yS1E3C1DBJpZh"] let API_KEY_INDEX = 0; -const MAX_RETRIES = 20; export async function queryDune(queryId: string, query_parameters = {}) { /* const error = new Error("Dune: queryId is required") diff --git a/helpers/duneRequest.ts b/helpers/duneRequest.ts index 61e23dce00..42028f63df 100644 --- a/helpers/duneRequest.ts +++ b/helpers/duneRequest.ts @@ -1,7 +1,8 @@ import retry from "async-retry"; import fetchURL from "../utils/fetchURL"; +import { getEnv } from "./env"; -const API_KEYS = process.env.DUNE_API_KEYS?.split(",") ?? []; +const API_KEYS = getEnv('DUNE_API_KEYS').split(",") ?? []; type IRequest = { [key: string]: Promise; } diff --git a/helpers/env.ts b/helpers/env.ts new file mode 100644 index 0000000000..d62550126f --- /dev/null +++ b/helpers/env.ts @@ -0,0 +1,39 @@ +const BOOL_KEYS = [ + 'LLAMA_DEBUG_MODE', +] + +const DEFAULTS: any = { + ANKR_API_KEY: '79258ce7f7ee046decc3b5292a24eb4bf7c910d7e39b691384c7ce0cfb839a01', + ZETA_RPC: "https://zetachain-evm.blockpi.network/v1/rpc/public,https://zetachain-mainnet-archive.allthatnode.com:8545" +} + +export const ENV_KEYS = new Set([ + ...BOOL_KEYS, + ...Object.keys(DEFAULTS), + 'PANCAKESWAP_OPBNB_SUBGRAPH', + 'INDEXA_DB', + 'FLIPSIDE_API_KEY', + 'DUNE_API_KEYS', + 'ALLIUM_API_KEY', + 'BIT_QUERY_API_KEY', + 'SMARDEX_SUBGRAPH_API_KEY', + 'PROD_VYBE_API_KEY', + 'PERENNIAL_V2_SUBGRAPH_API_KEY', + 'ZEROx_API_KEY', + 'ZEROX_API_KEY' +]) + +// This is done to support both ZEROx_API_KEY and ZEROX_API_KEY +if (!process.env.ZEROX_API_KEY) process.env.ZEROX_API_KEY = process.env.ZEROx_API_KEY + +Object.keys(DEFAULTS).forEach(i => { + if (!process.env[i]) process.env[i] = DEFAULTS[i] // this is done to set the chain RPC details in @defillama/sdk +}) + + +export function getEnv(key: string): any { + if (!ENV_KEYS.has(key)) throw new Error(`Unknown env key: ${key}`) + const value = process.env[key] ?? DEFAULTS[key] + return BOOL_KEYS.includes(key) ? !!value : value +} + diff --git a/helpers/flipsidecrypto.ts b/helpers/flipsidecrypto.ts index 8b42c27d94..eff6d56e35 100644 --- a/helpers/flipsidecrypto.ts +++ b/helpers/flipsidecrypto.ts @@ -1,9 +1,10 @@ import retry from "async-retry"; import { IJSON } from "../adapters/types"; import { httpPost } from "../utils/fetchURL"; +import { getEnv } from "./env"; const token = {} as IJSON -const FLIPSIDE_API_KEYS = process.env.FLIPSIDE_API_KEY?.split(',') ?? ["f3b65679-a179-4983-b794-e41cf40103ed"] +const FLIPSIDE_API_KEYS = getEnv('FLIPSIDE_API_KEY').split(',') ?? ["f3b65679-a179-4983-b794-e41cf40103ed"] let API_KEY_INDEX = 0; const MAX_RETRIES = 20; diff --git a/helpers/indexer.ts b/helpers/indexer.ts index 2df2084fe9..5cdd654e4d 100644 --- a/helpers/indexer.ts +++ b/helpers/indexer.ts @@ -1,7 +1,8 @@ import { Sequelize } from 'sequelize'; import { FetchOptions } from '../adapters/types'; -const dbString = process.env.INDEXA_DB!; +import { getEnv } from './env'; +const dbString = getEnv('INDEXA_DB') let connection: Sequelize; diff --git a/helpers/token.ts b/helpers/token.ts index 2c07c3209a..e98aa7a73b 100644 --- a/helpers/token.ts +++ b/helpers/token.ts @@ -5,6 +5,7 @@ import axios from 'axios' import { getCache, setCache } from "./cache"; import { ethers } from "ethers"; import { getUniqueAddresses } from '@defillama/sdk/build/generalUtil'; +import { getEnv } from './env'; export const nullAddress = ADDRESSES.null @@ -136,7 +137,7 @@ async function ankrGetTokens(address: string, { onlyWhitelisted = true }: { const options = { method: 'POST', - url: `https://rpc.ankr.com/multichain/${process.env.ANKR_API_KEY}`, + url: `https://rpc.ankr.com/multichain/${getEnv('ANKR_API_KEY')}`, headers: { accept: 'application/json', 'content-type': 'application/json' }, data: { jsonrpc: '2.0', diff --git a/protocols/pancakeswap/index.ts b/protocols/pancakeswap/index.ts index 67b733c7f2..13a73de495 100644 --- a/protocols/pancakeswap/index.ts +++ b/protocols/pancakeswap/index.ts @@ -6,6 +6,7 @@ import disabledAdapter from "../../helpers/disabledAdapter"; import { getGraphDimensions } from "../../helpers/getUniSubgraph" import * as sdk from "@defillama/sdk"; import { httpGet } from "../../utils/fetchURL"; +import { getEnv } from "../../helpers/env"; const endpoints = { [CHAIN.BSC]: "https://proxy-worker.pancake-swap.workers.dev/bsc-exchange", @@ -15,7 +16,7 @@ const endpoints = { [CHAIN.ARBITRUM]: "https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v2-arb", [CHAIN.LINEA]: "https://graph-query.linea.build/subgraphs/name/pancakeswap/exhange-v2", [CHAIN.BASE]: "https://api.studio.thegraph.com/query/45376/exchange-v2-base/version/latest", - [CHAIN.OP_BNB]: `${process.env.PANCAKESWAP_OPBNB_SUBGRAPH}/subgraphs/name/pancakeswap/exchange-v2` + [CHAIN.OP_BNB]: `${getEnv('PANCAKESWAP_OPBNB_SUBGRAPH')}/subgraphs/name/pancakeswap/exchange-v2` }; const stablesSwapEndpoints = { @@ -30,7 +31,7 @@ const v3Endpoint = { [CHAIN.ARBITRUM]: "https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-arb", [CHAIN.LINEA]: "https://graph-query.linea.build/subgraphs/name/pancakeswap/exchange-v3-linea", [CHAIN.BASE]: "https://api.studio.thegraph.com/query/45376/exchange-v3-base/version/latest", - [CHAIN.OP_BNB]: `${process.env.PANCAKESWAP_OPBNB_SUBGRAPH}/subgraphs/name/pancakeswap/exchange-v3` + [CHAIN.OP_BNB]: `${getEnv('PANCAKESWAP_OPBNB_SUBGRAPH')}/subgraphs/name/pancakeswap/exchange-v3` } const VOLUME_USD = "volumeUSD";