ox
Version:
Ethereum Standard Library
512 lines • 18.4 kB
TypeScript
import type * as abitype from 'abitype';
import * as AbiParameters from './AbiParameters.js';
import * as Address from './Address.js';
import * as Bytes from './Bytes.js';
import * as Errors from './Errors.js';
import * as Hash from './Hash.js';
import * as Hex from './Hex.js';
import type { Compute } from './internal/types.js';
import * as Json from './Json.js';
export type TypedData = abitype.TypedData;
export type Domain = abitype.TypedDataDomain;
export type Parameter = abitype.TypedDataParameter;
export type Definition<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, primaryTypes = typedData extends TypedData ? keyof typedData : string> = primaryType extends 'EIP712Domain' ? EIP712DomainDefinition<typedData, primaryType> : MessageDefinition<typedData, primaryType, primaryTypes>;
export type EIP712DomainDefinition<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends 'EIP712Domain' = 'EIP712Domain', schema extends Record<string, unknown> = typedData extends TypedData ? abitype.TypedDataToPrimitiveTypes<typedData> : Record<string, unknown>> = {
types?: typedData | undefined;
} & {
primaryType: 'EIP712Domain' | (primaryType extends 'EIP712Domain' ? primaryType : never);
domain: schema extends {
EIP712Domain: infer domain;
} ? domain : Compute<Domain>;
message?: undefined;
};
export type MessageDefinition<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData = keyof typedData, primaryTypes = typedData extends TypedData ? keyof typedData : string, schema extends Record<string, unknown> = typedData extends TypedData ? abitype.TypedDataToPrimitiveTypes<typedData> : Record<string, unknown>, message = schema[primaryType extends keyof schema ? primaryType : keyof schema]> = {
types: typedData;
} & {
primaryType: primaryTypes | (primaryType extends primaryTypes ? primaryType : never);
domain?: (schema extends {
EIP712Domain: infer domain;
} ? domain : Compute<Domain>) | undefined;
message: {
[_: string]: any;
} extends message ? Record<string, unknown> : message;
};
/**
* Asserts that [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) is valid.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.assert({
* domain: {
* name: 'Ether!',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
* },
* primaryType: 'Foo',
* types: {
* Foo: [
* { name: 'address', type: 'address' },
* { name: 'name', type: 'string' },
* { name: 'foo', type: 'string' }
* ]
* },
* message: {
* address: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9',
* name: 'jxom',
* foo: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9'
* }
* })
* ```
*
* @param value - The Typed Data to validate.
*/
export declare function assert<const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | 'EIP712Domain'>(value: assert.Value<typedData, primaryType>): void;
export declare namespace assert {
type Value<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData> = Definition<typedData, primaryType>;
type ErrorType = Address.InvalidAddressError | BytesSizeMismatchError | InvalidArrayError | InvalidArrayLengthError | InvalidPrimaryTypeError | Hex.fromNumber.ErrorType | Hex.size.ErrorType | Errors.GlobalErrorType;
}
/**
* Creates [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) [`domainSeparator`](https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator) for the provided domain.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.domainSeparator({
* name: 'Ether!',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
* })
* // @log: '0x9911ee4f58a7059a8f5385248040e6984d80e2c849500fe6a4d11c4fa98c2af3'
* ```
*
* @param domain - The domain for which to create the domain separator.
* @returns The domain separator.
*/
export declare function domainSeparator(domain: Domain): Hex.Hex;
export declare namespace domainSeparator {
type ErrorType = hashDomain.ErrorType | Errors.GlobalErrorType;
}
/**
* Encodes typed data in [EIP-712 format](https://eips.ethereum.org/EIPS/eip-712): `0x19 ‖ 0x01 ‖ domainSeparator ‖ hashStruct(message)`.
*
* @example
* ```ts twoslash
* import { TypedData, Hash } from 'ox'
*
* const data = TypedData.encode({
* // [!code focus:33]
* domain: {
* name: 'Ether Mail',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0x0000000000000000000000000000000000000000'
* },
* types: {
* Person: [
* { name: 'name', type: 'string' },
* { name: 'wallet', type: 'address' }
* ],
* Mail: [
* { name: 'from', type: 'Person' },
* { name: 'to', type: 'Person' },
* { name: 'contents', type: 'string' }
* ]
* },
* primaryType: 'Mail',
* message: {
* from: {
* name: 'Cow',
* wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
* },
* to: {
* name: 'Bob',
* wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
* },
* contents: 'Hello, Bob!'
* }
* })
* // @log: '0x19012fdf3441fcaf4f30c7e16292b258a5d7054a4e2e00dbd7b7d2f467f2b8fb9413c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e'
* // @log: (0x19 ‖ 0x01 ‖ domainSeparator ‖ hashStruct(message))
*
* const hash = Hash.keccak256(data)
* ```
*
* @param value - The Typed Data to encode.
* @returns The encoded Typed Data.
*/
export declare function encode<const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | 'EIP712Domain'>(value: encode.Value<typedData, primaryType>): Hex.Hex;
export declare namespace encode {
type Value<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData> = Definition<typedData, primaryType>;
type ErrorType = extractEip712DomainTypes.ErrorType | hashDomain.ErrorType | hashStruct.ErrorType | assert.ErrorType | Errors.GlobalErrorType;
}
/**
* Encodes [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) schema for the provided primaryType.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.encodeType({
* types: {
* Foo: [
* { name: 'address', type: 'address' },
* { name: 'name', type: 'string' },
* { name: 'foo', type: 'string' }
* ]
* },
* primaryType: 'Foo'
* })
* // @log: 'Foo(address address,string name,string foo)'
* ```
*
* @param value - The Typed Data schema.
* @returns The encoded type.
*/
export declare function encodeType(value: encodeType.Value): string;
export declare namespace encodeType {
type Value = {
primaryType: string;
types: TypedData;
};
type ErrorType = findTypeDependencies.ErrorType | Errors.GlobalErrorType;
}
/**
* Gets [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) schema for EIP-721 domain.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.extractEip712DomainTypes({
* name: 'Ether!',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
* })
* // @log: [
* // @log: { 'name': 'name', 'type': 'string' },
* // @log: { 'name': 'version', 'type': 'string' },
* // @log: { 'name': 'chainId', 'type': 'uint256' },
* // @log: { 'name': 'verifyingContract', 'type': 'address' },
* // @log: ]
* ```
*
* @param domain - The EIP-712 domain.
* @returns The EIP-712 domain schema.
*/
export declare function extractEip712DomainTypes(domain: Domain | undefined): Parameter[];
export declare namespace extractEip712DomainTypes {
type ErrorType = Errors.GlobalErrorType;
}
/**
* Gets the payload to use for signing typed data in [EIP-712 format](https://eips.ethereum.org/EIPS/eip-712).
*
* @example
* ```ts twoslash
* import { Secp256k1, TypedData, Hash } from 'ox'
*
* const payload = TypedData.getSignPayload({
* // [!code focus:99]
* domain: {
* name: 'Ether Mail',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0x0000000000000000000000000000000000000000'
* },
* types: {
* Person: [
* { name: 'name', type: 'string' },
* { name: 'wallet', type: 'address' }
* ],
* Mail: [
* { name: 'from', type: 'Person' },
* { name: 'to', type: 'Person' },
* { name: 'contents', type: 'string' }
* ]
* },
* primaryType: 'Mail',
* message: {
* from: {
* name: 'Cow',
* wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
* },
* to: {
* name: 'Bob',
* wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
* },
* contents: 'Hello, Bob!'
* }
* })
*
* const signature = Secp256k1.sign({
* payload,
* privateKey: '0x...'
* })
* ```
*
* @param value - The typed data to get the sign payload for.
* @returns The payload to use for signing.
*/
export declare function getSignPayload<const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | 'EIP712Domain'>(value: encode.Value<typedData, primaryType>): Hex.Hex;
export declare namespace getSignPayload {
type ErrorType = Hash.keccak256.ErrorType | encode.ErrorType | Errors.GlobalErrorType;
}
/**
* Hashes [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) domain.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.hashDomain({
* domain: {
* name: 'Ether Mail',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0x0000000000000000000000000000000000000000'
* }
* })
* // @log: '0x6192106f129ce05c9075d319c1fa6ea9b3ae37cbd0c1ef92e2be7137bb07baa1'
* ```
*
* @param value - The Typed Data domain and types.
* @returns The hashed domain.
*/
export declare function hashDomain(value: hashDomain.Value): Hex.Hex;
export declare namespace hashDomain {
type Value = {
/** The Typed Data domain. */
domain: Domain;
/** The Typed Data types. */
types?: {
EIP712Domain?: readonly Parameter[] | undefined;
[key: string]: readonly Parameter[] | undefined;
} | undefined;
/** Optional cache of `keccak256(encodeType(t))` keyed by type name, shared across nested struct/array calls. */
typeHashes?: Map<string, Hex.Hex> | undefined;
};
type ErrorType = hashStruct.ErrorType | Errors.GlobalErrorType;
}
/**
* Hashes [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) struct.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.hashStruct({
* types: {
* Foo: [
* { name: 'address', type: 'address' },
* { name: 'name', type: 'string' },
* { name: 'foo', type: 'string' }
* ]
* },
* primaryType: 'Foo',
* data: {
* address: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9',
* name: 'jxom',
* foo: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9'
* }
* })
* // @log: '0x996fb3b6d48c50312d69abdd4c1b6fb02057c85aa86bb8d04c6f023326a168ce'
* ```
*
* @param value - The Typed Data struct to hash.
* @returns The hashed Typed Data struct.
*/
export declare function hashStruct(value: hashStruct.Value): Hex.Hex;
export declare namespace hashStruct {
type Value = {
/** The Typed Data struct to hash. */
data: Record<string, unknown>;
/** The primary type of the Typed Data struct. */
primaryType: string;
/** The types of the Typed Data struct. */
types: TypedData;
/** Optional cache of `keccak256(encodeType(t))` keyed by type name, shared across nested struct/array calls. */
typeHashes?: Map<string, Hex.Hex> | undefined;
};
type ErrorType = encodeData.ErrorType | Hash.keccak256.ErrorType | Errors.GlobalErrorType;
}
/**
* Serializes [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) schema into string.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* TypedData.serialize({
* domain: {
* name: 'Ether!',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
* },
* primaryType: 'Foo',
* types: {
* Foo: [
* { name: 'address', type: 'address' },
* { name: 'name', type: 'string' },
* { name: 'foo', type: 'string' }
* ]
* },
* message: {
* address: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9',
* name: 'jxom',
* foo: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9'
* }
* })
* // @log: "{"domain":{},"message":{"address":"0xb9cab4f0e46f7f6b1024b5a7463734fa68e633f9","name":"jxom","foo":"0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9"},"primaryType":"Foo","types":{"Foo":[{"name":"address","type":"address"},{"name":"name","type":"string"},{"name":"foo","type":"string"}]}}"
* ```
*
* @param value - The Typed Data schema to serialize.
* @returns The serialized Typed Data schema. w
*/
export declare function serialize<const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | 'EIP712Domain'>(value: serialize.Value<typedData, primaryType>): string;
export declare namespace serialize {
type Value<typedData extends TypedData | Record<string, unknown> = TypedData, primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData> = Definition<typedData, primaryType>;
type ErrorType = Json.stringify.ErrorType | Errors.GlobalErrorType;
}
/**
* Checks if [EIP-712 Typed Data](https://eips.ethereum.org/EIPS/eip-712) is valid.
*
* @example
* ```ts twoslash
* import { TypedData } from 'ox'
*
* const valid = TypedData.validate({
* domain: {
* name: 'Ether!',
* version: '1',
* chainId: 1,
* verifyingContract:
* '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
* },
* primaryType: 'Foo',
* types: {
* Foo: [
* { name: 'address', type: 'address' },
* { name: 'name', type: 'string' },
* { name: 'foo', type: 'string' }
* ]
* },
* message: {
* address: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9',
* name: 'jxom',
* foo: '0xb9CAB4F0E46F7F6b1024b5A7463734fa68E633f9'
* }
* })
* // @log: true
* ```
*
* @param value - The Typed Data to validate.
*/
export declare function validate<const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | 'EIP712Domain'>(value: assert.Value<typedData, primaryType>): boolean;
export declare namespace validate {
type ErrorType = assert.ErrorType | Errors.GlobalErrorType;
}
/** Thrown when the bytes size of a typed data value does not match the expected size. */
export declare class BytesSizeMismatchError extends Errors.BaseError {
readonly name = "TypedData.BytesSizeMismatchError";
constructor({ expectedSize, givenSize, }: {
expectedSize: number;
givenSize: number;
});
}
/** Thrown when the domain is invalid. */
export declare class InvalidDomainError extends Errors.BaseError {
readonly name = "TypedData.InvalidDomainError";
constructor({ domain }: {
domain: unknown;
});
}
/** Thrown when the primary type of a typed data value is invalid. */
export declare class InvalidPrimaryTypeError extends Errors.BaseError {
readonly name = "TypedData.InvalidPrimaryTypeError";
constructor({ primaryType, types, }: {
primaryType: string;
types: TypedData | Record<string, unknown>;
});
}
/** Thrown when the struct type is not a valid type. */
export declare class InvalidStructTypeError extends Errors.BaseError {
readonly name = "TypedData.InvalidStructTypeError";
constructor({ type }: {
type: string;
});
}
/** Thrown when an array-typed value is not an array. */
export declare class InvalidArrayError extends Errors.BaseError {
readonly name = "TypedData.InvalidArrayError";
constructor({ name, type, value, }: {
name: string;
type: string;
value: unknown;
});
}
/** Thrown when a fixed-length array does not match its declared length. */
export declare class InvalidArrayLengthError extends Errors.BaseError {
readonly name = "TypedData.InvalidArrayLengthError";
constructor({ name, type, expectedLength, givenLength, }: {
name: string;
type: string;
expectedLength: number;
givenLength: number;
});
}
/** @internal */
export declare function encodeData(value: {
data: Record<string, unknown>;
primaryType: string;
types: TypedData;
typeHashes?: Map<string, Hex.Hex> | undefined;
}): Hex.Hex;
/** @internal */
export declare namespace encodeData {
type ErrorType = AbiParameters.encode.ErrorType | encodeField.ErrorType | hashType.ErrorType | Errors.GlobalErrorType;
}
/** @internal */
export declare function hashType(value: {
primaryType: string;
types: TypedData;
typeHashes?: Map<string, Hex.Hex> | undefined;
}): Hex.Hex;
/** @internal */
export declare namespace hashType {
type ErrorType = Hex.fromString.ErrorType | encodeType.ErrorType | Hash.keccak256.ErrorType | Errors.GlobalErrorType;
}
/** @internal */
export declare function encodeField(properties: {
types: TypedData;
name: string;
type: string;
value: any;
typeHashes?: Map<string, Hex.Hex> | undefined;
}): [type: AbiParameters.Parameter, value: Hex.Hex];
/** @internal */
export declare namespace encodeField {
type ErrorType = AbiParameters.encode.ErrorType | Hash.keccak256.ErrorType | Bytes.fromString.ErrorType | InvalidArrayError | InvalidArrayLengthError | Errors.GlobalErrorType;
}
/** @internal */
export declare function findTypeDependencies(value: {
primaryType: string;
types: TypedData;
}, results?: Set<string>): Set<string>;
/** @internal */
export declare namespace findTypeDependencies {
type ErrorType = Errors.GlobalErrorType;
}
//# sourceMappingURL=TypedData.d.ts.map