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…
Signer
…
Account
…
Observed
…
SymbolShares heldVerifiedDigest

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.