proof-of-reserves.org
This page asks the service what it holds, then checks the answer itself.
It rebuilds the EIP-712 digest from the published fields and recovers the
signing address in your browser. Nothing below is taken on the server's word.
checking…
Each row is signed on its own, so a consumer can carry the one it needs on
chain without the other forty. There is no expiry: observedAt
is a fact about the reading, and how stale a reading may be is the
consumer's policy, not ours.
What this proves is what the broker said, not what is true, and it sits
below governance rather than above it.
API
Public, unauthenticated, CORS open. No key, no rate-limit headers, no signup.
GET/v1/reserves
Every position on the account. Each one signed separately, so you can take one and leave the rest.
curl -s https://proof-of-reserves.org/v1/reserves
GET/v1/reserves/{symbol}
One asset. A symbol the broker does not list returns a signed zero rather than a 404, because
“we hold none of this” is exactly the statement a caller gating a mint wants to hear.
curl -s https://proof-of-reserves.org/v1/reserves/AAPL
GET/v1/signer
The address to pin, and the EIP-712 domain. Confirm it out of band before trusting anything signed.
curl -s https://proof-of-reserves.org/v1/signer
GET/health
Liveness. Touches nothing upstream, so a green health check says nothing about the broker.
curl -s https://proof-of-reserves.org/health
A response
Live, fetched when you loaded this page.
Fields
- symbol
- As the broker names it.
- quantity
- Integer, scaled by
10^decimals. A string, so a JSON parser cannot round it away.
- decimals
- The scale. Carried explicitly so you never assume it. If it is not what you expect, revert rather than rescale.
- accountId
- The brokerage account the reading came from.
- observedAt
- Unix seconds at which the broker was read.
- signature
- 65 bytes,
r ‖ s ‖ v, v in {27, 28}. Ready for ecrecover.
- digest
- The EIP-712 digest. Recompute it; do not trust it.
- quantityDecimal
- Convenience for humans. Not signed. Never trust it over
quantity.
Verifying on chain
Standard EIP-712 over this struct and domain. There is no chainId and no
verifyingContract: an attestation is a statement about the world, not about a chain,
and pinning it to one would stop every other consumer using it.
struct ReserveAttestation {
string symbol;
uint256 quantity;
uint8 decimals;
string accountId;
uint64 observedAt;
}
EIP712Domain { name: "proof-of-reserves.org", version: "1" }
There is no expiry field, on purpose. observedAt is a fact about the reading;
how stale a reading may be is your policy, not ours. A contract enforces
block.timestamp - observedAt <= maxAge with its own maxAge.
Keep it tight: the cost of this choice is that the attestor cannot revoke.