Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/CONFIG_AND_DEPENDENCIES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# YAA β€” Config, Resources, Keys & Dependencies Inventory

> What YetAnotherAA actually depends on: secrets/private keys, endpoints/services, chain
> config. Feeds two things: (1) **beta security hygiene** (dev keys must not ship), and
> (2) the **zero-backend / decentralization** design β€” which of these can be user-configured
> ("use AAStar's or your own") vs which must be *eliminated* (relay + API-key model).
> Date: 2026-07-02. Source: `aastar/.env` + `aastar-frontend/.env.local` + code.

Disposition legend for the zero-backend target:
- πŸ”΄ **Eliminate** β€” a server-only secret; remove via the relay + API-key model (never in a browser).
- 🟒 **User-configurable endpoint** β€” AAStar default OR the user's own (decentralization choice).
- 🟑 **Dev/test only** β€” must NOT be present in a production/beta build.
- βš™οΈ **App/runtime flag** β€” non-secret configuration.

## 1. Secrets & private keys (backend `aastar/.env`)

| Key | Purpose | Disposition |
|---|---|---|
| `JWT_SECRET` | signs the app session JWT | πŸ”΄ β†’ auth root becomes passkey/KMS session (drop server JWT) |
| `USER_ENCRYPTION_KEY` | AES-256 at-rest encryption (32 chars) | πŸ”΄ β†’ client-side encryption keyed off passkey/KMS |
| `KMS_API_KEY` | KMS access (injected by the `/kms-api` proxy) | πŸ”΄ β†’ replaced by the **user's own API key** (direct KMS) |
| `PIMLICO_API_KEY` | ERC-4337 bundler | πŸ”΄ β†’ user's key / public/sponsored bundler |
| `DEPLOYER_PRIVATE_KEY` (config `deployerPrivateKey`; not in current .env β€” maps from `ETH_PRIVATE_KEY` or unset) | relays passkey **account deploy** (`submitCreateWithPasskey`) | πŸ”΄ β†’ **AAStar relay service** (see `RELAY_SERVICE_PROPOSAL.md`) |
| `ETH_PRIVATE_KEY` | relays **recovery** `executeRecovery()` on-chain | πŸ”΄ β†’ relay service (same pattern as deploy) |
| `RESEND_API_KEY` | email OTP send | πŸ”΄/drop β†’ OTP optional; passkey is primary |
| `ETHERSCAN_API_KEY` | explorer lookups | 🟒 optional / user-configurable |
| `TELEGRAM_BOT_TOKEN` | ops liveness alerts (monitor) | πŸ”΄ ops-only (never client) |
| `DATA_TOOLS_PASSWORD` | `/data-tools` admin gate | πŸ”΄ admin-only |
| `PRIVATE_KEY`, `PRIVATE_KEY_{JASON,ANNI,BOB,BROWN,CHARLIE,JACK,SUPPLIER}`, `TEST_PRIVATE_KEY` | **test EOAs** for L1 scripts | 🟑 **dev-only β€” must not ship to beta/prod** |
| `BLS_TEST_PRIVATE_KEY_1/2` (+ node ids/pubkeys) | BLS test-node keys | 🟑 dev-only |

> Beta gate: confirm the 🟑 dev keys are absent from any deployed `.env` (readiness DoD #8:
> "codebase secret scan clean"). The πŸ”΄ set is what the relay + API-key model removes.

## 2. Endpoints / external services (🟒 user-configurable in the zero-backend model)

| Config | Service | AAStar default | Self-config? |
|---|---|---|---|
| `ETH_RPC_URL` / `SEPOLIA_RPC_URL{,2,3}` / `RPC_URL` | chain RPC | publicnode / infura | 🟒 own RPC |
| `BUNDLER_RPC_URL` / `PIMLICO_BUNDLER_URL` / `CANDIDE_BUNDLER_URL` | ERC-4337 bundler | Pimlico (via key) | 🟒 own bundler |
| `KMS_BASE_URL` / `KMS_ENDPOINT` / `KMS_PROXY_URL` / `NEXT_PUBLIC_KMS_URL` | KMS (WebAuthn ceremonies + signing) | `kms.aastar.io` / `kms1.aastar.io` | 🟒 own/community KMS |
| BLS signer network (`NEXT_PUBLIC_BLS_SEED_NODE`, DVT nodes) | BLS aggregate signatures | `yetanotheraa-validator.onrender.com`, `dvt1/2/3.aastar.io` | 🟒 own signer set |
| (proposed) `RELAY_URL` | account-deploy relay | `relay.aastar.io` / SuperRelay | 🟒 own relayer |
| `BACKEND_API_URL` / `NEXT_PUBLIC_API_URL` | app backend (goes away in zero-backend) | `127.0.0.1:3000` | n/a (removed) |

> **Decentralization choice (user request):** every 🟒 row is "AAStar default **or** your own".
> The client already supports KMS/bundler URL overrides (`lib/api-key-store.ts`, on the
> migration branch); the config page extends this to RPC + RELAY. Blank = AAStar default;
> filled = self-hosted. Code supports self-config; AAStar defaults are a convenience, not a lock-in.

## 3. Chain / contracts (βš™οΈ mostly canonical, not secrets)

