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", requiredcreatedandexpires, noalg, and a canonicaleip155:<chain-id>:<lowercase-address>CAIP-10keyid. - Request-bound signatures cover
@scheme,@authority,@method,@path, and@queryunconditionally. Received content requires a covered RFC 9530Content-Digestverified over the exact bytes; receivedContent-Typemust also be covered. - Component identifiers are structural. A covered Structured Field using
;sfis parsed and canonically serialized according to RFC 9651. - A present
noncemeans Non-Replayable; an absentnoncemeans Replayable. There is no separate request replay flag. A winning nonce is consumed atomically as(canonical keyid, nonce)only after every other check passes. createdandexpiresare 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|28EOA 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.