import * as Hash from './Hash.js';
import * as Hex from './Hex.js';
import * as Rlp from './Rlp.js';
import * as Signature from './Signature.js';
/**
 * Converts an [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization object into a typed {@link ox#Authorization.Authorization}.
 *
 * @example
 * An Authorization can be instantiated from an [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization tuple in object format.
 *
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.from({
 *   address: '0x1234567890abcdef1234567890abcdef12345678',
 *   chainId: 1,
 *   nonce: 69n,
 * })
 * ```
 *
 * @example
 * ### Attaching Signatures
 *
 * A {@link ox#Signature.Signature} can be attached with the `signature` option. The example below demonstrates signing
 * an Authorization with {@link ox#Secp256k1.(sign:function)}.
 *
 * ```ts twoslash
 * import { Authorization, Secp256k1 } from 'ox'
 *
 * const authorization = Authorization.from({
 *   address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 *   chainId: 1,
 *   nonce: 40n,
 * })
 *
 * const signature = Secp256k1.sign({
 *   payload: Authorization.getSignPayload(authorization),
 *   privateKey: '0x...',
 * })
 *
 * const authorization_signed = Authorization.from(authorization, { signature }) // [!code focus]
 * ```
 *
 * @param authorization - An [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization tuple in object format.
 * @param options - Authorization options.
 * @returns The {@link ox#Authorization.Authorization}.
 */
export function from(authorization, options = {}) {
    if (typeof authorization.chainId === 'string')
        return fromRpc(authorization);
    return { ...authorization, ...options.signature };
}
/**
 * Converts an {@link ox#Authorization.Rpc} to an {@link ox#Authorization.Authorization}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.fromRpc({
 *   address: '0x0000000000000000000000000000000000000000',
 *   chainId: '0x1',
 *   nonce: '0x1',
 *   r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
 *   s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
 *   yParity: '0x0',
 * })
 * ```
 *
 * @param authorization - The RPC-formatted Authorization.
 * @returns A signed {@link ox#Authorization.Authorization}.
 */
export function fromRpc(authorization) {
    const { address, chainId, nonce } = authorization;
    const signature = Signature.extract(authorization);
    return {
        address,
        chainId: Number(chainId),
        nonce: BigInt(nonce),
        ...signature,
    };
}
/**
 * Converts an {@link ox#Authorization.ListRpc} to an {@link ox#Authorization.List}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorizationList = Authorization.fromRpcList([{
 *   address: '0x0000000000000000000000000000000000000000',
 *   chainId: '0x1',
 *   nonce: '0x1',
 *   r: '0x635dc2033e60185bb36709c29c75d64ea51dfbd91c32ef4be198e4ceb169fb4d',
 *   s: '0x50c2667ac4c771072746acfdcf1f1483336dcca8bd2df47cd83175dbe60f0540',
 *   yParity: '0x0',
 * }])
 * ```
 *
 * @param authorizationList - The RPC-formatted Authorization list.
 * @returns A signed {@link ox#Authorization.List}.
 */
export function fromRpcList(authorizationList) {
    return authorizationList.map(fromRpc);
}
/**
 * Converts an {@link ox#Authorization.Tuple} to an {@link ox#Authorization.Authorization}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.fromTuple([
 *   '0x1',
 *   '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 *   '0x3'
 * ])
 * // @log: {
 * // @log:   address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 * // @log:   chainId: 1,
 * // @log:   nonce: 3n
 * // @log: }
 * ```
 *
 * @example
 * It is also possible to append a Signature tuple to the end of an Authorization tuple.
 *
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.fromTuple([
 *   '0x1',
 *   '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 *   '0x3',
 *   '0x1',
 *   '0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90',
 *   '0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064',
 * ])
 * // @log: {
 * // @log:   address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 * // @log:   chainId: 1,
 * // @log:   nonce: 3n
 * // @log:   r: BigInt('0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90'),
 * // @log:   s: BigInt('0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064'),
 * // @log:   yParity: 0,
 * // @log: }
 * ```
 *
 * @param tuple - The [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization tuple.
 * @returns The {@link ox#Authorization.Authorization}.
 */
