import * as Hex from './Hex.js';
import * as Transaction from './Transaction.js';
import * as Withdrawal from './Withdrawal.js';
/**
 * Converts a {@link ox#Block.Block} to an {@link ox#Block.Rpc}.
 *
 * @example
 * ```ts twoslash
 * // @noErrors
 * import { Block } from 'ox'
 *
 * const block = Block.toRpc({
 *   // ...
 *   hash: '0xebc3644804e4040c0a74c5a5bbbc6b46a71a5d4010fe0c92ebb2fdf4a43ea5dd',
 *   number: 19868020n,
 *   size: 520n
 *   timestamp: 1662222222n,
 *   // ...
 * })
 * // @log: {
 * // @log:   // ...
 * // @log:   hash: '0xebc3644804e4040c0a74c5a5bbbc6b46a71a5d4010fe0c92ebb2fdf4a43ea5dd',
 * // @log:   number: '0xec6fc6',
 * // @log:   size: '0x208',
 * // @log:   timestamp: '0x63198f6f',
 * // @log:   // ...
 * // @log: }
 * ```
 *
 * @param block - The Block to convert.
 * @returns An RPC Block.
 */
export function toRpc(block, _options = {}) {
    const transactions = block.transactions.map((transaction) => {
        if (typeof transaction === 'string')
            return transaction;
        return Transaction.toRpc(transaction);
    });
    return {
        baseFeePerGas: typeof block.baseFeePerGas === 'bigint'
            ? Hex.fromNumber(block.baseFeePerGas)
            : undefined,
        blobGasUsed: typeof block.blobGasUsed === 'bigint'
            ? Hex.fromNumber(block.blobGasUsed)
            : undefined,
        excessBlobGas: typeof block.excessBlobGas === 'bigint'
            ? Hex.fromNumber(block.excessBlobGas)
            : undefined,
        extraData: block.extraData,
        difficulty: typeof block.difficulty === 'bigint'
            ? Hex.fromNumber(block.difficulty)
            : undefined,
        gasLimit: Hex.fromNumber(block.gasLimit),
        gasUsed: Hex.fromNumber(block.gasUsed),
        hash: block.hash,
        logsBloom: block.logsBloom,
        miner: block.miner,
        mixHash: block.mixHash,
        nonce: block.nonce,
        number: (typeof block.number === 'bigint'
            ? Hex.fromNumber(block.number)
            : null),
        parentBeaconBlockRoot: block.parentBeaconBlockRoot,
        parentHash: block.parentHash,
        receiptsRoot: block.receiptsRoot,
        sealFields: block.sealFields,
        sha3Uncles: block.sha3Uncles,
        size: Hex.fromNumber(block.size),
        stateRoot: block.stateRoot,
        timestamp: Hex.fromNumber(block.timestamp),
        totalDifficulty: typeof block.totalDifficulty === 'bigint'
            ? Hex.fromNumber(block.totalDifficulty)
            : undefined,
        transactions,
        transactionsRoot: block.transactionsRoot,
        uncles: block.uncles,
        withdrawals: block.withdrawals?.map(Withdrawal.toRpc),
        withdrawalsRoot: block.withdrawalsRoot,
    };
}
/**
 * Converts a {@link ox#Block.Rpc} to an {@link ox#Block.Block}.
 *
 * @example
 * ```ts twoslash
 * // @noErrors
 * import { Block } from 'ox'
 *
 * const block = Block.fromRpc({
 *   // ...
 *   hash: '0xebc3644804e4040c0a74c5a5bbbc6b46a71a5d4010fe0c92ebb2fdf4a43ea5dd',
 *   number: '0xec6fc6',
 *   size: '0x208',
 *   timestamp: '0x63198f6f',
 *   // ...
 * })
 * // @log: {
 * // @log:   // ...
 * // @log:   hash: '0xebc3644804e4040c0a74c5a5bbbc6b46a71a5d4010fe0c92ebb2fdf4a43ea5dd',
 * // @log:   number: 19868020n,
 * // @log:   size: 520n,
 * // @log:   timestamp: 1662222222n,
 * // @log:   // ...
 * // @log: }
 * ```
 *
 * @example
 * ### End-to-end
 *
 * Below is an end-to-end example of using `Block.fromRpc` to fetch a block from the network and convert it to an {@link ox#Block.Block}.
 *
 * ```ts twoslash
 * import 'ox/window'
 * import { Block } from 'ox'
 *
 * const block = await window.ethereum!
 *   .request({
 *     method: 'eth_getBlockByNumber',
 *     params: ['latest', false],
 *   })
 *   .then(Block.fromRpc) // [!code hl]
 * // @log: {
 * // @log:   // ...
 * // @log:   hash: '0xebc3644804e4040c0a74c5a5bbbc6b46a71a5d4010fe0c92ebb2fdf4a43ea5dd',
 * // @log:   number: 19868020n,
 * // @log:   size: 520n,
 * // @log:   timestamp: 1662222222n,
 * // @log:   // ...
 * // @log: }
 * ```
 *
 * :::note
 *
 * For simplicity, the above example uses `window.ethereum.request`, but you can use any
 * type of JSON-RPC interface.
 *
 * :::
 *
 * @param block - The RPC block to convert.
 * @returns An instantiated {@link ox#Block.Block}.
 */
export function fromRpc(block, _options = {}) {
    if (!block)
        return null;
    const transactions = block.transactions.map((transaction) => {
        if (typeof transaction === 'string')
            return transaction;
        return Transaction.fromRpc(transaction);
    });
    return {
        ...block,
        baseFeePerGas: block.baseFeePerGas
            ? BigInt(block.baseFeePerGas)
            : undefined,
        blobGasUsed: block.blobGasUsed ? BigInt(block.blobGasUsed) : undefined,
        difficulty: block.difficulty ? BigInt(block.difficulty) : undefined,
        excessBlobGas: block.excessBlobGas
            ? BigInt(block.excessBlobGas)
            : undefined,
        gasLimit: BigInt(block.gasLimit ?? 0n),
        gasUsed: BigInt(block.gasUsed ?? 0n),
        number: block.number ? BigInt(block.number) : null,
        size: BigInt(block.size ?? 0n),
        stateRoot: block.stateRoot,
        timestamp: BigInt(block.timestamp ?? 0n),
        totalDifficulty: BigInt(block.totalDifficulty ?? 0n),
        transactions,
        withdrawals: block.withdrawals?.map(Withdrawal.fromRpc),
    };
}
//# sourceMappingURL=Block.js.map