Polymarket.Crypto (Polymarket v0.1.1)

Copy Markdown View Source

Low-level Ethereum cryptographic primitives used to sign Polymarket orders.

Wraps the two native dependencies — ExKeccak for keccak-256 and ExSecp256k1 for ECDSA secp256k1 — behind a small, total API so the rest of the codebase never touches the NIFs directly:

All functions raise ArgumentError on malformed input (wrong byte sizes); a failure here is a programming error, not a recoverable runtime condition.

Summary

Types

A 20-byte Ethereum address.

A 32-byte digest, e.g. a keccak-256 hash.

A 32-byte secp256k1 private key.

A 65-byte r ‖ s ‖ v signature, with v in 27..28.

Functions

Derives the 20-byte Ethereum address controlled by private_key.

Computes the keccak-256 hash of data (a binary or iodata).

Signs a pre-computed 32-byte digest with private_key, returning a 65-byte Ethereum signature r (32) ‖ s (32) ‖ v (1), where v is the recovery id normalised to 27 or 28.

Renders a 20-byte address as its EIP-55 mixed-case checksummed 0x string.

Renders a binary as a lowercase 0x-prefixed hex string.

Types

address()

@type address() :: <<_::160>>

A 20-byte Ethereum address.

digest()

@type digest() :: <<_::256>>

A 32-byte digest, e.g. a keccak-256 hash.

private_key()

@type private_key() :: <<_::256>>

A 32-byte secp256k1 private key.

signature()

@type signature() :: <<_::520>>

A 65-byte r ‖ s ‖ v signature, with v in 27..28.

Functions

address_from_private_key(private_key)

@spec address_from_private_key(private_key()) :: address()

Derives the 20-byte Ethereum address controlled by private_key.

The address is the last 20 bytes of the keccak-256 hash of the 64-byte uncompressed public key (the key without its leading 0x04 prefix).

keccak256(data)

@spec keccak256(iodata()) :: digest()

Computes the keccak-256 hash of data (a binary or iodata).

This is the hash function Ethereum uses everywhere — address derivation, EIP-712, function selectors. It differs from the FIPS-202 :sha3_256 exposed by :crypto, which uses different padding and produces different output.

sign_digest(digest, private_key)

@spec sign_digest(digest(), private_key()) :: signature()

Signs a pre-computed 32-byte digest with private_key, returning a 65-byte Ethereum signature r (32) ‖ s (32) ‖ v (1), where v is the recovery id normalised to 27 or 28.

The signature is deterministic (RFC 6979): the same digest and key always yield the same bytes.

to_checksum_address(address)

@spec to_checksum_address(address()) :: String.t()

Renders a 20-byte address as its EIP-55 mixed-case checksummed 0x string.

Each hex letter is upper-cased when the corresponding nibble of the keccak-256 hash of the lowercase address string is >= 8. Polymarket's L2 POLY_ADDRESS header expects this form (the order wire body, by contrast, uses lowercase).

to_hex(bytes)

@spec to_hex(binary()) :: String.t()

Renders a binary as a lowercase 0x-prefixed hex string.