How It Works
ERC-8021 appends a small suffix to a transaction’s calldata. The suffix is invisible to the contract being called — the EVM discards trailing bytes — so adding it never changes execution semantics. It just makes the transaction identifiable as having come through your app to anyone reading calldata off-chain.Tagging a transaction is open to everyone. Whether a code gets credited on a leaderboard or rewards program is resolved at the registry/indexer layer, not at the tagging step.
Install
viem is an optional peer dependency — only required if you call verifyTx to decode a tag from a transaction hash.
The SDK exports four functions:
Quickstart
If you’ve been issued a code (celo_xxxxxxxx) — for example through Proof of Ship onboarding or a hackathon registration — pass it directly:
[a-z0-9_] (1–32 characters) is a valid code. If a program assigned you a code, it must be present in the suffix — leaderboards and reward programs only credit the assigned code, not one you derive yourself with codeFromHostname. You can include both:
Tagging a Contract Call
Concatenate your encoded calldata with the suffix:dataSuffix directly and wagmi handles the concatenation:
The Layering Rule
ERC-8021 suffixes can carry multiple codes, but each code should only be added by the entity it represents:- Your app code — added by your app, as shown above.
- A platform code like
minipay— added by the platform itself (the wallet or cohort layer), never by your app.
Verifying It Worked
verifyTx returns null (never throws) if no tag is found. For offline decoding without an RPC call, use fromDataSuffix(rawCalldata) instead.
Resources
| Resource | Link |
|---|---|
| Source & full docs | github.com/celo-org/attribution-tags |
| npm package | @celo/attribution-tags |
| ERC-8021 standard | oxlib.sh/ercs/erc8021 |
Related
- x402: Agent Payments
- Fund your Project — Proof of Ship progress tracking uses attribution tags
- Launch Checklist