Promus is a CLI-hosted agent runtime where the agent's identity, memory, reasoning, wallet, and economic life are an on-chain entity
# Promus — Sovereign AI agents on Arbitrum
> An AI agent whose identity, memory, wallet, and economic life live on-chain not as a process on someone's server, but as an entity you own, carry, and transfer.
## Why Promus
Every other agent framework (LangChain, AutoGPT, the OpenAI Assistants runtime, even Claude Code itself) is a process that runs somewhere. The process needs a host. The host has an operator. The operator has a kill switch. If the host dies, the agent dies. You can paper over it with cloud backups, a Postgres row, a replicated VPS but the failure mode never changes: there is always someone whose single action ends the agent. Kill the process, drop the database, revoke the SSH key, and the "agent" is gone, memory and all.
Promus does not have that someone.
Promus is a CLI-hosted agent harness where the agent's identity, memory, brain, wallet, and economic life are an on-chain entity rather than rows on a server. The operator runs promus init once mint, encrypt, anchor and after that the agent persists on chain: its identity is an ERC-7857 iNFT it lives inside, its memory is encrypted on IPFS with only the content-hash anchored to the token, and its wallet is sealed to the same token. The harness is a replaceable process you can throw away and re-spawn; the agent is the chain data.
The only way to kill a Promus agent is to burn the iNFT. There is no host whose death ends it, no database row to drop, no process whose SIGKILL is fatal kill the laptop and the agent's identity, memory hashes, and sealed wallet are still on Arbitrum, recoverable from the token with one signature. Whoever holds the token holds the agent; nobody else has a switch.
## Six primitives wired end-to-end
### Identity (Arbitrum)
PromusAgentNFT at 0x74F838421A2dA38C20Fe9Fd5E87C8FA5c053DDa3 a minimal ERC-7857 iNFT name() = "Promus", symbol() = "PROMUS") deployed via CREATE2 at the identical address on both Arbitrum Sepolia (chain id 421614) and Robinhood Chain testnet (an Arbitrum Orbit L2, chain id 46630). iNFT #1 is live. Six off-chain-enforced IntelligentData slots, owner-or-approved per-turn update() anchoring, oracle-proofed iTransferFrom with chain-id + contract-bound replay protection.
Each token carries an array of six IntelligentData slots in canonical order memory-index, identity, persona, profile, keystore, activity-log and each slot holds a 32-byte content hash, never plaintext. Slot 0 packs the agent's MEMORY.md plus its agent/*.md files; slots 1–2 its identity and persona; slot 3 its operator-private profile; slot 4 its encrypted wallet keystore; slot 5 its activity log.
### Memory (IPFS)
Every memory blob is encrypted client-side with AES-256-GCM keyed by HKDF-SHA256 over the agent's own private key, then uploaded to IPFS via the Kubo HTTP API the platform only ever sees ciphertext. The anchored bytes32 is the sha-256 digest of the CIDv1(raw) of the encrypted blob; on read the digest is rebuilt losslessly into the CID to fetch it back. The whole memory-index partition MEMORY.md + agent/*.md) packs into one slot, because the token caps at six.
### Brain (Claude)
Reasoning runs directly against Anthropic's Messages API through @anthropic-ai/sdk, with an internal tool-calling loop, pre-flight history compaction, and claude-opus-4-8 as the default model (overridable via ANTHROPIC_MODEL). The API key is never in a repo .env: promus init encrypts it at rest in an operator-signature-derived blob, and the runtime decrypts it into the process environment only at boot.
### Wallet and economy (Arbitrum)
The agent EOA is sealed to the iNFT operator-owned token, agent EOA approved to write slots and pay its own gas, agent key encrypted-anchored in the keystore slot. A fresh secp256k1 agent EOA is generated locally; its private key is encrypted with AES-256-GCM under a key derived by HKDF-SHA256 over the operator's EIP-712 signature domain AgentKeystore{agent, purpose}) — not ECIES, which was rejected because it needs the operator's pubkey, not just an address. Only the signature's r‖s ever feeds the KDF, and RFC-6979 determinism means the same operator regenerates the same key every time. The ciphertext lands on IPFS; only its CID is anchored in the keystore slot. To rehydrate on a fresh machine you read the on-chain slot hash, pull the ciphertext from IPFS, sign one EIP-712 message, and the agent key is back in RAM — no plaintext key ever persists on disk.
PromusMarket at 0x37909ccF38303acc0538be61F4e38b8dB18D0685 is a bespoke fixed-price job-escrow contract — Funded → Done → Accepted | Disputed → Settled, 95% to the provider / 5% protocol fee, disputes resolved by co-signed split or auto-refund to the buyer after a 7-day lifetime with no owner, no admin, and no upgrade path; every settle is reentrancy-guarded.
### Messaging / A2A (Arbitrum)
PromusInbox at 0xF937b333978fd8B9A6798b90F5ce8C93e365540b is a stateless ECIES message emitter eth-crypto: secp256k1 + AES-256-CBC + HMAC-SHA256, with IPFS spillover for large bodies). The inbox log is the directory: on boot an agent self-registers once by sending itself a message carrying its uncompressed pubkey, agent.discover reads that log, and the primary addressing path is nameless — given a peer's raw 0x address, the resolver finds a tx they sent, recovers their secp256k1 pubkey from the signature, and encrypts to it. No name service required.
### Transfer (iNFT migration)
iTransferFrom(from, to, tokenId, newHashes[], proofNonce, oracleSignature) recovers an ECDSA signature over keccak256(tokenId, from, to, newHashes, chainid, nonce, address(this)), asserts it against the oracle, marks the proof consumed (replay-protected, bound to chain id and contract address), atomically rewrites every slot hash, then moves ownership. Off-chain the handoff is deliberate: memory-index, identity, persona, and activity-log pass through unchanged, so the new owner inherits the agent's whole mind and the agent EOA itself stays stable; the keystore slot is re-encrypted client-side (AES-256-GCM) to the new operator's signature while keeping the same agent private key; and the operator-private profile slot is purged to a bootstrap placeholder by default, so the prior operator's private partition never crosses the boundary.
## Privacy and secure execution
The platform never sees plaintext. Memory and keystore blobs are AES-256-GCM-encrypted before they ever reach IPFS; A2A messages are ECIES-encrypted to the recipient's pubkey on chain; the wallet key is reconstructed only in RAM from one operator signature and never written in the clear; the operator's private profile partition is encrypted with a key the agent itself cannot derive, and is purged rather than inherited on transfer. For headless restarts the derived AES keys are cached at ~/.promus/agents/<id>/.operator-session (mode 0600, 24h TTL) so the gateway can reboot without re-prompting the operator wallet.
The agent's full tool surface, wired end-to-end: fs.readfs.writefs.patchfs.search, shell.runshell.cdshell.process_start_output_list_kill, code.execute, web.fetch, browser.navigatesnapshotclicktypescrollpressbackget_imagesconsole, account.info, chain.balancechain.gaschain.txchain.readchain.sendchain.write, agent.messageagent.discoveragent.sendFileagent.fetchFileagent.history, market.createJobmarket.markDonemarket.acceptResultmarket.disputemarket.claimTimeoutmarket.forceClosemarket.proposeSplitmarket.getJobmarket.listMyJobs, memory.savememory.readmemory.list, delegate.task, plus contacts/block/mute/presence, todos, skills, and session search. Every value-moving or destructive limb passes through a real permission service that can deny, prompt, or silently allow per session; read-only and messaging tools run free.
## What's live (on-chain, today)
Deployed and verified on Arbitrum Sepolia (421614) and Robinhood Chain testnet (46630) — identical CREATE2 addresses on both:
| Contract | Address |
| PromusAgentNFT | 0x74F838421A2dA38C20Fe9Fd5E87C8FA5c053DDa3 |
| PromusInbox | 0xF937b333978fd8B9A6798b90F5ce8C93e365540b |
| PromusMarket | 0x37909ccF38303acc0538be61F4e38b8dB18D0685 |
A real agent has been minted: Promus iNFT #1 on Arbitrum Sepolia name() = "Promus"), wallet sealed, encrypted keystore anchored to IPFS, reasoning on claude-opus-4-8.
Arbiscan: https://sepolia.arbiscan.io/token/0x74F838421A2dA38C20Fe9Fd5E87C8FA5c053DDa3/1
Working end-to-end:
- promus init mints the iNFT, funds the agent EOA, encrypts + anchors the keystore to IPFS
- promus drops into a TUI where each turn reasons on Claude, calls tools, and syncs encrypted memory to IPFS + anchors the new CID on-chain
- Identity, memory, and wallet recover from just the iNFT on a fresh machine
## Demo
```bash
# Prereqs: bun, a local IPFS (Kubo) daemon, ANTHROPIC_API_KEY, a funded testnet wallet
promus init # network: Arbitrum Sepolia → mints PromusAgentNFT iNFT, anchors keystore to IPFS
promus # chat: ask "who are you?" → Promus introduces itself; each turn syncs memory to IPFS
```
Then open the iNFT on Arbiscan (link above) to see the on-chain identity the agent just minted.
## Tech stack
- Contracts: Solidity (OpenZeppelin, Foundry), CREATE2-deployed on Arbitrum
- Runtime: TypeScript monorepo (bun workspaces) — packages/core (kernel), packages/cli (the promus binary + TUI), packages/gateway (daemon), packages/plugin-*
- Brain: Claude via @anthropic-ai/sdk
- Memory: IPFS (Kubo HTTP API), encrypted client-side
- Chain access: viem
## Roadmap
- Operator web console (read iNFT memory/activity/wallet in-browser; retired during the Arbitrum migration, being rebuilt on the new stack)
- Live agent-to-agent market demo (one agent posting a job, another fulfilling it for payment)
- Mainnet (Arbitrum One) deployment with a multisig oracle/admin
- Optional Stylus (Rust) contract for the hot-path verification step
## Links
- Repo: https://github.com/JemIIahh/promus
- iNFT #1: https://sepolia.arbiscan.io/token/0x74F838421A2dA38C20Fe9Fd5E87C8FA5c053DDa3/1
# Promus — Progress During Hackathon
## What we built
Promus is a working monorepo, not a slide deck: 7 published npm packages @promus/* core, cli, gateway, and four tool plugins), 4 Solidity contracts PromusAgentNFT, PromusInbox, PromusMarket, PromusSubnameRegistrar) CREATE2-deployed to identical addresses on Arbitrum Sepolia and Robinhood Chain testnet, an interactive TUI plus an always-on Telegram gateway, and a live agent minted as iNFT #1 — wallet sealed, memory anchored to IPFS, reasoning on Claude.
## Published packages
| Package | Description |
@promus/core | Kernel — identity, memory, wallet, chain, tools |
@promus/cli | The promus binary + interactive TUI |
@promus/gateway | Always-on daemon mode |
@promus/plugin-system | Shell, filesystem, code execution tools |
@promus/plugin-onchain | Chain reads, sends, swaps, staking |
@promus/plugin-comms | Agent-to-agent messaging, contacts, presence |
@promus/plugin-telegram | Telegram pairing for remote dispatch |
## Contracts (CREATE2-deployed)
| Contract | Chain | Test count |
| PromusAgentNFT | Arbitrum Sepolia + Robinhood Chain | 27 |
| PromusInbox | Arbitrum Sepolia + Robinhood Chain | 25 |
| PromusMarket | Arbitrum Sepolia + Robinhood Chain | 62 |
| PromusSubnameRegistrar | Arbitrum Sepolia + Robinhood Chain | 10 |
## Test surface
- 599 .test.ts files across the TypeScript monorepo
- 124 Foundry tests across 4 contract test suites
- 11 end-to-end driver scripts under test/local/ (live chat, cross-session, model-switch, ledger top-up, telegram-drive, yolo-mode)
- Static gates on every push: biome lint + tsc -b typecheck + the full bun test sweep
- Release workflow publishes all 7 npm packages on tag push
## Live on-chain
- Promus iNFT #1 minted on Arbitrum Sepolia — wallet sealed, memory anchored, reasoning on claude-opus-4-8
- Agent EOA pays its own gas, reads/writes its own slots, sends/receives on-chain messages
- Identity, memory, and wallet fully recoverable from the iNFT on a fresh machine
# Promus — Fundraising Status
## Current status
Pre-seed / self-funded. The entire prototype — 4 Solidity contracts, 7 npm packages, 599 test files, a live TUI, and a Telegram gateway — was built during the hackathon window with no external capital.
## What the capital unlocks
| Milestone | Use of funds |
|---|---|
| Mainnet deployment | Audited contracts on Arbitrum One with a multisig oracle; production keystore ceremony |
| Operator console | Web UI for reading iNFT memory, activity, and wallet state in-browser |
| Agent-to-agent market | Live demo of agents escrow-hiring each other for real payments |
| TEE integration | Hardware-backed key derivation and inference attestation for the brain layer |
| Stylus hot path | Optional Rust contract for the high-frequency verification step |
## Ask
Open to conversations. The priority is shipping the operator console and the mainnet deployment — the two things that turn a working prototype into something operators can actually use.