~148 `*_ADDRESS` / `*_FACTORY` / `CHAIN_ID` / `ENTRY_POINT_*` / `VALIDATOR_*` / `AIRACCOUNT_*` /
`PAYMASTER_*` vars. Most resolve from **`@aastar/sdk` canonical** (`getCanonicalAddresses(chainId)`);
`.env` only overrides. Includes: EntryPoint v0.6/0.7/0.8, AAStar account factory/impl/extension,
validator router, BLS aggregator, SuperPaymaster, PaymasterV4, registry, GToken, aPNTs. Per-chain
(Sepolia now; Optimism mainnet for the phase-2 release).

## 4. Runtime flags (βš™οΈ)

`NODE_ENV`, `PORT`, `NETWORK`, `CHAIN_ID`, `KMS_ENABLED`, `DB_TYPE` (json/postgres),
`DEFAULT_ENTRYPOINT_VERSION`.

## 5. Summary β€” what the zero-backend + relay design does to this list

- **πŸ”΄ secrets β†’ eliminated** from the app: KMS/bundler via the **user's API key**; account-deploy
+ recovery via the **AAStar relay service** (billed in aPNTs); JWT/encryption via a
passkey/KMS-rooted client session. No private key in the app/browser.
- **🟒 endpoints β†’ user-configurable**: RPC / KMS / bundler / relay β€” AAStar default or self-hosted
(the decentralization choice), surfaced in the config page.
- **🟑 dev keys β†’ must be stripped** before beta (security hygiene).
- **βš™οΈ chain/contracts β†’ canonical from the SDK**, per-network.

This is the config target the config-center page (`app/settings`) manages: **endpoints + the
user's own API key only β€” never private keys.**
58 changes: 58 additions & 0 deletions docs/REPLAY_AND_RECOVERY_VERIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Beta-pre verification: replay rejection + social recovery

> Two beta-pre negatives that are **live/integration** flows (need a funded account, KMS,
> and β€” for recovery β€” an on-chain timelock), so they can't be deterministic headless
> tests. This records the protection **mechanism** (grounded in code) + an **owner runbook**
> to verify on Sepolia, with status. Date: 2026-07-02.

## 1. Replay rejection (challenge / nonce) β€” beta-pre #3

**Mechanism (already in place, by design):**
- The prepared transfer handle is **single-use with a ~10-min TTL** β€” `transfer.service.ts`
("The prepared handle is single-use and ~10min TTL"). The KMS `/SignHash` ceremony
**consumes** the `ChallengeId`; reusing it is rejected.
- The UserOp **EntryPoint nonce** is monotonic on-chain; replaying a landed UserOp with a
used nonce reverts (AA25).
- The challenge itself is the **WYSIWYS commitment** over the exact payload, so it can't be
re-pointed at a different transfer.

So replay protection is enforced at the **KMS (challenge consumption) + EntryPoint (nonce)**
layers, not in app code β€” there is no app-level unit test that meaningfully covers it.

**Owner runbook (Sepolia, funded passkey account):**
1. Transfer page β†’ prepare + submit a small transfer; confirm it lands (tx on-chain).
2. Capture the `challengeId` from the prepare response (devtools/network).
3. Re-POST `/transfer/submit` with the **same** `challengeId` + credential β†’
**expect rejection** (challenge consumed / TTL). βœ… = replay blocked.
4. Also: after a successful transfer, retry the exact prepared op β†’ expect nonce/AA25 reject.

**Status:** mechanism βœ… (code-confirmed); end-to-end run ⬜ (owner, live).

## 2. Social recovery β€” beta-pre #1

**Flow (backend `guardian.controller.ts`):** `guardian/add` β†’ `recovery/initiate` β†’
`recovery/support` (guardian co-sign) β†’ **on-chain 2-day timelock** β†’ `recovery/execute`
(backend relayer sends `executeRecovery()`), plus `recovery/cancel` and
`recovery/:accountAddress` (status). P256 (passkey) guardian path:
`recovery/p256/prepare` + `recovery/p256/submit`.

**Existing runbook:** `docs/social-recovery-e2e-test.md` (3 MetaMask guardians, full steps
+ expected results). The **only slow part is the 2-day on-chain timelock** before `execute`.

**Recommended split for beta:**
- Verify NOW (fast, no timelock): add/remove guardian, `recovery/initiate`, guardian
`support`/co-sign, `recovery/cancel`, status endpoint, and **replay/unauthorized
rejections** (non-guardian can't support; can't execute before timelock; can't replay a
used recovery). These prove the flow + its guards without waiting.
- `recovery/execute` happy path requires the **2-day timelock** β€” schedule one full run
(initiate β†’ wait 2 days β†’ execute) before the OP-mainnet release (phase 2).

**Status:** design βœ… + runbook βœ…; fast-path e2e ⬜ (owner); full timelock run ⬜ (owner, phase 2).

## 3. Beta recommendation

Neither is deterministically testable headless. For beta:
- **Replay:** mechanism is sound (KMS single-use + nonce); do the owner runbook once on
Sepolia to confirm, then ship.
- **Recovery:** run the **fast-path + rejection** checks before beta; **gate the full
timelocked recovery as "experimental" in beta** and complete the 2-day run before mainnet.
Loading