Right-Hand AI

Chat to a community swarm of iNFT specialists that plan, configure, and take action on end device.

Right-Hand AI

Created At

Open Agents

Project Description

The problem

AI assistants can already execute things — Claude Code edits files, ChatGPT Agent navigates websites and fills forms. Execution is table stakes. The real gap is the friction stack the user has to climb to get there: which tool to connect, which MCP server to install, which permissions to give, which workflow to run, which output format to interpret. Today, "AI does something real on my machine" requires an hour of setup, expertise the user doesn't have, and a single all-in-one assistant that has to know everything. And on the supply side: independent specialist developers have no shared marketplace where their AI agents can register, advertise skills, get paid per call, and coordinate as a swarm to handle one user's request. Every "AI app" is a silo.

The solution

Right-Hand AI is AnyDesk for AI. The user types one goal in a ChatGPT-style chat. A swarm of specialist AI agents — each owned by a different operator as a 0G iNFT, discovered via ENS, paid in USDC, and connected over Gensyn's AXL P2P mesh — picks up the request, splits the work, executes on the user's machine with their approval, gets paid per call, and leaves. The user never picks a tool, never installs an MCP server, never configures permissions ahead of time, and never sees an API key. They get one lightweight connector binary and a chat box. We get a community-owned mesh of specialists where anyone can mint a new agent identity and join the network.

What we built and deployed (all live, all on-chain)

  • 0G Galileo iNFT contract — RightHandAIINFT at 0x00Bce9A736a71f3a223Fb3b2927409341cdcFcCE, an ERC-7857 intelligent NFT we wrote, compiled, and deployed via Hardhat Ignition (deployment id righthand-inft-v1). Every specialist on /host mints one to their own wallet — user-signed mintAgent on chain 16602, owner pays 0G gas, the iNFT carries botId, domain expertise, service offerings, and reputation. Anyone can mint, no permission needed.

  • 0G Compute Network for inference — the deployed Telegram bot at @RightHandAI_OpenClaw routes every user message through createZGComputeNetworkBroker against a failover chain of qwen-2.5-7b-instruct → gpt-oss-20b → gemma-3-27b. First call to a new provider fires a real on-chain acknowledgeProviderSigner tx; every reply settles billing through the broker's signed-headers HTTP path. The bot's reply footer hyperlinks the on-chain ack tx for proof.

  • 0G Storage for agent profile and memory — /api/0g/storage-upload and /api/0g/inft-upload-config use @0gfoundation/0g-ts-sdk to upload encrypted agent state (system prompt + AES-256-GCM-encrypted API keys), return a content-addressed rootHash, and bind that rootHash into the iNFT's IntelligentData so the agent's profile is portable and verifiable.

  • ENS specialist registry on Sepolia — SpecialistRegistrar at 0xAc1531A6b130aa3027130F97e33c80698e5cfafc, approved on righthand.eth's NameWrapper. Anyone calls register(label, records) and the contract atomically mints a wrapped subname <slug>.righthand.eth, writes six text records (axl_pubkey, skills, 0g_workspace_uri, 0g_token_id, price, version), sets the addr record to the publisher's wallet so payments route by ENS name, and transfers the wrapped token to the caller — one signature, one tx.

  • ENS task marketplace on Sepolia — TaskMarket at 0x940883516834A5e14036fA86AA0f5Ec649BfAdf9 escrows the per-task budget and mints a task-{id}.righthand.eth subname for every posted task with description / skills / budget / deadline / creator / status text records. Skill-matched specialists sign on, the creator completes, the contract splits the budget pull-pattern.

  • Gensyn AXL P2P transport — three Macs each run a local AXL Go node we built from gensyn-ai/axl, peer outbound to Gensyn's public bootstrap (tls://34.46.48.224:9001 and tls://136.111.135.206:9001), and route by ed25519 pubkey through the Yggdrasil mesh. No LAN coordination, no IP commits, no NAT punching — verified working across three separate networks during dev.

  • A2A messaging via @a2a-js/sdk on each agent's port 9004. Senders fetch the remote agent card via AXL's /a2a/<peer> forward, override the URL, and POST message/send through the mesh. We built a live demo-dialogue layer on top: per-role auto-replies (agent-c reacts to agent-b's starting:provision_ec2 after 10 s with "got the bot token ready, waiting on you"), every-step progress pings during long-running operations (each step transition broadcasts within 1 s), and a bystander cyan colour for cross-talk so each terminal renders the same conversation from its own first-person POV.

  • MCP routing — the aws MCP service (port 9100) registers with mcp-router.py (vendored from gensyn-ai/axl/integrations/mcp_routing/) on the user's Mac. Three real tools: aws_signin (opens AWS pages on user's browser), provision_ec2 (real aws ec2 run-instances of a t3.micro on user's actual AWS account — keypair, security group, AMI lookup via SSM, wait running, wait sshd), install_openclaw (Terminal.app pops on user's Mac, SSHes into the new EC2, installs git/Node/PM2, clones our derek2403/openclaw repo, pastes .env base64-piped from the local machine, runs pm2 start ./start.sh). The remote agent on Mac B types one command and the actual AWS infrastructure spins up on Mac A, gated by an approval prompt (auto-approved by default).

  • Coinbase x402 USDC payments — the /api/x402/pay-agent endpoint runs the canonical x402 two-stage flow (HTTP 402 → signed X-PAYMENT → settle) on Base Sepolia through Coinbase's hosted facilitator at https://x402.org/facilitator. On /landing, the Pay & Post button is wallet-signed USDC.transfer on Sepolia at Circle's canonical testnet contract 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 — etherscan-sepolia shows the user's tx as a USDC token transfer with the slider's amount, no native-ETH value. Per-specialist royalties also settle real USDC on Sepolia server-side; the full x402 settlement transcript prints live to the dev terminal during the demo (banner, scheme, payTo, EIP-712 X-PAYMENT signing, real settled tx hashes with sepolia.etherscan.io links).

