UNPKG

ox

Version:

Ethereum Standard Library

313 lines 9.82 kB
import * as Address from '../core/Address.js'; import type * as Bytes from '../core/Bytes.js'; import * as Errors from '../core/Errors.js'; import * as Hash from '../core/Hash.js'; import * as Hex from '../core/Hex.js'; import type { Compute, OneOf } from '../core/internal/types.js'; /** Maximum number of owners allowed in a native multisig config. */ export declare const maxOwners = 255; /** Maximum threshold accepted by a native multisig config. */ export declare const maxThreshold = 8; /** Maximum number of owner approvals in a native multisig signature. */ export declare const maxSignatures = 8; /** * Maximum number of native multisig signatures in one nested authorization * path, including the top-level transaction signature. */ export declare const maxNestingDepth = 2; /** Maximum encoded byte length for one owner approval. */ export declare const maxOwnerSignatureBytes = 2049; /** Tempo signature type byte for native multisig signatures. */ export declare const signatureTypeByte: "0x05"; /** Zero 32-byte salt (the default when no salt is provided). */ export declare const zeroSalt: `0x${string}`; /** * Native multisig configuration. Determines the stable multisig account * address. */ export type Config<numberType = number> = Compute<{ /** * Caller-chosen 32-byte salt mixed into the derived account address. * Defaults to the zero salt (`MultisigConfig.zeroSalt`) when omitted. */ salt?: Hex.Hex | undefined; /** Minimum total owner weight required to authorize a transaction. */ threshold: numberType; /** Weighted owner list (strictly ascending by `owner` address). */ owners: readonly Owner<numberType>[]; }>; /** Native multisig owner entry. */ export type Owner<numberType = number> = { /** Owner address (recovered from the owner's approval). */ owner: Address.Address; /** Nonzero owner weight. */ weight: numberType; }; /** RLP tuple representation of a {@link ox#MultisigConfig.Config}. */ export type Tuple = readonly [ salt: Hex.Hex, threshold: Hex.Hex, owners: readonly Hex.Hex[][] ]; /** * Asserts that a native multisig {@link ox#MultisigConfig.Config} is valid. * * Mirrors the Tempo `InitMultisig::validate` rules: owners non-empty and * `<= maxOwners`, strictly ascending unique nonzero owner addresses, nonzero * integer owner weights, integer `threshold` between `1` and `maxThreshold`, * total weight `<= 255` (u8 max), and `threshold <= total weight`. * * @example * ```ts twoslash * import { MultisigConfig } from 'ox/tempo' * * MultisigConfig.assert({ * threshold: 1, * owners: [ * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * ``` * * @param config - The multisig config. */ export declare function assert<numberType = number>(config: Config<numberType>): void; export declare namespace assert { type ErrorType = InvalidConfigError | Errors.GlobalErrorType; } /** * Normalizes a native multisig {@link ox#MultisigConfig.Config}. * * Sorts owners into strictly ascending `owner` address order (the canonical * form required for account derivation) and asserts the config is valid. * * @example * ```ts twoslash * import { MultisigConfig } from 'ox/tempo' * * const config = MultisigConfig.from({ * threshold: 2, * owners: [ * { * owner: '0x2222222222222222222222222222222222222222', * weight: 1 * }, * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * // owners are now sorted ascending by address * ``` * * @param config - The multisig config. * @returns The normalized multisig config. */ export declare function from<numberType = number>(config: Config<numberType>): Config<numberType>; /** * Converts an RLP {@link ox#MultisigConfig.Tuple} back to a * {@link ox#MultisigConfig.Config}. * * @example * ```ts twoslash * import { MultisigConfig } from 'ox/tempo' * * const config = MultisigConfig.fromTuple([ * `0x${'00'.repeat(32)}`, * '0x01', * [['0x1111111111111111111111111111111111111111', '0x01']] * ]) * ``` * * @param tuple - The RLP tuple. * @returns The multisig config. */ export declare function fromTuple(tuple: Tuple): Config; /** * Derives the stable native multisig account address. * * Preimage (fixed-width big-endian, **not** RLP): * `keccak256("tempo:multisig:account" || salt || u8(threshold) || u8(owners.length) || (owner || u8(weight)) for each owner)[12:32]`. * * The address is derived once from the initial (bootstrap) config and never * changes — config updates do not affect it. * * @example * ```ts twoslash * import { MultisigConfig } from 'ox/tempo' * * const genesisConfig = MultisigConfig.from({ * threshold: 1, * owners: [ * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * * const address = MultisigConfig.getAddress(genesisConfig) * ``` * * @param config - The initial (bootstrap) multisig config. * @returns The multisig account address. */ export declare function getAddress(config: Config): Address.Address; export declare namespace getAddress { type ErrorType = assert.ErrorType | Address.from.ErrorType | Hash.keccak256.ErrorType | Hex.concat.ErrorType | Hex.fromNumber.ErrorType | Hex.fromString.ErrorType | Hex.slice.ErrorType | Errors.GlobalErrorType; } /** * Computes the digest a native multisig owner approves (signs). * * `keccak256("tempo:multisig:signature" || inner_digest || account)`, * where `inner_digest` is the transaction sign payload * ({@link ox#TxEnvelopeTempo.(getSignPayload:function)}). * * The digest is keyed on the permanent `account` derived from the genesis * (bootstrap) config — config updates never change it, so the genesis config * is the correct input even for post-update transactions. * * For a nested multisig owner approval, the parent digest becomes the nested * approval's `payload`, with the nested multisig `account`. * * @example * ```ts twoslash * import { MultisigConfig, TxEnvelopeTempo } from 'ox/tempo' * * const genesisConfig = MultisigConfig.from({ * threshold: 1, * owners: [ * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * * const envelope = TxEnvelopeTempo.from({ * chainId: 1, * calls: [] * }) * * const digest = MultisigConfig.getSignPayload({ * payload: TxEnvelopeTempo.getSignPayload(envelope), * genesisConfig * }) * ``` * * @example * ### From `account` * * If you already have the permanent `account` (for example, recovered from a * stored envelope), pass it directly: * * ```ts twoslash * import { MultisigConfig, TxEnvelopeTempo } from 'ox/tempo' * * const genesisConfig = MultisigConfig.from({ * threshold: 1, * owners: [ * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * const account = MultisigConfig.getAddress(genesisConfig) * * const envelope = TxEnvelopeTempo.from({ * chainId: 1, * calls: [] * }) * * const digest = MultisigConfig.getSignPayload({ * payload: TxEnvelopeTempo.getSignPayload(envelope), * account * }) * ``` * * @param value - The digest derivation parameters. * @returns The owner approval digest. */ export declare function getSignPayload(value: getSignPayload.Value): Hex.Hex; export declare namespace getSignPayload { type Value = { /** The inner transaction sign payload (`tx.signature_hash()`). */ payload: Hex.Hex | Bytes.Bytes; } & OneOf<{ /** The native multisig account address. */ account: Address.Address; } | { /** * The initial multisig config (the bootstrap config that derived the * permanent `account`). Used to derive the account automatically. * Config updates never change `account`, so the genesis config is * also the correct input for post-update transactions. */ genesisConfig: Config; }>; type ErrorType = getAddress.ErrorType | Hash.keccak256.ErrorType | Hex.concat.ErrorType | Hex.from.ErrorType | Errors.GlobalErrorType; } /** * Converts a {@link ox#MultisigConfig.Config} to its RLP tuple form (carried * by the multisig signature `init`). * * Tuple shape: `[salt, threshold, [[owner, weight], ...]]`. The * 32-byte `salt` encodes as a full fixed-width string; other integers use * canonical RLP encoding (zero values encode as `0x`). * * @example * ```ts twoslash * import { MultisigConfig } from 'ox/tempo' * * const tuple = MultisigConfig.toTuple({ * threshold: 1, * owners: [ * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * ``` * * @param config - The multisig config. * @returns The RLP tuple. */ export declare function toTuple(config: Config): Tuple; /** * Validates a native multisig {@link ox#MultisigConfig.Config}. Returns `true` * if valid, `false` otherwise. * * @example * ```ts twoslash * import { MultisigConfig } from 'ox/tempo' * * const valid = MultisigConfig.validate({ * threshold: 1, * owners: [ * { * owner: '0x1111111111111111111111111111111111111111', * weight: 1 * } * ] * }) * // @log: true * ``` * * @param config - The multisig config. * @returns Whether the config is valid. */ export declare function validate(config: Config): boolean; /** Thrown when a native multisig config is invalid. */ export declare class InvalidConfigError extends Errors.BaseError { readonly name = "MultisigConfig.InvalidConfigError"; constructor({ reason }: { reason: string; }); } //# sourceMappingURL=MultisigConfig.d.ts.map