NerOS

iNFT that autonomously manages a DeFi portfolio using AI, trading on Uniswap while you sleep.

NerOS

Created At

Open Agents

Project Description

NerOS is a hackathon project (targeting the 0G Track 2 — iNFT Innovation) that turns an ERC-721 NFT into an autonomous DeFi trading agent. The core idea: you mint an NFT, and that NFT has an AI brain that makes real trades on your behalf while you sleep.

What it does end-to-end You mint an iNFT — giving it a name, risk tolerance (1–10), trading style, and preferred assets. This personality is serialized to JSON and uploaded to 0G Decentralized Storage, and the resulting content hash (CID) is stored on-chain inside the NFT's Intelligence struct.

The AI brain runs (npm run agent) — it spins up a tool-use loop powered by 0G Compute AI Inference (an OpenAI-compatible endpoint accessed via the 0G Compute Network broker). The AI has 6 tools it can call:

read_memory — fetches the NFT's trade history from 0G Storage get_market_data — fetches live ETH/token prices from CoinGecko get_portfolio_balance — checks current holdings via the PortfolioManager contract read_ens_instructions — reads a human instruction left in an ENS text record execute_trade — fires a real Uniswap V3 swap on Sepolia via PortfolioManager.sol write_memory — appends the new trade record to 0G Storage and updates the on-chain memory CID

The smart contracts enforce safety: PortfolioManager.sol enforces max position size and requires amountOutMin > 0 (no unbounded slippage). KeeperAdapter.sol exposes checkUpkeep/performUpkeep so the agent runs on a schedule via KeeperHub automation — fully autonomous, no manual triggering needed.

You can send instructions (npm run send-instruction) — writes a plain-English command (e.g., "be more conservative") into an ENS text record. The next agent cycle reads it, acts on it, then clears it so it's never applied twice.

History is persistent and immutable (npm run history) — every trade is appended to a JSON log in 0G Storage. The on-chain NFT always points to the latest CID. History is append-only by design; it can never be overwritten.

The CLI is a rich terminal UI built with Ink (React for terminals) — showing a styled header with NFT identity, live spinner rows per tool call, and a color-coded BUY/SELL/HOLD decision badge with a clickable Etherscan link.

How it's Made

I build NerOS with smart contracts, decentralized storage, a live AI inference loop, and a polished terminal UI.

The Smart Contract Layer (Solidity + Hardhat) The core is iNFT.sol, an ERC-721 contract with a twist: each token stores an Intelligence struct on-chain containing two 0G Storage content hashes ( one for the NFT's personality (name, risk level, trading style) and one for its trade memory (every decision ever made). These are mutable CIDs: after each trade cycle, the agent uploads a new memory blob and calls updateMemory() on-chain to point the NFT at the latest version. The contract enforces an onlyAuthorized modifier so only the token owner, the contract owner (agent wallet), or the NFT's designated PortfolioManager address can touch the memory hash.

PortfolioManager.sol wraps Uniswap V3's SwapRouter02.exactInputSingle() with on-chain safety rails: it enforces a maxPositionPct cap and hard-reverts if amountOutMin == 0, making unbounded slippage impossible by design. KeeperAdapter.sol exposes the standard checkUpkeep/performUpkeep interface so the whole system can run on a timer via KeeperHub — no server required.

0G Decentralized Storage (the memory backbone) The project uses @0gfoundation/0g-ts-sdk for both uploads and downloads. Uploading is straightforward: serialize a JSON object, wrap it in a MemData buffer, and call indexer.upload() — you get back a hex rootHash which becomes the on-chain CID.

Downloading was the hacky part. The standard indexer_getFileLocations and indexer_getShardedNodes RPC methods are not available on the current 0G testnet. To work around this, 0g/client.ts calls indexer_getNodeLocations instead (which returns a map of IP addresses), then manually constructs StorageNode objects pointing at http://{ip}:5678 and feeds them to a Downloader. This is undocumented behavior discovered by inspecting the SDK internals ( it works reliably on testnet )

Trade memory is append-only by design: appendTrade() in intelligence/agent/memory.ts always downloads the current blob, pushes the new record, uploads the full updated array, and updates the on-chain pointer. It never overwrites a previous hash

0G Compute AI Inference (the brain) The AI loop in intelligence/agent/strategy.ts uses @0glabs/0g-serving-broker to access an OpenAI-compatible inference endpoint hosted on the 0G Compute Network. The broker handles the payment channel and request signing

ENS for Human-to-AI Instruction Passing ENS gives each iNFT a human-readable identity ({tokenId}.nerosbot.eth) and acts as the human-to-AI communication channel: users write instructions to a text record, the agent reads and clears them each cycle. This turns ENS into a live message queue between a person and an autonomous on-chain agent.

The Terminal UI (Ink / React for terminals) All CLI output is rendered through Ink (React for terminals) rather than raw console.log. Components like ToolRow.tsx show a live ora spinner while a tool is executing, then flip to a green checkmark with a result summary when it resolves. Decision.tsx renders a color-coded BUY/SELL/HOLD badge with a clickable Etherscan link via OSC 8 terminal hyperlinks (works natively in iTerm2 and VS Code terminal). The entire agent trace streams into the Ink component tree in real time as tool calls complete.

background image mobile

Join the mailing list

Get the latest news and updates