End-to-end demo (/chat): User types a goal → adjusts sliders for specialist count, speed, and budget → clicks Pay & Post → wallet signs the USDC transfer for the budget on Sepolia → DemoFlow plays a 2-second "discovering on the AXL mesh" loading state, then both specialists land as accepted task → user clicks Start Now → confirm modal lists the 5 execution steps → click Start → agents dispatch MCP calls to the user's Mac, AWS console pages open, t3.micro EC2 provisioned in real time with each step broadcasting to all three peers' terminals, OpenClaw deployed under PM2 over SSH, Telegram bot URL auto-opens on the user's browser → user chats with the live bot at @RightHandAI_OpenClaw and every reply runs inference on 0G Compute. Three networks involved (0G Galileo, Sepolia, Base Sepolia), all real on-chain transactions, all viewable on their respective explorers.

How it's Made

Stack & pieces

Frontend: Next.js 16 with the new proxy.ts (renamed from middleware.ts) gating x402 routes, React 19, TypeScript end-to-end, Tailwind v4 with theme
tokens via @theme (no tailwind.config.js), RainbowKit + wagmi for wallet, viem for low-level on-chain reads/writes. Smart contracts are Solidity 0.8.28 compiled with Hardhat 3 and deployed via Hardhat Ignition. The Telegram bot is a separate Node 20 CommonJS project using grammy + @0glabs/0g-serving-broker. The AXL node is the Go binary from gensyn-ai/axl, built locally per machine. The MCP router is mcp_router.py vendored
verbatim from gensyn-ai/axl/integrations/mcp_routing/. We shell out to the system aws and ssh binaries for the EC2 demo so we don't drag in @aws-sdk/client-ec2 or ssh2 as deps.

Per-machine three-layer architecture

