"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatLogEvent = exports.formatPendingTransaction = exports.formatTransaction = exports.formatBlock = exports.parseBlockTime = void 0;
const wasm_1 = require("../abi/wasm");
const bn_1 = require("./bn");
function parseBlockTime(timestamp) {
    if (typeof timestamp === 'number') {
        return timestamp * 1000;
    }
    if (typeof timestamp === 'string') {
        // Timestamp on Quorum/Raft nodes are emitted as nanoseconds since unix epoch
        // so translate it to milliseconds
        const ms = BigInt(timestamp) / BigInt(1000000);
        return bn_1.bigIntToNumber(ms);
    }
    throw new Error(`Unable to parse block timestamp "${timestamp}"`);
}
exports.parseBlockTime = parseBlockTime;
function formatBlock(rawBlock) {
    return {
        timestamp: bn_1.parseBigInt(rawBlock.timestamp),
        number: rawBlock.number != null ? bn_1.bigIntToNumber(rawBlock.number) : null,
        hash: rawBlock.hash,
        parentHash: rawBlock.parentHash,
        sha3Uncles: rawBlock.sha3Uncles,
        miner: wasm_1.toChecksumAddress(rawBlock.miner),
        stateRoot: rawBlock.stateRoot,
        transactionsRoot: rawBlock.transactionsRoot,
        receiptsRoot: rawBlock.receiptsRoot,
        logsBloom: rawBlock.logsBloom,
        difficulty: bn_1.parseBigInt(rawBlock.difficulty),
        gasLimit: bn_1.parseBigInt(rawBlock.gasLimit),
        gasUsed: bn_1.parseBigInt(rawBlock.gasUsed),
        extraData: rawBlock.extraData,
        nonce: rawBlock.nonce,
        totalDifficulty: bn_1.parseBigInt(rawBlock.totalDifficulty),
        size: bn_1.bigIntToNumber(rawBlock.size),
        uncles: rawBlock.uncles,
        transactionCount: rawBlock.transactions == null ? 0 : rawBlock.transactions.length,
        transactions: ((rawBlock.transactions == null
            ? []
            //@ts-ignore
            : rawBlock.transactions.map(txn => (typeof txn === 'string' ? txn : txn.hash))))
    };
}
exports.formatBlock = formatBlock;
function formatStatus(receiptStatus) {
    if (receiptStatus != null) {
        const n = bn_1.bigIntToNumber(receiptStatus);
        if (n === 0) {
            return 'failure';
        }
        else if (n === 1) {
            return 'success';
        }
        else {
            throw new Error(`Encountered invalid receipt status value: ${n} (expected 0 or 1)`);
        }
    }
    return null;
}
function formatBaseTransaction(rawTx) {
    const base = {
        hash: rawTx.hash,
        from: wasm_1.toChecksumAddress(rawTx.from),
        to: rawTx.to != null ? wasm_1.toChecksumAddress(rawTx.to) : null,
        gas: bn_1.parseBigInt(rawTx.gas),
        gasPrice: bn_1.parseBigInt(rawTx.gasPrice),
        input: rawTx.input,
        nonce: bn_1.bigIntToNumber(rawTx.nonce),
        value: bn_1.parseBigInt(rawTx.value),
        v: rawTx.v,
        r: rawTx.r,
        s: rawTx.s
    };
    if (rawTx.maxFeePerGas != null) {
        base.maxFeePerGas = bn_1.parseBigInt(rawTx.maxFeePerGas);
    }
    if (rawTx.maxPriorityFeePerGas != null) {
        base.maxPriorityFeePerGas = bn_1.parseBigInt(rawTx.maxPriorityFeePerGas);
    }
    return base;
}
function formatTransaction(rawTx, receipt, fromInfo, toInfo, contractAddressInfo, call, privatePayload) {
    return {
        ...formatBaseTransaction(rawTx),
        blockHash: rawTx.blockHash,
        blockNumber: rawTx.blockNumber != null ? bn_1.bigIntToNumber(rawTx.blockNumber) : null,
        transactionIndex: rawTx.transactionIndex != null ? bn_1.bigIntToNumber(rawTx.transactionIndex) : null,
        status: formatStatus(receipt.status),
        contractAddress: receipt.contractAddress != null ? wasm_1.toChecksumAddress(receipt.contractAddress) : null,
        cumulativeGasUsed: bn_1.parseBigInt(receipt.cumulativeGasUsed),
        gasUsed: bn_1.parseBigInt(receipt.gasUsed),
        fromInfo,
        toInfo,
        contractAddressInfo,
        call,
        privatePayload
    };
}
exports.formatTransaction = formatTransaction;
function formatPendingTransaction(rawTx, type, fromInfo, toInfo, call) {
    return {
        type,
        ...formatBaseTransaction(rawTx),
        fromInfo,
        toInfo,
        call
    };
}
exports.formatPendingTransaction = formatPendingTransaction;
function formatLogEvent(evt, addressInfo, event) {
    return {
        removed: evt.removed,
        logIndex: evt.logIndex != null ? bn_1.bigIntToNumber(evt.logIndex) : null,
        blockNumber: evt.blockNumber != null ? bn_1.bigIntToNumber(evt.blockNumber) : null,
        blockHash: evt.blockHash,
        transactionHash: evt.transactionHash,
        transactionIndex: evt.transactionIndex != null ? bn_1.bigIntToNumber(evt.transactionIndex) : null,
        address: wasm_1.toChecksumAddress(evt.address),
        data: evt.data,
        topics: evt.topics,
        addressInfo,
        event
    };
}
exports.formatLogEvent = formatLogEvent;
