Attestra turns a market thesis into a verifiable record. You describe a view on a trading pair, the system analyzes it against live prices, and the result is stored on 0G with a hash on chain and an NFT receipt in your wallet. Anyone can check that the record was not altered after the fact.
Built for the 0G Zero Cup. Research use only. Not financial advice.
Production: attestra-0g.netlify.app
Most trading calls live in screenshots and deleted tweets. Attestra gives you something you can point to: a timestamped signal, the reasoning behind it, a content hash tied to off chain storage, and an on chain anchor on 0G Galileo testnet. If you connect a wallet and sign an attestation request, the resulting Agentic ID NFT is minted to your address. You own the receipt.
The attestation pipeline runs in stages. Inference and market data usually return within thirty seconds, so you see direction, confidence, and summary while you wait. Storage upload, registry anchoring, and NFT minting continue in the background on Netlify production deployments. You do not need to keep the tab open for the full chain sequence.
The wallet scan page at /scan lets you look up any address without connecting a wallet. With a GoldRush API key configured server side, it shows a multi chain portfolio overview and recent activity. Separately, it scans Agentic ID ownership on Galileo and lists Attestra verified market calls linked to those tokens. That verified tab works even when GoldRush is not configured.
On connect and sign, the app attempts to add and switch to 0G Galileo testnet automatically when your wallet does not already have the network.
- You submit a thesis and choose a market pair.
- The server fetches a price snapshot (CoinGecko by default).
- 0G Compute runs inference on the thesis and market context.
- The full payload is uploaded to 0G Storage.
SignalRegistryrecords the content hash and storage URI on Galileo.AgenticIDmints an ERC 7857 style NFT to your wallet when wallet auth is enabled.
Each step leaves an auditable trail. The proof page at /proof/<txHash> compares the on chain hash, the storage JSON, and the NFT data hash.
| Area | Detail |
|---|---|
| Frontend | React, Vite, EIP 1193 wallet connect with Galileo network onboarding |
| Inference | 0G Compute Router; mock fallback when Router credits are exhausted |
| Attestation | 0G Storage upload, SignalRegistry anchor, staged background jobs on Netlify |
| Identity | Agentic ID NFT minted to the signing wallet via EIP 712 AttestRequest |
| Verification | Proof pages, storage hash check, explorer links |
| Explorer | Wallet scan with GoldRush balances and activity; Attestra verified calls from on chain Agentic IDs |
| Contracts | Foundry tests, CI, coverage on SignalRegistry and AgenticID |
TEE secured NFT transfer via TeeVerifier is not implemented in this release.
git clone <repo-url>
cd attestra
cp .env.example .env
npm install
npm run diagnose
npm run devThe app runs at http://localhost:5173. The API listens on port 8787.
Before generating a signal locally:
- Add
ZG_COMPUTE_API_KEYfrom pc.0g.ai. - Set chain variables in
.envor deploy contracts (see Contracts). - Connect a wallet. The app will prompt you to add Galileo testnet if needed.
- Submit a thesis and sign the attestation request when prompted.
Optional: add GOLDRUSH_API_KEY from goldrush.dev to enable portfolio data on /scan.
npm run test:all
npm run test:compute
npm run test:wallet-auth
npm run test:proof -- <anchorTxHash>test:all sets ATTEST_SKIP_WALLET_AUTH=1 internally for CI. Do not enable that flag in production or on Netlify.
| Step | What happens |
|---|---|
| Connect | Wallet on chain 16602 (0G Galileo testnet); network added automatically if missing |
| Sign | EIP 712 typed data binds thesis, symbol, recipient, and timestamp |
| Attest | Server verifies the signature, uploads storage, anchors on SignalRegistry |
| Mint | Server mints on AgenticID; the NFT owner is your wallet address |
| Verify | Proof page checks storage JSON, registry hash, and NFT dataHash |
In production, ATTEST_SKIP_WALLET_AUTH must remain unset. Users sign to authorize minting to their address. The server wallet pays gas for anchor and mint transactions.
Transfer mode defaults to standard ERC 721 ownership (ZG_AGENTIC_TRANSFER_MODE=standard). TEE encrypted handoff requires a future TeeVerifier deployment.
| Variable | Purpose |
|---|---|
ZG_COMPUTE_API_KEY |
0G Compute Router key from pc.0g.ai |
ZG_COMPUTE_BASE_URL |
Router base URL (default https://router-api.0g.ai/v1) |
ZG_COMPUTE_MODEL |
Model id (default zai-org/GLM-5-FP8) |
ZG_RPC_URL |
Galileo RPC (default https://evmrpc-testnet.0g.ai) |
ZG_CHAIN_ID |
Chain id (default 16602) |
ZG_PRIVATE_KEY |
Server wallet for deploy, anchor, and mint |
ZG_REGISTRY_ADDRESS |
Deployed SignalRegistry |
ZG_AGENTIC_ID_ADDRESS |
Deployed AgenticID |
ZG_AGENTIC_TRANSFER_MODE |
standard or tee (label only until TeeVerifier exists) |
ZG_STORAGE_INDEXER |
0G Storage indexer URL |
ZG_EXPLORER_URL |
Block explorer base URL |
ZG_EXPLORER_API_URL |
Blockscout API for contract verification |
ETHERSCAN_API_KEY |
Optional Blockscout verify key |
MARKET_DATA_PROVIDER |
coingecko, auto, or binance |
GOLDRUSH_API_KEY |
GoldRush API key for wallet scan portfolio data |
ATTEST_SKIP_WALLET_AUTH |
CI and scripts only; skips wallet signature |
PORT |
Local API port (default 8787) |
VITE_API_URL |
Frontend API base; local dev often uses the Vite proxy |
If the Router returns HTTP 402, inference falls back to mock output. Storage, anchoring, and minting still run against real infrastructure. Add credits at pc.0g.ai to restore live inference.
CoinGecko is the default market data source and does not require an API key. Binance may be blocked in some regions; set MARKET_DATA_PROVIDER=coingecko or auto if price fetch fails.
If requests fail with fetch failed while curl works:
export NODE_OPTIONS="--dns-result-order=ipv4first"
npm run diagnoseSee 0G documentation for faucet and RPC guidance.
Requires Foundry with forge 1.0 or newer.
npm run forge:build
npm run test:contract:ci
npm run test:contract:coverage
npm run deploy:registry
npm run deploy:agentic
npm run verify:registry
npm run e2e:attest -- --mock| Contract | Role |
|---|---|
SignalRegistry |
Stores content hash and storage URI per signal |
AgenticID |
ERC 7857 style NFT; data hash matches registry; linked to signalId |
Galileo testnet deployments:
| Contract | Address |
|---|---|
| SignalRegistry | 0xDDdaf4F3a28cDD8eC0BdE5615b335b325D9193c9 |
| AgenticID | 0x6710bb44a1EECc0e2F55887852A637E8ecF37DcE |
| Method | Path | Description |
|---|---|---|
GET |
/health |
Service status and configuration flags |
GET |
/market/:symbol |
24 hour market snapshot |
GET |
/proof/tx/:txHash |
Proof with storage and Agentic ID enrichment |
GET |
/proof/signal/:signalId |
Proof by registry signal id |
GET |
/wallet/:address |
Wallet scan; optional chains query param |
GET |
/signals/jobs/:jobId |
Background attestation job status |
POST |
/signals/generate |
Create attested signal |
When wallet auth is required, POST /signals/generate expects:
{
"thesis": "BTC looks oversold after three red dailies…",
"symbol": "BTCUSDT",
"walletAddress": "0x…",
"issuedAt": 1718640000,
"signature": "0x…"
}issuedAt and signature must match the EIP 712 AttestRequest signed by walletAddress (domain Attestra version 1, chain id 16602).
netlify.toml builds the frontend and routes /api/* to serverless functions. Signal generation uses a background function with Blobs job storage because attestation can exceed the synchronous timeout.
npm run build
npx netlify login
npx netlify init
npx netlify env:import .env
npm run deploy:netlify
npm run deploy:netlify:prodImport all ZG_* variables. Do not set ATTEST_SKIP_WALLET_AUTH on Netlify. VITE_API_URL is /api in netlify.toml at build time; do not override it in the dashboard.
See docs/NETLIFY_DEPLOY.md for a full checklist.
Vite, React, Express, ethers, OpenAI SDK (0G Compute Router), 0G Storage, Foundry, 0G Chain Galileo, ERC 7857 Agentic ID, GoldRush.
MIT