Build on revenue tokens
The calls a contract or an app makes on a revenue token: sync, claims, the asset books, the earning supply, drops and signed actions.
On this page
A revenue token is an ordinary ERC-20 with an income ledger inside it. Anything that can hold an ERC-20 can hold one, and any contract can read its income, pull it in, claim it and pass it on. Nothing about the token changes after the mint, so what you build on it can rely on every rule below for as long as the token exists.
This section is for builders. It covers the calls a contract or an app makes, how income accrues, how a new platform plugs in as a door, the add-ons as worked examples, the read APIs, and a list of things to build.
The calls
Every call below is on the revenue token itself (IHookrRevenueToken). Assets are numbered: asset 0 is always native ETH, and the rest are the up to three currencies the token's streams pay in.
| Call | What it does |
|---|---|
sync() | Pulls every door, recognizes what arrived and starts releasing it. Anyone may call; the caller gets the tip when the pull is at least 0.001 ETH. |
syncSome(doors) | The same over the listed door indexes only, to step past a door that misbehaves. |
claimable(account, asset) | What account can claim of asset now, with the release run up to this block. |
claim(asset, to) / claimAll(to) | Pays the caller's income in one asset, or every asset, to to. |
releasable(asset) | How much of asset a release now would move to holders. |
poke() | Releases every asset's due income. Transfers, claims and syncs do it too. |
assetCount() / assetAt(asset) | The asset list and each asset's books: received, paid, what is still releasing and until when. |
earns(account) / earningSupply() | Whether an address earns, and the supply that does. The PoolManager, 0xdead, the drop box and the token itself never earn. |
doorCount() / doorAt(i) | The doors, fixed at the mint, each with its kind, its contract and its gas stipend. |
depositBonus(asset, amount) | Pays income in from anyone, released like the rest, with no tip. |
dropBox() / dropStray(asset) | The token's drop box, and turning any other ERC-20 sent to the token into a drop. |
streamSeconds() / tipBps() / bridge() / bridgeBps() | The release period, the tip and the Fee Bridge slice, all fixed at the mint. |
A sync needs gas for every door's stipend. A call that leaves too little reverts with SyncStarved instead of skipping a door; send more gas, or skip the door with syncSome.
The tokenizer adds the record of each token: tokenCount() and tokenAt(i) list every token it made, tokenizations(token) says who made it, which way in, its term and Hookr's leg, and streamsOf(token) lists each stream with how and when it ends.
Signed actions
A holder never needs gas. Every action can be signed and sent by anyone, under the token's EIP-712 domain (eip712Domain(), EIP-5267):
permit: ERC-2612, with sequential nonces.transferWithAuthorizationandreceiveWithAuthorization: EIP-3009-style signed transfers with random nonces, the form x402's EVM "exact" scheme settles with.claimWithSigandclaimAllWithSig: a claim that pays only thetothe holder signed, refused past its deadline;cancelAuthorizationrevokes an unused nonce.
Each signature can come from an EOA or a contract wallet through ERC-1271, so a smart wallet or an EIP-7702 account signs like anyone else. Permit2 works as with any ERC-20.
The rest of this section
- How income accrues: the release period, what a transfer settles, and drops.
- Doors for new platforms: the interface a door answers and how the tokenizer admits one.
- Add-ons and read APIs: time shares, day wrappers and the compounder as working examples, with their addresses, and the HTTP reads.
- Ideas to build: what is live and what is open for anyone to build.