Polymarket.Crypto.Eip712 (Polymarket v0.1.1)

Copy Markdown View Source

Minimal EIP-712 typed-data hashing, tailored to Polymarket orders.

Polymarket's Order struct contains only static ABI types (uint256, address, uint8, bytes32), so encoding a struct's data is simply each field left-padded to a 32-byte word and concatenated — no dynamic-type or nested-struct handling is required. This module deliberately implements only that subset.

The pieces, in EIP-712 terms:

  • type_hash/1keccak256(encodeType).
  • hash_struct/2keccak256(typeHash ‖ encodeData).
  • domain_separator/4 — the hashStruct of the standard EIP712Domain.
  • digest/2keccak256(0x19 0x01 ‖ domainSeparator ‖ hashStruct), the 32-byte value that is finally signed.

Summary

Functions

Assembles the final EIP-712 signing digest from a domain separator and a struct hash: keccak256(0x19 0x01 ‖ domainSeparator ‖ hashStruct).

Computes the domain separator for an EIP-712 domain without a verifying contract (name, version, chain_id).

Computes the domain separator for the standard EIP-712 domain (name, version, chain_id, verifying_contract).

Left-pads a 20-byte address to a 32-byte word.

Passes a 32-byte bytes32 value through unchanged (it is already one word).

Encodes a dynamic string value to its 32-byte EIP-712 word, keccak256(value).

Left-pads a uint8 to a 32-byte word.

Left-pads a non-negative uint256 to a 32-byte big-endian word.

Hashes a struct: keccak256(typeHash ‖ encodeData). encoded_fields is the list of already-encoded 32-byte words, in the struct's declared field order.

The type hash for an EIP-712 struct: keccak256(encodeType). encode_type is the canonical type string, e.g. "Order(uint256 salt,...)".

Functions

digest(domain_separator, hash_struct)

@spec digest(<<_::256>>, <<_::256>>) :: <<_::256>>

Assembles the final EIP-712 signing digest from a domain separator and a struct hash: keccak256(0x19 0x01 ‖ domainSeparator ‖ hashStruct).

domain_separator(name, version, chain_id)

@spec domain_separator(binary(), binary(), non_neg_integer()) :: <<_::256>>

Computes the domain separator for an EIP-712 domain without a verifying contract (name, version, chain_id).

A verifyingContract-less domain has a distinct type hash, so this is not the same as domain_separator/4 with a zero address. Polymarket's ClobAuthDomain (used for L1 API-key authentication) omits the verifying contract.

domain_separator(name, version, chain_id, verifying_contract)

@spec domain_separator(binary(), binary(), non_neg_integer(), <<_::160>>) ::
  <<_::256>>

Computes the domain separator for the standard EIP-712 domain (name, version, chain_id, verifying_contract).

encode_address(address)

@spec encode_address(<<_::160>>) :: <<_::256>>

Left-pads a 20-byte address to a 32-byte word.

encode_bytes32(value)

@spec encode_bytes32(<<_::256>>) :: <<_::256>>

Passes a 32-byte bytes32 value through unchanged (it is already one word).

encode_string(value)

@spec encode_string(binary()) :: <<_::256>>

Encodes a dynamic string value to its 32-byte EIP-712 word, keccak256(value).

Per EIP-712, dynamic types (string, bytes) contribute the keccak-256 hash of their contents rather than the value itself.

encode_uint8(value)

@spec encode_uint8(0..255) :: <<_::256>>

Left-pads a uint8 to a 32-byte word.

encode_uint256(value)

@spec encode_uint256(non_neg_integer()) :: <<_::256>>

Left-pads a non-negative uint256 to a 32-byte big-endian word.

hash_struct(encode_type, encoded_fields)

@spec hash_struct(binary(), [<<_::256>>]) :: <<_::256>>

Hashes a struct: keccak256(typeHash ‖ encodeData). encoded_fields is the list of already-encoded 32-byte words, in the struct's declared field order.

type_hash(encode_type)

@spec type_hash(binary()) :: <<_::256>>

The type hash for an EIP-712 struct: keccak256(encodeType). encode_type is the canonical type string, e.g. "Order(uint256 salt,...)".