"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBlockReceipts = exports.parityPendingTransactions = exports.parityPeers = exports.parityNodeKind = exports.parityMode = exports.parityEnode = exports.quorumPrivateTransactionPayload = exports.quorumRaftCluster = exports.quorumRaftLeader = exports.quorumRaftRole = exports.quorumIstanbulCandidates = exports.quorumIstanbulSnapshot = exports.gethTxpool = exports.gethMemStats = exports.gethMetrics = exports.gethPeers = exports.gethNodeInfo = exports.call = exports.syncing = exports.peerCount = exports.gasPrice = exports.hashRate = exports.mining = exports.protocolVersion = exports.chainId = exports.netVersion = exports.clientVersion = exports.pendingTransactions = exports.getStorageAt = exports.getCode = exports.getTransactionReceipt = exports.getTransaction = exports.getBlock = exports.blockNumber = exports.encodeParameter = exports.decodeResponseType = void 0;
const tslib_1 = require("tslib");
const web3_1 = tslib_1.__importDefault(require("web3")); // TODO: remove this. Replace with native functions needed.
const bn_1 = require("../utils/bn");
const debug_logging_1 = require("@splunkdlt/debug-logging");
const web3 = new web3_1.default();
const { info, warn, error, debug } = debug_logging_1.createModuleDebug('eth:requests');
function decodeResponseType(type, data) {
    if (type === 'hex') {
        if (data.startsWith('0x')) {
            return data;
        }
        return `0x${data}`;
    }
    if (type === 'string') {
        try {
            return web3.eth.abi.decodeParameter(type, data);
        }
        catch (e) {
            debug('Failed to decode string response, trying hexToAscii');
            return web3.utils.hexToAscii(data).replace(/\u0000/g, '');
        }
    }
    return web3.eth.abi.decodeParameter(type, data);
}
exports.decodeResponseType = decodeResponseType;
function encodeParameter(value, type) {
    return web3.eth.abi.encodeParameter(type, value);
}
exports.encodeParameter = encodeParameter;
exports.blockNumber = () => ({
    method: 'eth_blockNumber',
    response: (r) => bn_1.bigIntToNumber(r.result)
});
exports.getBlock = (blockNumber) => ({
    method: 'eth_getBlockByNumber',
    params: [typeof blockNumber === 'number' ? bn_1.numberToHex(blockNumber) : blockNumber, true]
});
exports.getTransaction = (txHash) => ({
    method: 'eth_getTransactionByHash',
    params: [txHash]
});
exports.getTransactionReceipt = (txHash) => ({
    method: 'eth_getTransactionReceipt',
    params: [txHash]
});
exports.getCode = (address) => ({
    method: 'eth_getCode',
    params: [address, 'latest']
});
exports.getStorageAt = (address, storageSlot) => ({
    method: 'eth_getStorageAt',
    params: [address, storageSlot, 'latest']
});
exports.pendingTransactions = () => ({
    method: 'eth_pendingTransactions'
});
/** Returns the current client version */
exports.clientVersion = () => ({
    method: 'web3_clientVersion'
});
/** Returns the current network id */
exports.netVersion = () => ({
    method: 'net_version',
    response: r => bn_1.bigIntToNumber(r.result)
});
/** Returns the chain ID - see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-695.md */
exports.chainId = () => ({
    method: 'eth_chainId',
    response: r => bn_1.bigIntToNumber(r.result)
});
/** Returns the current ethereum protocol version */
exports.protocolVersion = () => ({
    method: 'eth_protocolVersion',
    response: r => bn_1.bigIntToNumber(r.result)
});
/** Returns true if client is actively mining new blocks */
exports.mining = () => ({
    method: 'eth_mining'
});
/** Returns the number of hashes per second that the node is mining with */
exports.hashRate = () => ({
    method: 'eth_hashrate',
    response: r => bn_1.bigIntToNumber(r.result)
});
/** Returns the current price per gas in wei */
exports.gasPrice = () => ({
    method: 'eth_gasPrice',
    response: r => bn_1.bigIntToNumber(r.result)
});
/** Returns number of peers currently connected to the client */
exports.peerCount = () => ({
    method: 'net_peerCount',
    response: r => bn_1.bigIntToNumber(r.result)
});
/** Returns an object with sync status data or FALSE, when not syncing */
exports.syncing = () => ({
    method: 'eth_syncing'
});
/** Returns the result from calling a method of a contract */
exports.call = (to, method, responseType) => ({
    method: 'eth_call',
    params: [{ to, data: `0x${method}` }, 'latest'],
    response: r => decodeResponseType(responseType, r.result)
});
// Geth specific requests
exports.gethNodeInfo = () => ({
    method: 'admin_nodeInfo'
});
exports.gethPeers = () => ({
    method: 'admin_peers'
});
exports.gethMetrics = (param) => ({
    method: 'debug_metrics',
    params: [param]
});
exports.gethMemStats = () => ({
    method: 'debug_memStats'
});
exports.gethTxpool = () => ({
    method: 'txpool_content'
});
// Quorum specific requests
exports.quorumIstanbulSnapshot = () => ({
    method: 'istanbul_getSnapshot'
});
exports.quorumIstanbulCandidates = () => ({
    method: 'istanbul_candidates'
});
exports.quorumRaftRole = () => ({
    method: 'raft_role'
});
exports.quorumRaftLeader = () => ({
    method: 'raft_leader'
});
exports.quorumRaftCluster = () => ({
    method: 'raft_cluster'
});
exports.quorumPrivateTransactionPayload = (id) => ({
    method: 'eth_getQuorumPayload',
    params: [id]
});
// Parity specific requests
/** Returns the node enode URI */
exports.parityEnode = () => ({
    method: 'parity_enode'
});
exports.parityMode = () => ({
    method: 'parity_mode'
});
exports.parityNodeKind = () => ({
    method: 'parity_nodeKind'
});
exports.parityPeers = () => ({
    method: 'parity_netPeers'
});
exports.parityPendingTransactions = () => ({
    method: 'parity_pendingTransactions'
});
exports.getBlockReceipts = (blockNumber) => ({
    method: 'parity_getBlockReceipts',
    params: [typeof blockNumber === 'number' ? bn_1.numberToHex(blockNumber) : blockNumber]
});