export function fromTuple(tuple) {
    const [chainId, address, nonce, yParity, r, s] = tuple;
    let args = {
        address,
        chainId: chainId === '0x' ? 0 : Number(chainId),
        nonce: nonce === '0x' ? 0n : BigInt(nonce),
    };
    if (yParity && r && s)
        args = { ...args, ...Signature.fromTuple([yParity, r, s]) };
    return from(args);
}
/**
 * Converts an {@link ox#Authorization.TupleList} to an {@link ox#Authorization.List}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorizationList = Authorization.fromTupleList([
 *   ['0x1', '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c', '0x3'],
 *   ['0x3', '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c', '0x14'],
 * ])
 * // @log: [
 * // @log:   {
 * // @log:     address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 * // @log:     chainId: 1,
 * // @log:     nonce: 3n,
 * // @log:   },
 * // @log:   {
 * // @log:     address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 * // @log:     chainId: 3,
 * // @log:     nonce: 20n,
 * // @log:   },
 * // @log: ]
 * ```
 *
 * @example
 * It is also possible to append a Signature tuple to the end of an Authorization tuple.
 *
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorizationList = Authorization.fromTupleList([
 *   ['0x1', '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c', '0x3', '0x1', '0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90', '0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064'],
 *   ['0x3', '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c', '0x14', '0x1', '0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90', '0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064'],
 * ])
 * // @log: [
 * // @log:   {
 * // @log:     address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 * // @log:     chainId: 1,
 * // @log:     nonce: 3n,
 * // @log:     r: BigInt('0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90'),
 * // @log:     s: BigInt('0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064'),
 * // @log:     yParity: 0,
 * // @log:   },
 * // @log:   {
 * // @log:     address: '0xbe95c3f554e9fc85ec51be69a3d807a0d55bcf2c',
 * // @log:     chainId: 3,
 * // @log:     nonce: 20n,
 * // @log:     r: BigInt('0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90'),
 * // @log:     s: BigInt('0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064'),
 * // @log:     yParity: 0,
 * // @log:   },
 * // @log: ]
 * ```
 *
 * @param tupleList - The [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization tuple list.
 * @returns An {@link ox#Authorization.List}.
 */
export function fromTupleList(tupleList) {
    const list = [];
    for (const tuple of tupleList)
        list.push(fromTuple(tuple));
    return list;
}
/**
 * Computes the sign payload for an {@link ox#Authorization.Authorization} in [EIP-7702 format](https://eips.ethereum.org/EIPS/eip-7702): `keccak256('0x05' || rlp([chain_id, address, nonce]))`.
 *
 * @example
 * The example below demonstrates computing the sign payload for an {@link ox#Authorization.Authorization}. This payload
 * can then be passed to signing functions like {@link ox#Secp256k1.(sign:function)}.
 *
 * ```ts twoslash
 * import { Authorization, Secp256k1 } from 'ox'
 *
 * const authorization = Authorization.from({
 *   address: '0x1234567890abcdef1234567890abcdef12345678',
 *   chainId: 1,
 *   nonce: 69n,
 * })
 *
 * const payload = Authorization.getSignPayload(authorization) // [!code focus]
 *
 * const signature = Secp256k1.sign({
 *   payload,
 *   privateKey: '0x...',
 * })
 * ```
 *
 * @param authorization - The {@link ox#Authorization.Authorization}.
 * @returns The sign payload.
 */
export function getSignPayload(authorization) {
    return hash(authorization, { presign: true });
}
/**
 * Computes the hash for an {@link ox#Authorization.Authorization} in [EIP-7702 format](https://eips.ethereum.org/EIPS/eip-7702): `keccak256('0x05' || rlp([chain_id, address, nonce]))`.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.from({
 *   address: '0x1234567890abcdef1234567890abcdef12345678',
 *   chainId: 1,
 *   nonce: 69n,
 * })
 *
 * const hash = Authorization.hash(authorization) // [!code focus]
 * ```
 *
 * @param authorization - The {@link ox#Authorization.Authorization}.
 * @returns The hash.
 */
