sdk-js/README.md

357 lines
17 KiB
Markdown

# @aere/sdk
Official AERE Network TypeScript SDK. Wraps `ethers v6` with typed clients for the
live AERE L1 (chain ID 2800): the DeFi, agentic-settlement, compliance,
account-abstraction and post-quantum contract surface, the seedless hybrid PQC
wallet, and AERE's native NIST post-quantum precompiles.
**SDK version:** 0.16.12
**Last updated:** 2026-08-19 (consensus and network facts; the rest is as of 2026-07-16)
**Network state at this release:** 35+ typed contract clients over a canonical
address book of 130+ live contracts on chain 2800.
---
## Network parameters
| | |
|---|---|
| Chain name | AERE Network |
| Chain ID | 2800 (`0xAF0`) |
| Consensus | Hyperledger Besu QBFT, classical secp256k1 ECDSA |
| Validators | 7, Byzantine-fault tolerance f=2, commit quorum 5 of 7 |
| Operator / client diversity | Single operator (Foundation), single client (Besu) today |
| Block period | 0.5 s (500 ms) target, sub-second deterministic finality |
| Native token | AERE (18 decimals) |
| Max supply | 2,800,000,000 AERE (capped at genesis-v2, 2026-05-07) |
| EVM ruleset | Pectra + Fusaka opcode and precompile set (Besu), plus five AERE post-quantum precompiles; not full parity with Ethereum mainnet (the beacon-chain system contracts, e.g. EIP-4788 beacon roots, have no code on chain 2800) |
| HTTP RPC | `https://rpc.aere.network` |
| WebSocket RPC | `wss://wss.aere.network` |
| Explorer (Blockscout) | `https://explorer.aere.network` |
| Indexer REST | `https://api.aere.network` |
## Consensus and post-quantum boundary (read this)
AERE draws a hard line between consensus and the application layer, and this SDK
keeps it:
- **Consensus is classical ECDSA on every block, with a post-quantum checkpoint
every 32 blocks.** Blocks are proposed and sealed under Besu QBFT with secp256k1
ECDSA signatures (nine Foundation validators, quorum 6 of 9, f=2). Since block
13,014,000 anchor blocks also carry, under the block hash, a certificate of
validator Falcon-512 seals, and since 2026-08-14 a node rejects an anchor block
with fewer than three valid seals (f+1 of nine, not a quorum). That is the whole
post-quantum part of consensus: not a per-block quorum (the claim published on
2026-08-15 was withdrawn on 2026-08-19). A second client (Nethermind) validates
and follows the public chain at client2.aere.network; it does not produce blocks.
- **PQC lives at the application layer.** Five NIST post-quantum verification
precompiles are live on mainnet (see below). Contracts and this SDK use them for
application-layer signatures, attestations, key registries, agent DIDs, t-of-n
custody and a seedless wallet. None of that makes mainnet consensus
post-quantum, and the SDK never claims it does.
## Genesis allocation (2,800,000,000 AERE)
| Wallet | Allocation | Address |
|---|---:|---|
| Strategic Investor | 100,000,000 | `0xaee2f3989f0AB23296Fa3b92247fe67587141311` |
| Foundation (chain admin) | 180,000,000 | `0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3` |
| Mining Reserve | 1,400,000,000 | `0x038f59A40ceeCd599A4588E4B0ff4642a0fbfFB8` |
| Ecosystem Reserve | 560,000,000 | `0xB6a364F47d21DC2CbEB803565c111c1026e11C75` |
| Team Reserve | 420,000,000 | `0x7968C438204a78B4e032fcFFd9A56Edb15fdCCdf` |
| Airdrop Reserve | 140,000,000 | `0x261913fA73D6F109382F1aE98Ff6822ff03628B1` |
## What the SDK covers
The canonical address book (`AERE_MAINNET` in `src/addresses.ts`) maps 130+ live
contracts on chain 2800. On top of it the SDK ships 35 typed client classes (34
dedicated contract clients plus the `AereClient` facade, which itself wraps 8
core contracts), plus function-based PQC, wallet and MPC modules, grouped by
domain:
| Domain | Representative clients |
|---|---|
| Core L1 | `AereClient` (WAERE, locked + delegated staking V2, identity, faucet, AMM factory, bridge handles) |
| Flywheel | `sAEREClient` (ERC-4626 receipt vault, V2), `AereSinkClient` (immutable 3-bucket router) |
| DeFi | `LendingMarketClient`, `AereInsuranceFundClient`, `RWATransferAdapterClient`, `AereCoreBookClient` (native CLOB) |
| Rollup / RaaS | `AereRaaSFactoryClient`, `AereRollupSettlementClient` |
| Agentic (x402) | `AereAgentClient`, `AERE402SettlementClient`, `createAere402Middleware`, `AereAgentBondClient`, `AereAIReputationClient`, `AereInferNetClient`, `AereAgentMemoryVaultClient` |
| Compliance | `AereSanctionsRegistryClient`, `ChainalysisOracleWrapperClient`, `AereTravelRuleHashRegistryClient`, `AereForensicEventRegistryClient`, `AereZKScreenClient`, `AereAIProofClient`, `AereCompliancePoolClient`, `AereAttestationGatewayClient` |
| Payments | `AereStateChannelsClient` (bidirectional channels + HTLC), `BestExClient` (MiCA Article 78 receipts) |
| Post-quantum | `AerePQCClient`, `AerePQCKeyRegistryClient`, `AereAgentDIDClient`, `AereCryptoRegistryClient`, `AereHybridAuthorizerClient` |
| Account abstraction | `ModularAccountClient`, `SessionKeyClient`, `SocialRecoveryClient`, `AerePQCSocialRecoveryClient` (ERC-7579 modular accounts, bound to AereEntryPointV2) |
| PQC custody | `AereThresholdAccountClient` (non-custodial t-of-n post-quantum ERC-4337 account) |
| Seedless wallet | `wallet/` module (see below) |
Ownership is **not** uniform. The original 2026-05-07 core contracts (WAERE,
treasury, identity, faucet, and similar) are owned by the Foundation key
`0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3`. Many later corrected forks and
frontier primitives (the `*V2` redeploys, the PQC wave-1 contracts, the MPC and
interop primitives) are either **ownerless** or owned by the deployer key
`0xbeB3…6465`, and several are deployed **inert** (holding no value, not wired
live) pending a founder-supervised migration. Each entry in `src/addresses.ts`
documents its own owner, status and any deprecation. Do not assume a single owner
across the whole book.
## Post-quantum precompiles (5 live on mainnet)
Activated on chain 2800 at block 9,189,161. Address band `0x0AE1`..`0x0AE5`:
| Precompile | Scheme |
|---|---|
| `0x0AE1` | Falcon-512 (NIST) |
| `0x0AE2` | Falcon-1024 (NIST) |
| `0x0AE3` | ML-DSA-44 (Dilithium2, FIPS 204) |
| `0x0AE4` | SLH-DSA-SHA2-128s (SPHINCS+, FIPS 205) |
| `0x0AE5` | SHAKE256 |
`src/pqc` provides pure-JS keygen and internal-interface signing for all four
signature schemes, proven interoperable against the live precompiles
(`src/test/pqc-interop.test.ts`). Falcon-1024 and ML-DSA-44 signatures can be
recorded on-chain through `AerePQCAttestation`
(`0x465d9E3b476BF98Aa1393079e240Db5D2a9bEA6A`), which verifies each signature via
the matching precompile before storing it. AERE also ships extended EIP-2935
block-hash lookback (an 8191-block window) live on mainnet, used by the
canonical-binding validity anchors.
## Seedless hybrid PQC wallet
`src/wallet` implements a wallet with **no seed phrase**: a WebAuthn passkey is
the everyday factor and a NIST Falcon-512 co-owner is the quantum-durable root.
```ts
import {
createSeedlessAccount, generateFalconRoot, encryptFalconSecretKey,
upgradeToPostQuantum, buildUpgradeAttestation, signPqcAccountUserOp,
} from '@aere/sdk';
const descriptor = createSeedlessAccount({ passkey }); // pre-upgrade
const root = generateFalconRoot(); // Falcon-512 keypair
const enc = encryptFalconSecretKey(root, passphrase); // client-side-encrypted
const upgraded = upgradeToPostQuantum(descriptor, root.publicKey); // one-tap PQC
```
The Falcon root is verified by the on-chain `AereFalcon512Verifier` /
`AerePQCAttestation` path; the secret key is encrypted client-side and never
leaves the device unencrypted. See `docs/PQC-WALLET-DESIGN.md`.
## Post-quantum identity — one front door
The PQC pieces (Falcon root, key registry, agent DID, guardians) stitch into a
single flow. Three ready-made entry points:
- **End-to-end example** — `examples/pqc-identity-e2e.mjs`. One runnable script
that generates a Falcon-512 root, client-encrypts it, registers it with on-chain
proof-of-possession, opens an `AereAgentDID` with a revocable session key, and
sets a quantum-durable guardian committee. It is **read-only**: it reads live
chain state, **cross-checks the PoP / issuance / action challenges against the
on-chain views**, and prints the exact transactions each write flow would send —
nothing is signed with a funded key. Run:
```bash
npm run build && node examples/pqc-identity-e2e.mjs
```
- **Reference wallet dApp** — `pqc-wallet/` in the (not yet published) website source tree. A single
self-contained HTML page (no external CDN, all crypto bundled inline) that walks
the same flow in the browser against the live read-only RPC. Build it with
`node pqc-wallet/build.mjs`; the output is served at `/pqc-wallet.html`.
- **Project scaffolder** — `create-aere-pqc` (in the private working tree; not yet published).
Generates a wired-up wallet or agent project:
```bash
node aerenew/tools/create-aere-pqc/index.mjs my-pqc-wallet # or --template agent
cd my-pqc-wallet && npm install && npm run dev
```
The `AerePQCSocialRecoveryClient` guardian committee (M-of-N NIST PQC keys, 48h
timelock) uses the repo-shipped `AerePQCSocialRecoveryModule` contract; that module
is **not yet deployed to mainnet**, so those flows construct calldata and derive the
recovery challenge locally rather than reading a live module.
## Install
```bash
npm i @aere/sdk ethers
```
## Quickstart
```ts
import { AERE_MAINNET } from '@aere/sdk/addresses';
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider(AERE_MAINNET.rpc);
// Read a balance
const bal = await provider.getBalance(AERE_MAINNET.Foundation);
console.log(ethers.formatEther(bal), 'AERE');
// Subscribe to incoming WAERE transfers for an address
const waere = new ethers.Contract(
AERE_MAINNET.WAERE,
['event Transfer(address indexed from, address indexed to, uint256 value)'],
provider,
);
waere.on('Transfer', (from, to, value) => {
if (to.toLowerCase() === '0xMyHotWallet'.toLowerCase()) {
console.log(`got ${ethers.formatEther(value)} WAERE from ${from}`);
}
});
// Delegated stake 100 AERE via the canonical AereStakingV2 pool
const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const staking = new ethers.Contract(
AERE_MAINNET.AereStakingV2,
['function delegate(address validator) payable'],
signer,
);
const tx = await staking.delegate(validatorAddress, { value: ethers.parseEther('100') });
await tx.wait();
```
## CLI (`aere`)
The SDK ships a small, read-only developer CLI. After `npm i @aere/sdk` it is on
your path as `aere`; from a clone, build first (`npm run build`) and run
`node dist/cli/aere-cli.js <command>`.
Every command is **read-only or purely local**. The CLI never signs a real
transaction and never accepts a private key. Values are read live from the RPC
and printed verbatim; on an RPC or connection error it writes to stderr and exits
non-zero.
```bash
aere chain # chain id, block height, base fee, gas price, validators, peers
aere block <number|latest> # block summary: hash, parent, timestamp, tx count, gas, proposer
aere tx <hash> # transaction + receipt summary
aere addr <address> # native balance, nonce, and code size
aere pqc schemes # supported PQC schemes, precompiles, key/signature sizes
aere pqc keygen --scheme <1-4> # generate a PQC keypair locally (public key only)
```
Options:
| Option | Applies to | Meaning |
|---|---|---|
| `--rpc <url>` | all chain commands | RPC endpoint (default `https://rpc.aere.network`) |
| `--scheme <1\|2\|3\|4>` | `pqc keygen` | 1=Falcon-512, 2=Falcon-1024, 3=ML-DSA-44, 4=SLH-DSA-SHA2-128s |
| `--show-secret` | `pqc keygen` | also print the secret key. Dangerous, off by default |
| `--version`, `-V` | | print the SDK version |
| `--help`, `-h` | any | usage (also `aere <command> --help`) |
```bash
$ aere chain
AERE chain — https://rpc.aere.network
Chain ID 2800 (0xaf0)
Block height 9520927
Base fee 1.0 gwei
Gas price 1.0 gwei
Validators 7
Peers 7
```
## State window on the public RPC (read before pinning a historical block)
Both public endpoints are **pruning full nodes**, not archive nodes.
- Blocks, transactions, receipts, logs and `qbft_getValidatorsByBlockNumber` go back to **block 0**.
- **World state is kept for only about the most recent 512 blocks**, roughly 4 minutes 25 seconds
at the measured 517 ms block interval. That bounds `eth_getBalance`, `eth_getCode`,
`eth_getStorageAt`, `eth_call`, `eth_getProof` and `eth_getTransactionCount`.
Outside the window most methods say so: `eth_getBalance` / `eth_getCode` / `eth_getStorageAt`
return `null`, and `eth_getProof` returns `-32000 World state unavailable`.
**`eth_getTransactionCount` does not.** It returns `0x0`, which is well formed and
indistinguishable from an account that has never transacted. Reproduce it yourself: block
8,236,382 contains a transaction from `0xbeb33d20dfbbd49ec7ac1f617667f1f02dfd6465` with nonce
123,063, and the endpoint still answers `0x0` for that address at that block.
`StateWindowReader` returns a value or throws. It never returns a placeholder.
```ts
import { StateWindowReader, StateWindowError } from '@aere/sdk';
const reader = new StateWindowReader((m, p) => provider.send(m, p));
await reader.getTransactionCount(addr); // latest: fine
await reader.getBalance(addr, head - 100); // inside the window: fine
try {
await reader.getTransactionCount(addr, 8_236_382); // throws, never returns 0
} catch (e) {
if (e instanceof StateWindowError) console.log(e.detail.reason);
}
// Has this account ever signed anything? Answered only where it can be answered.
await reader.hasEverSigned(addr); // { signed, nonce, atBlock, method }
// Do not trust the 512 constant, measure it against the endpoint you are using.
await reader.measureWindow(); // { head, deepestOkDepth: 511, firstFailDepth: 512 }
```
Three rules if you are not using the reader: read state at `latest`; check the depth before
pinning a historical block; and never test a nonce for zero at a historical block.
## Operational notes (honest state)
- **Non-custodial.** End users hold their own keys. Consumer apps (wallets, card programs)
can use Privy / Magic / Web3Auth to provision wallets via email/social, then
pass that signer into the SDK, or use the seedless PQC wallet above.
- **Fiat rails are out of scope.** AERE is the on-chain settlement layer; fiat
IBANs / cards / SEPA come from a BaaS partner (Striga, Baanx, Kulipa, etc.).
- **Decentralization.** 7 QBFT validators give f=2 (the chain keeps producing
blocks while up to 2 validators are down), commit quorum 5 of 7. All 7 are
operated by the Foundation on a single client (Besu), so this is
fault-tolerance, not yet operator or client diversity. Broader validator
operators and a second client are roadmap.
- **Foundation key, not a multisig.** `0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3`
is a single-key EOA (zero bytecode on-chain), described here as a
Foundation-controlled account. A real Safe-style threshold multisig is roadmap,
not deployed. Governance contracts (Governor + Timelock + gAERE) are deployed
but own nothing until an audit-gated ownership transfer runs.
- **Price oracle.** `AereOracleV2` enforces a minimum fresh-reporter quorum
(`getPrice` reverts below it) and supersedes the flawed V1, which returned a
median even with a single fresh reporter. The V1 contract stays the live read
source for existing consumers until a founder-supervised repoint. Treat the
live feed as single-reporter-grade until that repoint lands.
- **Cross-chain bridging is not yet value-carrying.** The legacy `AereBridge`
reports `threshold()` == 1 on-chain and has no operational relayer. The current
approach is the Hyperlane-based `AereWarpRouteV3`, whose AERE side is deployed
but whose Ethereum leg awaits L1 bring-up. Do not route value across the bridge
until threshold expansion and a relayer are live.
- **Audit status.** Contracts have had an internal self-audit (Slither, Aderyn,
Semgrep, Mythril, SMTChecker, Halmos, Medusa) and several confirmed findings
were fixed via the `*V2` corrected forks documented in `src/addresses.ts`. An
external third-party audit is still pending; do not read "audited" as external.
- **Validity anchors.** The full-EVM validity anchors (`AereEVMValidityV2`,
`AereEVMValidityBatchV2`) are deployed and canonical-bound but not yet
exercised on mainnet (`provenCount()` reads 0 for both).
## Roadmap (deployed but inert, or not yet live)
Several contracts are on-chain but inert (holding no value, not wired live)
pending a founder-supervised migration, and a few product surfaces are not yet
deployed. Representative items:
- Cross-chain relayer + Ethereum-side counterparties for the Warp Route / bridge
- A real Safe-style Foundation multisig, and the audit-gated governance ownership
transfer
- Multi-operator validator set and a second consensus client
- External third-party security audit
- Founder-supervised migrations for the `*V2` inert forks (sAEREv2, settlement
hub V2, delegate-7702 V2, and others; runbooks live under `aerenew/docs/`)
Each contract's exact status is documented inline in `src/addresses.ts`.
## Source
- SDK source: <https://git.aere.network/aere-network/sdk-js>
- Contract source: <https://git.aere.network/aere-network/aere-contracts> (published Solidity sources and tests; the full working tree is private)
- Website source: not published yet
## License
MIT