Skip to content

fozagtx/pilow

Repository files navigation

Pilow

Sealed autonomous trading agents on 0G. Every decision is signed inside an Intel TDX TEE, every action is attested on-chain, every operator is slashable.

Sealed agents dashboard on 0G Galileo

Built for the 0G APAC Hackathon 2026.

Problem

Autonomous trading agents have a trust problem on both sides of the market.

  • Strategy authors cannot share a profitable strategy without leaking it. The moment the code, prompts, or model weights are visible to a renter or hoster, the alpha is gone — there is no way to rent out an agent while keeping the strategy sealed.
  • Renters cannot trust an agent's actions. A hosted agent could silently swap the model, alter the prompt, or front-run the user, and on-chain logs alone don't prove which binary actually produced a given trade.
  • Protocols have no slashing primitive for misbehavior, because nothing binds an on-chain action to the exact attested binary that produced it.

Pilow fixes this by minting each strategy as a sealed iNFT, running it inside an Intel TDX enclave whose signing key is derived from the image measurement, and recording a hash of the TDX remote-attestation quote on-chain for every tick. Anyone can challenge an action whose quote does not verify against the attested binary, and post a slashable bond. Authors get rentable, sealed strategies; renters get verifiable execution; the protocol gets a working dispute primitive.

0G stack integration

0G primitive Used? Where in Pilow
0G Chain Four contracts deployed on Galileo (chain id 16602): StrategyINFT, AgentWalletFactory, RentalAndRevenue, DisputeResolver. solc 0.8.24, evmVersion: "cancun". See Deployed contracts.
0G Compute Sealed inference per tick via provider 0xa48f01287233509FD694a22Bf840225062E67836 running qwen/qwen-2.5-7b-instruct. Settlement via processResponse(providerAddress, chatID, usageData) after every call. Broker reports verified=true. Code: agent/src/inference.ts.
0G Storage Strategy artifacts uploaded on mint; returned storage root hash is written on-chain in StrategyINFT.mintStrategy. Download path re-verifies the merkle root before the agent parses the artifact. Code: agent/src/storage.ts. Proof tx: 0xe14554…d51d0.
Agent ID (iNFT) Every strategy is an intelligent NFT (StrategyINFT, ERC-721). Each tokenId is the agent identity and binds 1:1 to a per-strategy AgentWallet deployed by AgentWalletFactory, and to a TEE-derived signer authorized on DisputeResolver.
Privacy / Secure Execution Agent runs inside an Intel TDX CVM on Phala Cloud. Signing key is derived from the image measurement via @phala/dstack-sdk — the key never exists outside the enclave. Each tick produces a TDX RA quote whose keccak256 hash is recorded on-chain via DisputeResolver.recordAction. Code: agent/src/tee.ts.
Other Slashable challenge market: DisputeResolver accepts a bond (min 0.01 OG) for anyone to challenge a recorded action whose quote hash does not verify against the attested binary.

0G on-chain integration proof

Every claim above maps to a transaction or address on Galileo — see the Live end-to-end proof on chain section below for clickable tx hashes covering strategy mint (Storage + Chain), agent wallet deployment, compute ledger funding, sealed inference run, attested tick recorded on DisputeResolver, and TEE agent authorization.

Architecture

flowchart LR
  User[User wallet] -->|mint / rent| FE[Next.js frontend]
  FE -->|wagmi v2| Chain[0G Galileo Testnet]
  Chain --> SINFT[StrategyINFT]
  Chain --> AWF[AgentWalletFactory]
  Chain --> RR[RentalAndRevenue]
  Chain --> DR[DisputeResolver]
  TEE[Agent in Phala CVM<br/>Intel TDX + dstack] -->|recordAction quote hash| DR
  TEE -->|inference| Compute[0G Compute provider<br/>qwen-2.5-7b]
  Compute -->|processResponse settlement| Chain
Loading

Sealed tick flow

sequenceDiagram
  participant Agent as Agent (CVM)
  participant DStack as dstack SDK
  participant Compute as 0G Compute
  participant DR as DisputeResolver
  Agent->>DStack: derive signing key from image measurement
  Agent->>Compute: inference request
  Compute-->>Agent: response + chatID
  Agent->>Compute: processResponse(provider, chatID, usage)
  Agent->>DStack: get TDX RA quote (report_data binds action)
  DStack-->>Agent: quote bytes
  Agent->>DR: recordAction(keccak256(quote))
  Note over DR: anyone can challenge later — only CVM-attested actions are trusted
Loading

Network

Network name 0G-Galileo-Testnet
Chain ID 16602
RPC URL https://evmrpc-testnet.0g.ai
Block explorer https://chainscan-galileo.0g.ai
Native currency OG (18 decimals)
Faucets https://faucet.0g.ai · https://cloud.google.com/application/web3/faucet/0g/galileo

Live end-to-end proof on chain

The pipeline below is not a sketch — every line points at a transaction you can click and verify on Galileo.

What Tx / address Result
Strategy #1 minted (real 0G Storage upload) 0xe14554…d51d0 tokenId=1, storageRoot 0x229b3f9e…0e18e79
Per-strategy AgentWallet deployed 0x731eb3…19413 wallet 0xf93B757dbD2C1dc300C948aFAA54fc0cAB667f9c
First real attested tick — qwen-2.5-7b returned sell, agent hashed attestation, wrote it on chain 0x85f1851f…4c49d block 33329274, ActionRecorded event emitted
0G Compute ledger created (3 OG) 0x15b16fde…6883c inference paid from this ledger
Sealed inference run, broker confirmed verified=true 0xf80f6293…becd530 model returned SHORT ETH 0.5X | LONG SOL 1.5X
Phala TEE-derived agent authorized on DisputeResolver 0xb559b8ad…f065a0 CVM agent 0xA2c6ACb4…f986 can now recordAction

