chaingate
Version:
Multi-chain cryptocurrency SDK for TypeScript — unified API for Bitcoin, Ethereum, Litecoin, Dogecoin, Bitcoin Cash, Polygon, Arbitrum, and any EVM-compatible chain. Create wallets, query balances, send transactions, and manage tokens and NFTs across UTXO
168 lines (167 loc) • 7.08 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChainGate = void 0;
const client_1 = require("../Client/client");
const Client_1 = require("../Client");
const UtxoExplorer_1 = require("../Explorer/UtxoExplorer");
const EvmExplorer_1 = require("../Explorer/EvmExplorer");
const GlobalExplorer_1 = require("../Explorer/GlobalExplorer");
const EvmConnector_1 = require("../Connector/EvmConnector/EvmConnector");
const EvmRpcConnector_1 = require("../Connector/EvmRpcConnector/EvmRpcConnector");
const EvmRpcExplorer_1 = require("../Connector/EvmRpcConnector/EvmRpcExplorer");
const UtxoConnector_1 = require("../Connector/UtxoConnector/UtxoConnector");
const BchConnector_1 = require("../Connector/UtxoConnector/BchConnector/BchConnector");
const errors_1 = require("../errors");
const networks_1 = require("./networks");
const TTLCache_1 = require("../utils/TTLCache");
const UtxoLocalCache_1 = require("../utils/UtxoLocalCache");
const EvmNonceCache_1 = require("../utils/EvmNonceCache");
const RpcUrls_1 = require("./RpcUrls");
const BASE_URL = 'https://api.chaingate.dev';
/** Default TTL for the markets cache: 60 seconds. */
const MARKETS_TTL = 60000;
/**
* Main client for the ChainGate blockchain API.
*
* Provides access to the ChainGate API for querying blockchain data
* across EVM and UTXO networks.
*
* The API key is optional — without one you get a small rate limit suitable
* for trying things out. Get a free API key at https://api.chaingate.dev for
* a higher quota.
*
* @example
* ```ts
* import { ChainGate } from 'chaingate';
*
* const cg = new ChainGate();
*
* const btc = cg.explore(cg.networks.bitcoin); // UtxoExplorer
* const eth = cg.explore(cg.networks.ethereum); // EvmExplorer
* const avax = cg.explore(cg.networks.avalanche); // EvmExplorer
* ```
*/
class ChainGate {
explore(network) {
if (network instanceof networks_1.EvmRpcNetworkDescriptor) {
return new EvmRpcExplorer_1.EvmRpcExplorer(network.rpcUrl, network.chainId, this.global.evmNonceCache);
}
if (network instanceof networks_1.UtxoNetworkDescriptor) {
return new UtxoExplorer_1.UtxoExplorer(this.client, network.id, BASE_URL, this.apiKey, this.global);
}
if (network instanceof networks_1.EvmNetworkDescriptor) {
return new EvmExplorer_1.EvmExplorer(this.client, network.id, BASE_URL, this.apiKey, this.global);
}
throw new errors_1.UnsupportedOperationError(`Unknown network: ${network.id}`);
}
/**
* Returns a {@link GlobalExplorer} for querying cross-network data such as
* market prices, fiat exchange rates, real-time network information, and
* network logos — including networks that don't have dedicated `/evm` or
* `/utxo` endpoints.
*
* @example
* ```ts
* const global = cg.exploreGlobal();
*
* const markets = await global.getMarkets();
* const info = await global.getNetworksInfo();
* const logoUrl = global.getNetworkLogoUrl('berachain');
* ```
*/
exploreGlobal() {
return new GlobalExplorer_1.GlobalExplorer(this.client, BASE_URL, this.apiKey, this.global);
}
/**
* Returns the collection of all supported networks.
*
* The returned object is iterable (like an array) **and** has named
* properties for direct access:
*
* ```ts
* // Direct access
* cg.networks.bitcoin // UtxoNetworkDescriptor
* cg.networks.ethereum // EvmNetworkDescriptor
*
* // Iteration
* for (const net of cg.networks) { ... }
* ```
*/
get networks() {
return this._networks;
}
/**
* Pre-built JSON-RPC endpoint URLs for every network supported by the
* ChainGate RPC proxy, with the API key already appended.
*
* Useful for passing to external libraries (ethers, viem, etc.) or to
* {@link NetworkCollection.evmRpc | `cg.networks.evmRpc()`}.
*
* @example
* ```ts
* // Use with evmRpc connector
* const polygon = cg.networks.evmRpc({
* rpcUrl: cg.rpcUrls.polygon,
* chainId: 137,
* name: 'Polygon',
* symbol: 'POL',
* });
*
* // Or pass to any JSON-RPC library
* const provider = new ethers.JsonRpcProvider(cg.rpcUrls.ethereum);
* ```
*/
get rpcUrls() {
return this._rpcUrls;
}
connect(network, wallet) {
if (network instanceof networks_1.BchNetworkDescriptor) {
const explorer = new UtxoExplorer_1.UtxoExplorer(this.client, network.id, BASE_URL, this.apiKey, this.global);
return new BchConnector_1.BchConnector(wallet, explorer, network);
}
if (network instanceof networks_1.EvmRpcNetworkDescriptor) {
const explorer = new EvmRpcExplorer_1.EvmRpcExplorer(network.rpcUrl, network.chainId, this.global.evmNonceCache);
return new EvmRpcConnector_1.EvmRpcConnector(wallet, explorer, network);
}
if (network instanceof networks_1.EvmNetworkDescriptor) {
const explorer = new EvmExplorer_1.EvmExplorer(this.client, network.id, BASE_URL, this.apiKey, this.global);
return new EvmConnector_1.EvmConnector(wallet, explorer, network);
}
if (network instanceof networks_1.UtxoNetworkDescriptor) {
const explorer = new UtxoExplorer_1.UtxoExplorer(this.client, network.id, BASE_URL, this.apiKey, this.global);
return new UtxoConnector_1.UtxoConnector(wallet, explorer, network);
}
throw new errors_1.UnsupportedOperationError(`Unsupported network for connect: ${network.id}`);
}
/**
* @param options - Optional configuration.
* @param options.apiKey - Your ChainGate API key. Omit to use the keyless
* tier (small rate limit). Get a free key at https://api.chaingate.dev.
*/
constructor({ apiKey } = {}) {
this.apiKey = apiKey;
this.client = (0, client_1.createClient)((0, client_1.createConfig)({
baseUrl: BASE_URL,
headers: apiKey ? { 'x-api-key': apiKey } : {},
throwOnError: true,
}));
const client = this.client;
this.global = {
marketsCache: new TTLCache_1.TTLCache(async () => {
const { data } = await (0, Client_1.getGlobalMarkets)({ client, throwOnError: true });
return data;
}, MARKETS_TTL),
utxoCache: new UtxoLocalCache_1.UtxoLocalCache(),
evmNonceCache: new EvmNonceCache_1.EvmNonceCache(),
};
this.client.interceptors.error.use((_error, response) => {
if (response?.status === 429) {
return apiKey ? new errors_1.RateLimitQuotaError() : new errors_1.RateLimitError();
}
return _error;
});
this._networks = (0, networks_1.createNetworkCollection)(this.global.marketsCache, apiKey);
this._rpcUrls = new RpcUrls_1.RpcUrls(apiKey);
}
}
exports.ChainGate = ChainGate;