server.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Disable the following rule because this file is the intended place to declare
  2. // and load all env variables.
  3. /* eslint-disable n/no-process-env */
  4. // Disable the following rule because variables in this file are only loaded at
  5. // runtime and do not influence the build outputs, thus they need not be
  6. // declared to turbo for it to be able to cache build outputs correctly.
  7. /* eslint-disable turbo/no-undeclared-env-vars */
  8. import "server-only";
  9. /**
  10. * Throw if the env var `key` is not set (at either runtime or build time).
  11. */
  12. const demand = (key: string): string => {
  13. const value = process.env[key];
  14. if (value === undefined || value === "") {
  15. throw new MissingEnvironmentError(key);
  16. } else {
  17. return value;
  18. }
  19. };
  20. const fromCsv = (value: string): string[] =>
  21. value.split(",").map((entry) => entry.toLowerCase().trim());
  22. const transform = <T>(key: string, fn: (value: string | undefined) => T): T => {
  23. const value = process.env[key];
  24. return fn(value === "" ? undefined : value);
  25. };
  26. const transformOr = <T>(
  27. key: string,
  28. fn: (value: string) => T,
  29. defaultValue: T,
  30. ): T => transform(key, (value) => (value ? fn(value) : defaultValue));
  31. const getOr = (key: string, defaultValue: string): string =>
  32. transform(key, (value) => value ?? defaultValue);
  33. /**
  34. * Indicates that this server is the live customer-facing production server.
  35. */
  36. export const IS_PRODUCTION_SERVER = process.env.VERCEL_ENV === "production";
  37. /**
  38. * Throw if the env var `key` is not set in the live customer-facing production
  39. * server, but allow it to be unset in any other environment.
  40. */
  41. const demandInProduction = IS_PRODUCTION_SERVER
  42. ? demand
  43. : (key: string) => process.env[key];
  44. export const GOOGLE_ANALYTICS_ID = demandInProduction("GOOGLE_ANALYTICS_ID");
  45. export const AMPLITUDE_API_KEY = demandInProduction("AMPLITUDE_API_KEY");
  46. export const WALLETCONNECT_PROJECT_ID = demandInProduction(
  47. "WALLETCONNECT_PROJECT_ID",
  48. );
  49. export const MAINNET_RPC = process.env.MAINNET_RPC;
  50. export const MAINNET_API_RPC =
  51. process.env.MAINNET_API_RPC ?? process.env.MAINNET_RPC;
  52. export const PYTHNET_RPC = getOr("PYTHNET_RPC", "https://pythnet.rpcpool.com");
  53. export const HERMES_URL = getOr("HERMES_URL", "https://hermes.pyth.network");
  54. export const BLOCKED_REGIONS = transformOr("BLOCKED_REGIONS", fromCsv, []);
  55. export const IP_ALLOWLIST = transformOr("IP_ALLOWLIST", fromCsv, []);
  56. export const VPN_ORGANIZATION_ALLOWLIST = transformOr(
  57. "VPN_ORGANIZATION_ALLOWLIST",
  58. fromCsv,
  59. ["iCloud Private Relay"],
  60. );
  61. export const GOVERNANCE_ONLY_REGIONS = transformOr(
  62. "GOVERNANCE_ONLY_REGIONS",
  63. fromCsv,
  64. [],
  65. );
  66. export const PROXYCHECK_API_KEY = demandInProduction("PROXYCHECK_API_KEY");
  67. // This needs to be a public key that has SOL in it all the time, it will be used as a payer in the transaction simulation to compute the claimable rewards
  68. // such simulation fails when the payer has no funds.
  69. export const SIMULATION_PAYER_ADDRESS = getOr(
  70. "SIMULATION_PAYER_ADDRESS",
  71. "E5KR7yfb9UyVB6ZhmhQki1rM1eBcxHvyGKFZakAC5uc",
  72. );
  73. export const AMOUNT_STAKED_PER_ACCOUNT_SECRET = demandInProduction(
  74. "AMOUNT_STAKED_PER_ACCOUNT_SECRET",
  75. );
  76. class MissingEnvironmentError extends Error {
  77. constructor(name: string) {
  78. super(`Missing environment variable: ${name}!`);
  79. this.name = "MissingEnvironmentError";
  80. }
  81. }