From 896a9792f7bdbfd80f26701f36a2df80ff1f07a1 Mon Sep 17 00:00:00 2001 From: "Leon.Zhang" Date: Thu, 26 Mar 2026 18:32:03 +0800 Subject: [PATCH] set default boa hosts --- README.md | 3 ++- src/core/chains.ts | 26 +++++++++++++++++++- tests/core/chains.test.ts | 50 +++++++++++++++++++++++++++++++++------ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6fb0e9e..803e40b 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,8 @@ npm install #### Network Configuration - `TRONGRID_API_KEY`: (Optional) Your TronGrid API key. - - **Why**: TRON mainnet RPCs have strict rate limits. Using an API key from [TronGrid](https://www.trongrid.io/) ensures reliable performance and higher throughput. + - **Why**: TRON mainnet RPCs have strict rate limits. When `TRONGRID_API_KEY` is set (and non-empty), the server uses `https://api.trongrid.io` as the default RPC hosts. + - **Fallback**: When `TRONGRID_API_KEY` is not set, the server uses `https://hptg.bankofai.io` as the default RPC hosts for `mainnet`. - **Usage**: ```bash export TRONGRID_API_KEY="" diff --git a/src/core/chains.ts b/src/core/chains.ts index 6f2f4fa..7b1c24c 100644 --- a/src/core/chains.ts +++ b/src/core/chains.ts @@ -14,6 +14,13 @@ export interface NetworkConfig { explorer: string; } +const BOA_MAINNET_HOST = "https://hptg.bankofai.io"; + +function isTronGridApiKeyConfigured(): boolean { + const apiKey = process.env.TRONGRID_API_KEY; + return typeof apiKey === "string" && apiKey.length > 0; +} + export const NETWORKS: Record = { [TronNetwork.Mainnet]: { name: "Mainnet", @@ -45,7 +52,16 @@ export function getNetworkConfig(network: string = DEFAULT_NETWORK): NetworkConf // Direct match if (Object.values(TronNetwork).includes(normalizedNetwork as TronNetwork)) { - return NETWORKS[normalizedNetwork as TronNetwork]; + const resolved = normalizedNetwork as TronNetwork; + if (resolved === TronNetwork.Mainnet && !isTronGridApiKeyConfigured()) { + return { + ...NETWORKS[TronNetwork.Mainnet], + fullNode: BOA_MAINNET_HOST, + solidityNode: BOA_MAINNET_HOST, + eventServer: BOA_MAINNET_HOST, + }; + } + return NETWORKS[resolved]; } // Aliases @@ -54,6 +70,14 @@ export function getNetworkConfig(network: string = DEFAULT_NETWORK): NetworkConf normalizedNetwork === "trx" || normalizedNetwork === "mainnet" ) { + if (!isTronGridApiKeyConfigured()) { + return { + ...NETWORKS[TronNetwork.Mainnet], + fullNode: BOA_MAINNET_HOST, + solidityNode: BOA_MAINNET_HOST, + eventServer: BOA_MAINNET_HOST, + }; + } return NETWORKS[TronNetwork.Mainnet]; } if (normalizedNetwork === "testnet") { diff --git a/tests/core/chains.test.ts b/tests/core/chains.test.ts index 7d03491..f53f51f 100644 --- a/tests/core/chains.test.ts +++ b/tests/core/chains.test.ts @@ -1,45 +1,78 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, afterAll } from "vitest"; import { getNetworkConfig, getRpcUrl, getSupportedNetworks, TronNetwork, - DEFAULT_NETWORK, NETWORKS, } from "../../src/core/chains"; describe("Chains", () => { + const BOA_MAINNET_HOST = "https://hptg.bankofai.io"; + const originalTronGridApiKey = process.env.TRONGRID_API_KEY; + const setEnv = (value: string | undefined) => { + if (value === undefined) { + delete process.env.TRONGRID_API_KEY; + } else { + process.env.TRONGRID_API_KEY = value; + } + }; + + afterAll(() => { + if (originalTronGridApiKey === undefined) { + delete process.env.TRONGRID_API_KEY; + } else { + process.env.TRONGRID_API_KEY = originalTronGridApiKey; + } + }); + it("should export supported networks", () => { const networks = getSupportedNetworks(); expect(networks).toEqual(["mainnet", "nile", "shasta"]); }); - it("should get network config for mainnet", () => { + it("should use hptg host for mainnet when TRONGRID_API_KEY not set", () => { + setEnv(undefined); + const config = getNetworkConfig(TronNetwork.Mainnet); + expect(config.name).toBe("Mainnet"); + expect(config.fullNode).toBe(BOA_MAINNET_HOST); + expect(config.solidityNode).toBe(BOA_MAINNET_HOST); + expect(config.eventServer).toBe(BOA_MAINNET_HOST); + }); + + it("should use api.trongrid.io for mainnet when TRONGRID_API_KEY is set", () => { + setEnv("dummy_key"); const config = getNetworkConfig(TronNetwork.Mainnet); expect(config.name).toBe("Mainnet"); expect(config.fullNode).toBe("https://api.trongrid.io"); }); it("should get network config for nile", () => { + setEnv(undefined); const config = getNetworkConfig(TronNetwork.Nile); expect(config.name).toBe("Nile"); expect(config.fullNode).toBe("https://nile.trongrid.io"); }); it("should get network config for shasta", () => { + setEnv(undefined); const config = getNetworkConfig(TronNetwork.Shasta); expect(config.name).toBe("Shasta"); expect(config.fullNode).toBe("https://api.shasta.trongrid.io"); }); it("should resolve aliases correctly", () => { - expect(getNetworkConfig("tron")).toBe(NETWORKS[TronNetwork.Mainnet]); - expect(getNetworkConfig("trx")).toBe(NETWORKS[TronNetwork.Mainnet]); + setEnv(undefined); + const hptgMainnet = getNetworkConfig("tron"); + expect(hptgMainnet.fullNode).toBe(BOA_MAINNET_HOST); + const hptgMainnet2 = getNetworkConfig("trx"); + expect(hptgMainnet2.fullNode).toBe(BOA_MAINNET_HOST); expect(getNetworkConfig("testnet")).toBe(NETWORKS[TronNetwork.Nile]); }); it("should return correct RPC URL", () => { - expect(getRpcUrl("mainnet")).toBe("https://api.trongrid.io"); + setEnv(undefined); + expect(getRpcUrl("mainnet")).toBe(BOA_MAINNET_HOST); expect(getRpcUrl("nile")).toBe("https://nile.trongrid.io"); }); @@ -50,6 +83,9 @@ describe("Chains", () => { }); it("should use default network if none provided", () => { - expect(getNetworkConfig()).toBe(NETWORKS[DEFAULT_NETWORK]); + setEnv(undefined); + const config = getNetworkConfig(); + expect(config.name).toBe("Mainnet"); + expect(config.fullNode).toBe(BOA_MAINNET_HOST); }); });