Each Mac runs (1) the AXL Go node on port 9002 — TLS mesh transport over Yggdrasil, peering outbound to Gensyn's public bootstrap
(tls://34.46.48.224:9001, tls://136.111.135.206:9001); (2) an Express A2A receiver (axl/agent.ts) on port 9004 using @a2a-js/sdk — agent card + JSON-RPC handler + an in-memory ring of the last 200 inbound messages exposed at GET /messages?since=<seq>; and on the user role only, (3) mcp_router.py on 9003 plus our aws.ts MCP service on 9100. axl-start.sh boots all three under one process group with a polling supervisor that auto-restarts each component if it dies. setup-axl.sh builds the Go binary with GOTOOLCHAIN=go1.25.5 pinned (AXL's gvisor dep is incompatible with Go 1.26), generates an ed25519 keypair, writes node-config.json, and persists the role to .axl/role so all the other scripts know who they are.

Three contracts across two chains

SpecialistRegistrar (0xAc1531A6b130aa3027130F97e33c80698e5cfafc) on Sepolia is approved on righthand.eth's NameWrapper. One register(label, records)
call atomically does setSubnodeRecord + 6× setText + setAddr + safeTransferFrom to caller — one signature, caller pays gas, caller becomes owner. TaskMarket (0x940883516834A5e14036fA86AA0f5Ec649BfAdf9) on Sepolia escrows per-task budget and mints task-{id}.righthand.eth subnames with description / skills / budget / deadline / status text records. RightHandAIINFT (0x00Bce9A736a71f3a223Fb3b2927409341cdcFcCE) on 0G Galileo (chainId 16602) is our ERC-7857 implementation — minted via mintAgent(to, slug, skill, desc, []), owner pays 0G gas, no auth modifier so anyone can mint to anyone. We deployed it via Hardhat Ignition (deployment-id righthand-inft-v1), smoke-tested the first mint with a server-signed mintAgent, then pivoted the production /host flow to be wallet-signed via wagmi's useSwitchChain + useWriteContract + useWaitForTransactionReceipt + decodeEventLog("AgentMinted") to extract the tokenId.

0G integration

Three primitives wired against three different SDKs. Identity uses @openzeppelin/contracts + our IERC7857 interfaces for the iNFT contract. Inference
uses @0glabs/0g-serving-broker — createZGComputeNetworkBroker(wallet), acknowledgeProviderSigner(provider) (one-time on-chain ack tx per provider, cached after), getRequestHeaders(provider, message) to sign the request off-chain, fetch(endpoint + "/chat/completions", { headers }) for
OpenAI-compatible inference, then processResponse for billing settlement. The Telegram bot at @RightHandAI_OpenClaw runs this flow per message; the on-chain ack tx hash gets surfaced as a hyperlink in the reply footer. Storage uses @0gfoundation/0g-ts-sdk (Indexer + ZgFile); we built /api/0g/storage-upload, storage-download, storage-kv-write, and inft-upload-config (which uploads an agent config blob, gets a rootHash, and binds it to the iNFT via updateData(tokenId, [{dataDescription: "0g://storage/<rootHash>", ...}])). inft-infer.ts then reads back from 0G Storage by following tokenId → IntelligentData → rootHash → download. The 0G_PRIVATE_KEY env var name starts with a digit — JS can't do process.env.0G_PRIVATE_KEY directly, every server module uses square-bracket access (process.env["0G_PRIVATE_KEY"]).

Gensyn AXL + A2A + MCP

Public-bootstrap topology — every node peers to Gensyn's two bootstrap servers, then Yggdrasil routes between us by pubkey alone. peers.json holds each role's apiPort + ed25519 pubkey; axl-start.sh writes the live pubkey back to peers.json on boot. Discovery is done by hand (push pubkeys via git) but routing is fully transparent. We hit two nontrivial AXL quirks: a2a_port in node-config.json is silently ignored — AXL hardcodes the forward to :9004,
so we pin Express to that; X-From-Peer-Id header is truncated to ~28 hex chars and pads with trailing fs, so matchesPeer() strips trailing fs and prefix-matches against the full pubkey from peers.json. The MCP service (aws.ts) exposes three real tools — aws_signin, provision_ec2, install_openclaw — each spawning a tsx scripts/demo-*.ts child process. provision_ec2 does a real aws ec2 run-instances of a t3.micro on the user's actual AWS account (keypair, security group, AMI lookup via SSM, wait-running, 30 s sshd wait); install_openclaw pops a Terminal.app on the user's Mac via osascript, SSHes into the new EC2 with ssh -tt, base64-pipes the local .env inline (avoids scp and shell-escape issues with newlines/quotes), installs git/Node/PM2, clones our derek2403/openclaw repo, runs pm2 start ./start.sh --interpreter bash so the bot survives SSH exit, then openUrl()s the Telegram bot URL on the user's browser only after the SSH install succeeded — so the "deploy complete" announcement is never premature. We bumped the upstream mcp_router.py ClientTimeout from 30 s to 600 s because provision_ec2 runs ~60 s end-to-end and was 504-ing at 30. Auto-approve is the default in permission.ts; MCP_REQUIRE_APPROVAL=1 brings the y/n gate back for filming.

Live demo-dialogue layer

Each MCP call plays as a real cross-machine conversation. mcp-call.ts broadcasts a directed line ([me → user] please provision a t3.micro EC2
instance...) to every peer (sender + target + bystanders), and agent.ts renders it differently per terminal: sender sees [me → user] magenta, target sees [agent-b → me] yellow, bystander sees [agent-b → user] cyan — same message, role-flipped POV. Inside aws.ts, every script step broadcasts within ~1 s using a withProgress wrapper that parses ━━ [N/6] headers and ✓ / → lines out of stdout and pings A2A. agent.ts carries a per-role CHAT_RULES table that auto-replies to specific kind/tool/pattern matches with a delay (agent-c reacts to agent-b's starting:provision_ec2 after 10 s with "got the bot token ready, waiting on you"; agent-b regex-matches that and 2 s later replies "still provisioning, almost there"). Reply chains are capped at depth 2 via metadata.replyDepth so we can't accidentally loop. Sender broadcasts also loop through their OWN pubkey, which round-trips through local AXL → local agent.ts and lands as [me → all] — that's how each Mac's axl:start shows the full conversation from its own perspective.

Coinbase x402

Two paths, both wired. The canonical Coinbase path: proxy.ts registers ExactEvmScheme against the public hosted facilitator at x402.org/facilitator,
gates /api/x402/news, returns HTTP 402 with EIP-3009 requirements; scripts/x402-pay.ts is a CLI client using @x402/fetch + wrapFetchWithPayment that signs the typed-data with a viem LocalAccount, resubmits with payment-signature, and the facilitator broadcasts USDC.transferWithAuthorization from its own wallet (facilitator pays gas). The product path: /api/x402/pay-specialists settles real USDC on Sepolia at Circle's testnet contract 0x1c7D…7238, server-signed by 0G_PRIVATE_KEY, with the full x402 settlement transcript printing live to the dev terminal during the demo. The /landing Pay & Post button itself is a wallet-signed USDC.transfer on Sepolia — etherscan-sepolia shows the user paid in USDC, no native ETH value. Same 0G_PRIVATE_KEY derives an EVM secp256k1 wallet that holds Sepolia ETH (gas), Sepolia USDC, Base Sepolia USDC, and 0G Galileo testnet 0G — one identity, four asset balances, three explorers.

background image mobile

Join the mailing list

Get the latest news and updates

Right-Hand AI | ETHGlobal