Technology
How Agapao works underneath
This page is for developers, validators and anyone checking the claims on the home page. Every rule here is enforced by the node software running the devnet today, except the ones marked as not built. The whitepaper has the full design and the reasons behind it.
The project was called Agape before it was renamed Agapao, and the software keeps its original
names: the node is agape-node, the crates are agape-ledger, agape-vm and so on, and addresses still start ag. The name is the
Greek verb agapaō, "to love". The currency is still AGAPE, the noun: the love the network
gives.
Consensus and validators
Agapao runs Malachite, a Rust implementation of Tendermint BFT consensus. A block is decided when validators holding more than two thirds of the active set's voting power sign it, and a decided block is final: there are no reorganisations. The target block time is 2 seconds.
The active set is the 100 eligible validators with the most bonded stake (self-stake plus delegations), recomputed every hour at an epoch boundary, and voting power is that stake, capped at 5% of the set's total once the set has 20 or more members, so it takes at least 7 validators to hold the third that can stop the chain. Proposers are still drawn by full stake. A validator needs 10,000 AGAPE of self-stake and pays a 500 AGAPE registration fee to the treasury. Up to 1,000 validators can be registered. Unbonding takes 21 days, and stake can still be slashed during that time.
| Offence | Penalty |
|---|---|
| Double-signing (two conflicting votes for the same height and round) | 5% of bonded and unbonding stake, and permanent removal |
| Downtime (missing from every commit certificate for 24 hours) | 0.1% of bonded and unbonding stake, and jail until the validator sends an unjail transaction |
Slashed stake goes to the philanthropy treasury, and the operator and every delegator lose the same fraction. A validator's rates can be lowered at once, but an increase to either rate waits 21 days.
Issuance and fees
One AGAPE is 1,000,000 base units. New AGAPE is created only by blocks, and issuance is defined in time rather than per block: each block issues the yearly rate in force at its timestamp, multiplied by the time since its parent, counting at most 60 seconds. Fast blocks can't inflate the supply, and an outage doesn't produce a catch-up payment. There's no supply cap; the tail keeps a security budget that doesn't depend on fees.
| Period | Years | AGAPE a year | AGAPE in the period |
|---|---|---|---|
| 1 | 0 to 2.4 | 21,024,000 | 50,500,000 |
| 2 | 2.4 to 4.8 | 10,512,000 | 25,250,000 |
| 3 | 4.8 to 7.2 | 5,256,000 | 12,625,000 |
| 4 | 7.2 to 9.6 | 2,628,000 | 6,312,500 |
| Tail | 9.6 onward | 1,314,000 | 1,314,000 a year |
Each block's issuance goes to its proposer's validator and is split in order: the validator's philanthropy percentage (0 to 100) to the treasury, its commission (0 to 100% of what remains) to the validator, and the rest to everyone staked with it in proportion to stake. Divisions round down, and rounding remainders go to the validator.
Fees follow demand, on the model of Ethereum's EIP-1559. Every block has a base fee per byte of encoded size and one per 1,000 gas, which rise when the block before was more than half full and fall when it was less, by up to an eighth a block, down to a floor of 1 base unit. The base fees go to the philanthropy treasury instead of being burned, so the proposer can't fill blocks with its own transactions for free. A transaction adds a tip for the proposer. A transfer costs about 0.0027 AGAPE at the starting base fee of 10 base units a byte, and about 0.0005 at the floor. Contract calls and deploys pay for gas on top, from a starting base fee of 4 base units per 1,000 gas.
Philanthropy
The protocol calls a beneficial cause a "charity": a record on chain with an owner, a name,
a content identifier for its documents and one to four withdrawal addresses, created with
the RegisterCharity transaction and served by the API under /charities. Anyone can register one, and only a cause a bonded PSP vets can be on
a slate or receive payouts and donations.
The treasury, causes, PSPs, slates and votes are part of agape-ledger's single
state transition, which every node runs. Payouts don't depend on the contract
runtime, and anyone can audit the balance and every payout from chain state. The treasury
receives the philanthropy share of every block's issuance, every transaction's base fees,
validator registration fees, slate deposits, asset creation fees, slashed stake, the
treasury's part of slashed PSP bonds and contract donations to the treasury.
A payout divides the treasury's whole balance among slates in proportion to the stake voting
for each, rounding down. Each slate's share is split equally among those of its causes
whose service PSP vets them at that moment. A slate with no eligible causes left keeps its
share in the treasury, and so does every rounding remainder. A Donate transaction gives to an eligible cause directly, in AGAPE or in a native asset the cause
has chosen to accept.
| Parameter | Value |
|---|---|
| Payout period | 30 days |
| Minimum PSP bond | 100,000 AGAPE |
| PSP unbonding period | 21 days |
| PSP fee | Up to 3% of what a cause receives |
| Challenge deposit | 1,000 AGAPE |
| Challenge vote | 14 days |
| Slate deposit | 100 AGAPE, paid to the treasury |
| Beneficial causes per slate | 1 to 8 |
| Slates with votes at once | 1,024 |
| Attesting PSPs per cause | 32 |
| Withdrawal addresses per cause | 1 to 4 |
Each cause names a service PSP, which takes a fee of at most 3% of everything the cause receives, at a rate published on the cause's record. The fee can be withdrawn 21 days after the end of the day the cause receives the money. Anyone can challenge a cause's vetting for a 1,000 AGAPE deposit, and stakers vote on it for 14 days. An upheld challenge costs the service PSP 20% of its bond and every other PSP attesting the cause 10%, with the cause's fees they can't yet withdraw. The challenger gets its deposit back and a quarter of what was slashed, and the rest goes to the treasury. A PSP with three upheld challenges in a year is removed for good.
Decided on 8 October 2026 and not built yet: a payout pays at most a sixth of the treasury, and the treasury pays on a PSP's vetting only once its bond has stood for 90 days, and on a cause only once it has been vetted for 30.
Native assets
Anyone can issue a fungible asset on the ledger itself (e.g. a stablecoin, a community or cause token, points) for 1,000 AGAPE, paid to the treasury. Every account, contract and beneficial cause can hold any asset, and wallets show assets beside AGAPE. Fees are always paid in AGAPE, and the treasury, its payouts and validator rewards stay in AGAPE.
An address opts in to an asset before it can hold it, for a refundable deposit of 0.122 AGAPE, so no one can fill an account with tokens it never asked for. A cause's owner chooses which assets it accepts, and its PSP's fee is taken in the asset given. An asset can declare a mint power and a freeze power at creation and only then, each held by an address that can hand it on or renounce it, and a mintable asset can cap its supply for good. Anyone can burn what they hold. Freezing reaches holdings, never what has already been given to a cause, and there's no clawback. Names aren't unique, so a wallet shows each asset with its issuer.
Private payments
The shielded pool is Zcash's Ironwood protocol: the Orchard circuit, with notes that can be
recovered if elliptic-curve cryptography is ever broken (ZIP 2005). Agapao uses the orchard crate (0.16) unchanged and writes no cryptography of its own. Proofs are
Halo 2, which needs no trusted setup.
AGAPE moves three ways. A shield sends it from a public account into the pool, a shielded transfer moves it inside the pool with sender, recipient and amount hidden, and an unshield sends it back out. Shields and unshields reveal their public side and the amount crossing.
The ledger checks each shielded transaction's proof and signatures, refuses any nullifier it has seen, and accepts an anchor only from the last 24 hours of blocks. The pool keeps its own balance, which no transaction may take below zero, so a soundness flaw in the circuit couldn't create AGAPE outside it. Viewing keys show a wallet's transactions without being able to spend. The pool's cryptography isn't post-quantum.
Staking, votes, beneficial causes, PSPs, the treasury and contracts stay public. Shielded AGAPE has to be unshielded before it can be staked or vote.
Contracts
Contracts are WebAssembly modules, run by agape-vm on Wasmtime 48, a
long-term-support release. A contract is compiled once, at deploy, with Wasmtime's
single-pass Winch compiler, and every node keeps the compiled module. Everything that could
differ between machines is fixed: floating point is refused at deploy, every WebAssembly
feature is set explicitly (sign extension, multi-value and bulk memory are on), call depth is
limited to 512 by instrumentation, memory is capped at 16 MiB and code at 128 KiB.
One gas meter covers execution and every host function, and host work is charged before it runs. A call that fails pays for the gas it used and changes nothing else. A contract also holds a refundable deposit of 1,000 base units for every byte it stores. The same deploys and calls give the same state root on arm64 and x86_64, which CI checks on every change.
A contract is an account: it holds AGAPE, keeps its storage in the state tree and emits events. It can donate to a vetted beneficial cause or the treasury, and check whether a cause is vetted. It can't register causes or PSPs, attest, delegate, vote or call another contract, and its code can't change once deployed.
A contract can also hold native assets, send and donate them, and use the mint and freeze powers it holds, including those of an asset it created with itself as the issuer. Host functions let it check other chains' proofs: BN254 and BLS12-381 with Ethereum's precompile encodings, Keccak-256, SHA-256, and SP1 PLONK proofs, which the node checks with SP1's own verifier. A release registry holds values only a node release writes, such as the SP1 verifier keys a release accepts, and contracts read them. These are the building blocks for bridges, which are applications of their own; a bridge to Ethereum is in development in a separate project.
Contracts are written in Rust with agape-sdk. Each embeds a schema of its
methods, arguments, return values and events, which the ledger checks at deploy. Wallets use
the schema to show what a call does before it's signed and to decode results and events.
State, keys and encoding
The state is a Jellyfish Merkle Tree over SHA-256, stored in redb and versioned by height. Every block header commits to the state root after that block, so a value can be checked against a header. Transactions, blocks and state use a canonical borsh encoding with a written specification and golden test vectors. Signatures are Ed25519, verified under ZIP-215.
A node keeps the newest day of state and prunes older versions as it goes. Blocks, certificates, state roots and every voting set are kept for every height, so peers and light clients still follow the chain from genesis. A node that wallets restore from can keep everything instead.
Public addresses are bech32m, ag1… on mainnet and agtest1… on test
networks, and shielded addresses agz1… and agztest1…, so neither
kind can be mistaken for the other or used on the wrong network.
No key signs the genesis. A chain starts from a public configuration that every node reproduces, and the hash of its encoding is the chain id, which every transaction signs. There's no admin key, pause switch or upgrade key anywhere in the ledger, the shielded pool and contracts included.
The wallet
The wallet app is written in Rust with a Slint interface, for macOS, Windows, Linux and
Android. Everything that touches keys or money is in agape-wallet-core, which the
command-line wallet shares. One 24-word BIP-39 phrase derives the public keys (Ed25519, by
SLIP-10) and the shielded spending key (by ZIP-32). The vault is encrypted with a key derived
from your password by Argon2id or, on Android, held in Android Keystore.
Every transaction goes through a plan: the core builds the exact body, writes a summary from it, and signs that body only after you confirm the summary. The wallet is a light client: starting from the genesis its chain id names, it follows the voting set through each change, checks the header at each answer's height against its commit certificate, and checks every balance and record it acts on against that header's state root. A node can still withhold answers or show an old height, but it can't change a balance.
Each release carries the Android app, signed with the Play upload key, as an app bundle and a universal APK. The desktop app has no release builds yet and builds from source, and the app isn't on Google Play yet.
Upgrades and releases
There's no on-chain governance. Protocol parameters are fixed in each release, and changing
one means a new release of agape-node that validators holding more than two
thirds of the voting power choose to run. A release can add rules to a running chain from an
activation height, and the chain ids and activations of known networks are compiled into the
binary.
Releases are built in CI: agape-node for Linux (x86_64 and ARM64) and Windows,
signed with Sigstore keyless signing and shipped with a CycloneDX software bill of
materials, and the Android wallet app with SHA-256 checksums. There's no macOS build. The
install script refuses an archive whose signature doesn't verify.
The devnet
The public devnet's chain id, which changes whenever it is reset, is reported by https://agape.money/api/status. The shielded pool, contracts, donations and every other rule are on from height 1. Its
nodes' API is at https://agape.money/api. Devnet coins have no value. The faucet sends 1,000 devnet AGAPE to an address once a day,
for a few seconds of proof of work in the browser; its API is at https://agape.money/faucet/api.
Specifications
| Parameter | Value |
|---|---|
| Consensus | Malachite (Tendermint BFT), stake-weighted |
| Active validators | Top 100 by bonded stake, recomputed hourly |
| Voting power cap | 5% of the active set per validator, from a set of 20 |
| Target block time | 2 seconds |
| Finality | When a block is decided (more than 2/3 of voting power signs it) |
| Maximum block size | 4 MiB |
| Signatures | Ed25519 with ZIP-215 verification |
| State commitment | Jellyfish Merkle Tree over SHA-256 |
| Fees | A base fee per encoded byte that follows demand, from 10 base units down to a floor of 1, paid to the treasury, plus a tip to the proposer |
| Shielded pool | Zcash Ironwood (orchard 0.16), Halo 2 proofs, no trusted setup |
| Shielded anchor window | 43,200 blocks (24 hours) |
| Contract runtime | Wasmtime 48 LTS, Winch compiler, no floating point |
| Contract code limit | 128 KiB |
| Contract memory limit | 16 MiB |
| Gas limits | 1 billion per transaction, 2 billion per block |
| Gas price | A base fee per 1,000 gas that follows demand, from 4 base units down to a floor of 1 |
| Storage deposit | 1,000 base units per stored byte, refundable |
Further reading
- Whitepaper The design, the economics and the reasons behind them.
- API explorer Every request the devnet's nodes answer, with a way to send them.
- Releases Signed node builds with checksums and SBOMs.
- The project on GitLab Releases and the project's page. The source repository isn't public yet.