"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkRpcClient = void 0;
const axios_1 = __importDefault(require("axios"));
const RPC_URLS_BY_CHAIN_ID = {
    1: 'https://rpc.ankr.com/eth',
    56: 'https://rpc.ankr.com/bsc',
    8453: 'https://rpc.ankr.com/base',
    42161: 'https://rpc.ankr.com/arbitrum',
    10: 'https://rpc.ankr.com/optimism',
    137: 'https://rpc.ankr.com/polygon',
    43114: 'https://rpc.ankr.com/avalanche',
    250: 'https://rpc.ankr.com/fantom',
    146: 'https://rpc.ankr.com/sonic',
    59144: 'https://rpc.ankr.com/linea',
    324: 'https://rpc.ankr.com/zksync',
    534352: 'https://rpc.ankr.com/scroll',
    5000: 'https://rpc.ankr.com/mantle',
    81457: 'https://rpc.ankr.com/blast',
    169: 'https://rpc.ankr.com/manta',
    2020: 'https://rpc.ankr.com/ronin',
    42220: 'https://rpc.ankr.com/celo',
    25: 'https://rpc.ankr.com/cronos',
    100: 'https://rpc.ankr.com/gnosis',
    1284: 'https://rpc.ankr.com/moonbeam',
    1285: 'https://rpc.ankr.com/moonriver',
    1666600000: 'https://rpc.ankr.com/harmony',
    1313161554: 'https://rpc.ankr.com/aurora',
    2222: 'https://rpc.ankr.com/kava',
    66: 'https://rpc.ankr.com/oktc',
    128: 'https://rpc.ankr.com/heco',
    888: 'https://rpc.ankr.com/wanchain',
    88: 'https://rpc.ankr.com/viction',
    61: 'https://rpc.ankr.com/etc',
    787: 'https://rpc.ankr.com/acala',
    60: 'https://rpc.ankr.com/gochain',
    108: 'https://rpc.ankr.com/thundercore',
    820: 'https://rpc.ankr.com/callisto',
    99: 'https://rpc.ankr.com/poa',
};
const DEFAULT_GAS_PRICE = '20000000000'; // 20 gwei
const SWAP_GAS_LIMIT = 200000;
const ERC20_NAME_SELECTOR = '0x06fdde03';
const ERC20_SYMBOL_SELECTOR = '0x95d89b41';
const ERC20_DECIMALS_SELECTOR = '0x313ce567';
class NetworkRpcClient {
    async getGasEstimate(chainId) {
        const rpcUrl = RPC_URLS_BY_CHAIN_ID[chainId];
        if (!rpcUrl) {
            return null;
        }
        try {
            const [blockResponse, gasResponse] = await Promise.all([
                this.callRpc(rpcUrl, 'eth_blockNumber'),
                this.callRpc(rpcUrl, 'eth_gasPrice'),
            ]);
            const blockNumber = blockResponse ? parseInt(blockResponse, 16) : 0;
            const gasPrice = gasResponse
                ? BigInt(gasResponse).toString()
                : DEFAULT_GAS_PRICE;
            const fee = (BigInt(gasPrice) * BigInt(SWAP_GAS_LIMIT)).toString();
            return {
                blockNumber,
                gasPrice,
                gasLimit: SWAP_GAS_LIMIT,
                fee,
            };
        }
        catch {
            return null;
        }
    }
    async getErc20TokenMetadata(chainId, contractAddress) {
        const rpcUrl = RPC_URLS_BY_CHAIN_ID[chainId];
        if (!rpcUrl) {
            return null;
        }
        const address = contractAddress.toLowerCase();
        try {
            const [nameHex, symbolHex, decimalsHex] = await Promise.all([
                this.callEthCall(rpcUrl, address, ERC20_NAME_SELECTOR),
                this.callEthCall(rpcUrl, address, ERC20_SYMBOL_SELECTOR),
                this.callEthCall(rpcUrl, address, ERC20_DECIMALS_SELECTOR),
            ]);
            if (!decimalsHex) {
                return null;
            }
            const decimals = this.decodeUint256(decimalsHex);
            const name = nameHex ? this.decodeAbiString(nameHex) ?? 'Unknown Token' : 'Unknown Token';
            const symbol = symbolHex ? this.decodeAbiString(symbolHex) ?? '???' : '???';
            return { name, symbol, decimals };
        }
        catch {
            return null;
        }
    }
    async callEthCall(rpcUrl, to, data) {
        return this.callRpc(rpcUrl, 'eth_call', [
            {
                to,
                data,
            },
            'latest',
        ]);
    }
    async callRpc(url, method, params = []) {
        const response = await axios_1.default.post(url, {
            jsonrpc: '2.0',
            method,
            params,
            id: 1,
        }, {
            headers: { 'Content-Type': 'application/json' },
            timeout: 5000,
        });
        if (response.data.error) {
            return null;
        }
        return response.data.result ?? null;
    }
    decodeUint256(hex) {
        const normalized = hex.startsWith('0x') ? hex.slice(2) : hex;
        return Number(BigInt(`0x${normalized}`));
    }
    decodeAbiString(hex) {
        const normalized = hex.startsWith('0x') ? hex.slice(2) : hex;
        if (normalized.length < 128) {
            return null;
        }
        const offset = Number(BigInt(`0x${normalized.slice(0, 64)}`));
        if (offset !== 32) {
            return null;
        }
        const length = Number(BigInt(`0x${normalized.slice(64, 128)}`));
        if (length === 0) {
            return '';
        }
        const dataStart = 128;
        const dataEnd = dataStart + length * 2;
        if (normalized.length < dataEnd) {
            return null;
        }
        const stringHex = normalized.slice(dataStart, dataEnd);
        try {
            const bytes = Buffer.from(stringHex, 'hex');
            return new TextDecoder().decode(bytes);
        }
        catch {
            return null;
        }
    }
}
exports.NetworkRpcClient = NetworkRpcClient;
//# sourceMappingURL=network-rpc-client.js.map