export function hash(authorization, options = {}) {
    const { presign } = options;
    return Hash.keccak256(Hex.concat('0x05', Rlp.fromHex(toTuple(presign
        ? {
            address: authorization.address,
            chainId: authorization.chainId,
            nonce: authorization.nonce,
        }
        : authorization))));
}
/**
 * Converts an {@link ox#Authorization.Authorization} to an {@link ox#Authorization.Rpc}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.toRpc({
 *   address: '0x0000000000000000000000000000000000000000',
 *   chainId: 1,
 *   nonce: 1n,
 *   r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
 *   s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
 *   yParity: 0,
 * })
 * ```
 *
 * @param authorization - An Authorization.
 * @returns An RPC-formatted Authorization.
 */
export function toRpc(authorization) {
    const { address, chainId, nonce, ...signature } = authorization;
    return {
        address,
        chainId: Hex.fromNumber(chainId),
        nonce: Hex.fromNumber(nonce),
        ...Signature.toRpc(signature),
    };
}
/**
 * Converts an {@link ox#Authorization.List} to an {@link ox#Authorization.ListRpc}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.toRpcList([{
 *   address: '0x0000000000000000000000000000000000000000',
 *   chainId: 1,
 *   nonce: 1n,
 *   r: 44944627813007772897391531230081695102703289123332187696115181104739239197517n,
 *   s: 36528503505192438307355164441104001310566505351980369085208178712678799181120n,
 *   yParity: 0,
 * }])
 * ```
 *
 * @param authorizationList - An Authorization List.
 * @returns An RPC-formatted Authorization List.
 */
export function toRpcList(authorizationList) {
    return authorizationList.map(toRpc);
}
/**
 * Converts an {@link ox#Authorization.Authorization} to an {@link ox#Authorization.Tuple}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization = Authorization.from({
 *   address: '0x1234567890abcdef1234567890abcdef12345678',
 *   chainId: 1,
 *   nonce: 69n,
 * })
 *
 * const tuple = Authorization.toTuple(authorization) // [!code focus]
 * // @log: [
 * // @log:   address: '0x1234567890abcdef1234567890abcdef12345678',
 * // @log:   chainId: 1,
 * // @log:   nonce: 69n,
 * // @log: ]
 * ```
 *
 * @param authorization - The {@link ox#Authorization.Authorization}.
 * @returns An [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization tuple.
 */
export function toTuple(authorization) {
    const { address, chainId, nonce } = authorization;
    const signature = Signature.extract(authorization);
    return [
        chainId ? Hex.fromNumber(chainId) : '0x',
        address,
        nonce ? Hex.fromNumber(nonce) : '0x',
        ...(signature ? Signature.toTuple(signature) : []),
    ];
}
/**
 * Converts an {@link ox#Authorization.List} to an {@link ox#Authorization.TupleList}.
 *
 * @example
 * ```ts twoslash
 * import { Authorization } from 'ox'
 *
 * const authorization_1 = Authorization.from({
 *   address: '0x1234567890abcdef1234567890abcdef12345678',
 *   chainId: 1,
 *   nonce: 69n,
 * })
 * const authorization_2 = Authorization.from({
 *   address: '0x1234567890abcdef1234567890abcdef12345678',
 *   chainId: 3,
 *   nonce: 20n,
 * })
 *
 * const tuple = Authorization.toTupleList([authorization_1, authorization_2]) // [!code focus]
 * // @log: [
 * // @log:   [
 * // @log:     address: '0x1234567890abcdef1234567890abcdef12345678',
 * // @log:     chainId: 1,
 * // @log:     nonce: 69n,
 * // @log:   ],
 * // @log:   [
 * // @log:     address: '0x1234567890abcdef1234567890abcdef12345678',
 * // @log:     chainId: 3,
 * // @log:     nonce: 20n,
 * // @log:   ],
 * // @log: ]
 * ```
 *
 * @param list - An {@link ox#Authorization.List}.
 * @returns An [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Authorization tuple list.
 */
export function toTupleList(list) {
    if (!list || list.length === 0)
        return [];
    const tupleList = [];
    for (const authorization of list)
        tupleList.push(toTuple(authorization));
    return tupleList;
}
//# sourceMappingURL=Authorization.js.map