Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Specifications – ERC-8128
Skip to content

Specifications

@slicekit/erc8128 implements two complementary specifications: ERC-8128 Signed HTTP Requests with Ethereum and the recursive Delegated Signed HTTP Requests extension.

ERC-8128 request signatures

  • A candidate is an RFC 9421 request signature with the exact tag="erc8128", required created and expires, no alg, and a canonical eip155:<chain-id>:<lowercase-address> CAIP-10 keyid.
  • Request-bound signatures cover @scheme, @authority, @method, @path, and @query unconditionally. Received content requires a covered RFC 9530 Content-Digest verified over the exact bytes; received Content-Type must also be covered.
  • Component identifiers are structural. A covered Structured Field using ;sf is parsed and canonically serialized according to RFC 9651.
  • A present nonce means Non-Replayable; an absent nonce means Replayable. There is no separate request replay flag. A winning nonce is consumed atomically as (canonical keyid, nonce) only after every other check passes.
  • created and expires are required. Signers choose the shortest delivery-safe validity window; a baseline route accepts windows up to 60 seconds, while routes may document another maximum. The SDK's 60-second default is an implementation choice, not a protocol-mandated signer value.
  • Universal Account verification runs ERC-6492 first, then ERC-1271 for code-bearing and EIP-7702 accounts, then strict 65-byte, low-s, v=27|28 EOA recovery only for code-free accounts.
  • Malformed Signature-Input, Signature, Content-Digest, or delegation fields fail as whole fields. Eligible candidates share one bounded budget and are evaluated in wire order with stable RFC 9457 failure responses.

The signer generates a nonce by default. Passing { nonce: null } deliberately omits it and creates a Replayable request, which a verifier may accept only with an early-invalidation policy.

Delegated requests

ERC-8128-Delegation is an RFC 9651 Dictionary containing only consecutive, ordered keys g0 through gN. Each value is a Byte Sequence whose bytes are the deterministic CBOR encoding of one 14-element Delegation Link array. The array keeps canonical CAIP-10 identities as strings, follows the EIP-712 struct order, and places the proof last. Indefinite lengths, non-shortest heads, unsupported CBOR types, gaps, reordering, and trailing bytes are rejected.

Each grant uses the exact EIP-712 Delegation domain and struct. A recursive chain enforces issuer/delegate continuity and attenuates the parent grant hash, exact audiences, nested validity windows, maximum request validity, non-replayable requirements, component floors, and permissions.

A delegated HTTP request has exactly one RFC 9421 request signature tagged erc8128-delegated. Its keyid is the leaf delegate and it covers "erc-8128-delegation";sf plus the base request requirements. No root, authorization, or grant proof appears as another RFC 9421 signature member; grant proofs are embedded only in the delegation field.

Verification checks the leaf request proof first, embedded proofs leaf-to-root, canonical revocation state for every link on its issuer's chain, then route permissions, and consumes the leaf nonce last. Only a leaf with signed delegateIsEOA=true receives strict local ECDSA verification; issuers always use Universal Account verification for grant proofs.

The canonical registry coordinates are protocol-owned, never signer-selected. Every link derives its registry chain from its signed issuer, and the exact runtime code hash must be present at the canonical address on that chain. The standards draft has not yet populated its final address and hash table; this repository pins the Slice reference-deployment candidate for production and local testing, while failing closed if that exact deployment is absent.

Registry runtime and status observations are made at the chain's finalized block. Consequently, a revocation or epoch advance is not enforced until that block finalizes. An issuer may read currentEpoch at latest when creating a grant; during the short window after an epoch advance and before finality, that new grant carries the new epoch while verifiers still observe the old epoch and reject it. User-facing status reads use the same finalized view as verification so they do not claim enforcement earlier than verifiers can observe it. The local Anvil runtime uses one slot per epoch, so its finalized view trails latest by two blocks (about two seconds with the configured one-second block time).

Invalid proof is normally 401, an authenticated principal missing a route permission is 403, malformed input is 400 where specified, and unavailable proof or revocation state is retryable at 503.