Deployed contracts

Network: 0G Galileo Testnet (chain id 16602). Pilow is not deployed to a 0G mainnet — at the time of the hackathon submission, 0G is in testnet phase, so all live contracts and proofs below are on Galileo testnet. The same deployment script (npm -w contracts run deploy:testnet) is the path that will be used for mainnet once 0G mainnet is available; only the RPC URL and chain id in contracts/hardhat.config.ts need to change.

Deployer: 0x74CeCe8C927587620FF5171cEd3FA852185252A2

Contract Address Explorer
StrategyINFT 0x8D1AB23bEee17e58FB437cDcC35c75B89276fc26 open
AgentWalletFactory 0x4eD99BAf8efB12215b65514D235C8dA637F062a6 open
RentalAndRevenue 0x01A906558623edfF2ac416256eb832F74f09fd81 open
DisputeResolver 0x9f73cB87A43deAe721cbf69cfb8a356e2C7275FA open

Deployment manifest: contracts/deployments/0g-testnet.json

Constructor arguments

StrategyINFT(initialOwner = deployer)
AgentWalletFactory(strategyContract = StrategyINFT)
RentalAndRevenue(
  strategies      = StrategyINFT,
  feeRecipient    = deployer,
  protocolFeeBps  = 1000,           // 10% protocol fee
  initialOwner    = deployer
)
DisputeResolver(
  minBond         = 0.01 ether,     // 0.01 OG minimum dispute bond
  initialOwner    = deployer,
  initialAgent    = deployer        // bootstrap; rotate to TEE agent address
)

0G Compute provider (Galileo)

Provider address 0xa48f01287233509FD694a22Bf840225062E67836
Service type chatbot
Model qwen/qwen-2.5-7b-instruct
Minimum ledger balance 3 OG
Settlement processResponse(providerAddress, chatID, usageData) after each inference

The /app/providers page surfaces this provider after filtering listService() tuples down to teeVerified=true:

TEE-verified qwen chatbot provider on /app/providers

Solc / EVM config

Frontend

Next.js 16, App Router, Tailwind v4. Wallet via ConnectKit + wagmi v2 on chain 16602.

  • Local: npm run frontend:devhttp://localhost:3000
  • Wallet-gated: /app, /app/agents/new, /app/account
  • Open: /app/providers, /app/market

Contract wiring:

Surface Reads Writes
Dashboard balanceOf, tokenOfOwnerByIndex, strategies
Mint mintStrategycreateWallet
Market rent (native value)
Agent detail setActive, challenge

Setup and run

Prerequisites

  • Node.js >= 22
  • Docker (only required to deploy the agent to a Phala CVM)
  • A funded 0G Galileo testnet key — fund at https://faucet.0g.ai
  • Phala Cloud account + phala CLI (only required for the TEE deployment step)

1. Install

git clone https://github.com/fozagtx/pilow.git && cd pilow
npm install            # installs workspaces: contracts, agent, frontend
cp .env.example .env   # fill in PRIVATE_KEY=0x... and any RPC overrides

2. Compile and deploy contracts to 0G Galileo

npm -w contracts run compile
npm -w contracts run deploy:testnet
# writes addresses to contracts/deployments/0g-testnet.json

3. Wire up 0G Compute

npm -w agent run list-providers          # discover live providers
# edit .env: set PROVIDER_ADDRESS=0x... (use the listed qwen-2.5-7b provider)
npm -w agent run setup-ledger 3          # create compute ledger w/ 3 OG
npm -w agent run smoke-inference         # end-to-end sealed inference (no TEE yet)

4. Run the frontend

npm run frontend:dev                     # http://localhost:3000

Wallet-gated routes: /app, /app/agents/new, /app/account. Open routes: /app/providers, /app/market.

5. Deploy the agent to a Phala TDX CVM

npm i -g phala
phala login
phala deploy -c docker-compose.yml -n pilow-agent --wait

# Grab the TEE-derived agent address from CVM logs
phala logs pilow-agent | grep "Address  :"

# Authorize that TEE address on DisputeResolver (from deployer wallet, idempotent)
AGENT=0xTEE_ADDR npm -w contracts run authorize-agent

6. End-to-end smoke test

node scripts/smoke-test.mjs

See LOCAL_TESTING.md for the full test plan and BUILD.md for build-system notes.

Agent TEE runtime on Phala Cloud

The agent ships to a Phala Cloud CVM so the signing key is derived inside the enclave from the image measurement (no key in any env var), and each tick produces a TDX RA quote whose hash is recorded via DisputeResolver.recordAction(...).

Files:

File Role
agent/Dockerfile Image, node:22-slim base
agent/src/tee.ts @phala/dstack-sdk wrapper with local dev fallback
docker-compose.yml What the Phala CLI deploys
.dockerignore Excludes .env, caches, node_modules

Deploy:

# 0. Install Phala CLI (one-time, global)
npm i -g phala

# 1. Authenticate
phala login

# 2. Build + deploy the CVM
phala deploy -c docker-compose.yml -n pilow-agent --wait

# 3. Get the TEE-derived agent address from CVM logs
phala logs pilow-agent | grep "Address  :"
# prints: Address  : 0x... (different from your deployer wallet)

# 4. Authorize that TEE address on DisputeResolver (from deployer wallet, idempotent)
AGENT=0xTEE_ADDR npm -w contracts run authorize-agent

npm -w agent run report works in both modes — the local script falls back to the .env wallet when dstack is unavailable.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors