ORRANGE / Architecture

Security Model

Short and serious: the boundaries that make the copilot safe to use on real money.

What ORRANGE never handles

The dapp never receives or stores:

  • Viewing keys — they live in the connected privacy wallet.
  • Encrypted notes or decrypted notes.
  • Private keys — the browser never holds them (Privy signs server-side; Ready signs in-wallet).
  • Nullifiers and proofs.

Private balances come only from the wallet (wallet_strk20Balances / SDK discovery), never from a local cache.

What the AI receives

Hamster receives only the aggregate portfolio summary necessary for analysis: balances, USD values, allocations, and liquidity — plus the active policy. It never receives notes, viewing keys, or per-transaction metadata.

What the AI cannot do

  • Sign — only your wallet signs.
  • Choose arbitrary calldata — the only action is a STRK20 private transfer to an approved destination.
  • Weaken policy — user-selected, server-validated; model constraints are rejected.
  • Bypass destination controls — an explicit allowlist gates every recipient.

Threats and mitigations

ThreatMitigation
Stale stateExecution re-fetches current balances and aborts if they differ from analysis-time state (STATE_CHANGED).
Prompt injectionModel output is schema-validated, cannot add constraints or destinations, and is advisory-only. The policy engine never trusts the model.
Malicious destinationRecipient must be in the approved allowlist; the treasury identity itself is rejected as a self-transfer.
Stale priceVolatile assets require a fresh live AVNU price (< 60s) to authorize execution.
Client-modified balancesBalances are analysis input, but execution re-checks against the wallet and re-runs the policy; prices are resolved fresh on the server.
Expired proposalsA 120 s TTL invalidates analysis; execution refuses an expired proposal.
Arbitrary calldataNo generic invoke exists from the copilot — only the existing private-transfer path.

Signing boundary

  • Ready lane: the wallet signs after you approve in its UI; the app only requests authorized Wallet API operations.
  • Privy lane: /api/privy/sign requires an authenticated Privy JWT and signs only the pre-computed transaction hash — no blind or arbitrary transactions.
The full integration audit lives in docs/PRIVY_STRK20_AUDIT.md. If you find a way to weaken these boundaries, please report it responsibly via GitHub.