UNPKG

ox

Version:

Ethereum Standard Library

408 lines 13.4 kB
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; const signature = yParity && r && s ? Signature.fromTuple([yParity, r, s]) : undefined; return from({ address, chainId: Number(chainId), nonce: BigInt(nonce), ...signature, }); } /** * 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); } /** * 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) { return Hash.keccak256(Hex.concat('0x05', Rlp.fromHex(toTuple(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