Simple dashboard for discovering a large list of agents via agent0-sdk with filters, stats, and a sortable search query.
npm install
npm run devOpen http://localhost:3000.
Optional:
PORT(default3000)CHAIN_ID(default11155111)RPC_URL(defaulthttps://ethereum-sepolia-rpc.publicnode.com)
Example:
CHAIN_ID=11155111 RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY npm run devThe app includes GET /api/agents (Next Route Handler), which calls:
sdk.searchAgents(filters, options)
Defaults:
chains=allsort=updatedAt:descmax=500
This repo now includes a Foundry-based onchain PoC for the x402-affiliate concept. API routes read/write directly to the deployed contract (no in-memory centralized store).
Routes:
GET/POST /api/programsGET/POST /api/offersGET/POST /api/linksGET/POST /api/x402/eventsGET/POST /api/payouts/run
Contract:
contracts/X402Affiliate.sol
Tests:
test/X402Affiliate.t.sol
Run tests:
forge testDeploy:
export PROTOCOL_WALLET=0x0000000000000000000000000000000000000000
export AFFILIATE_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
export AFFILIATE_PRIVATE_KEY=0x...
forge script script/DeployX402Affiliate.s.sol:DeployX402Affiliate \
--rpc-url $AFFILIATE_RPC_URL \
--private-key $AFFILIATE_PRIVATE_KEY \
--broadcastConfigure Next API to use deployed contract:
export AFFILIATE_CONTRACT_ADDRESS=0x...
export AFFILIATE_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
export AFFILIATE_PRIVATE_KEY=0x...
export AFFILIATE_CHAIN_ID=11155111
export ERC8004_IDENTITY_REGISTRY=0x8004A818BFB912233c491871b3d84c89A494BD9e
export ERC8004_REPUTATION_REGISTRY=0x8004B663056A597Dffe9eCcC1965A193B7388713Set environment:
export CONVEX_URL=https://<deployment>.convex.cloud
export INDEXER_SHARED_SECRET=<strong-random-secret>
export INDEXER_START_BLOCK=<contract-deploy-block>
export INDEXER_MAX_BLOCK_RANGE=2000Convex local/dev:
bun run convex:devSync chain events into Convex projections:
curl -sS -X POST "http://localhost:3000/api/indexer/sync" \
-H "x-indexer-key: $INDEXER_SHARED_SECRET"Optional block range:
curl -sS -X POST "http://localhost:3000/api/indexer/sync?fromBlock=123&toBlock=456" \
-H "x-indexer-key: $INDEXER_SHARED_SECRET"Read routes are Convex-first with chain fallback:
GET /api/programsGET /api/offersGET /api/linksGET /api/x402/eventsGET /api/payouts/run
If Convex is empty or lagging, read routes now auto-fallback to direct onchain reads so Marketplace does not appear blank.
Generate signer + indexer secret:
cast wallet new --json
cast wallet new --jsonUse first wallet for:
AFFILIATE_PRIVATE_KEYAFFILIATE_SIGNER_ADDRESS
Use second wallet private key for:
INDEXER_SHARED_SECRET
This repo has been configured with:
- Dev deployment URL:
https://beloved-goose-765.convex.cloud - Prod deployment URL:
https://giddy-tapir-982.convex.cloud
And INDEXER_SHARED_SECRET has been set on both dev and prod Convex deployments.
Useful commands:
# Deploy convex functions to prod
bun run convex:deploy
# Set secret on dev
bunx convex env set INDEXER_SHARED_SECRET "<secret>"
# Set secret on prod
bunx convex env set --prod INDEXER_SHARED_SECRET "<secret>"
# Verify
bunx convex env list
bunx convex env list --prodQuick test flow:
# Fast path smoke test (expects app already running):
bash scripts/smoke-sepolia.sh# Seed realistic marketplace cards + payment history
BASE_URL=http://localhost:3000 bash scripts/seed-real-programs.sh# 1) Create program (ids are numeric strings from chain state)
curl -sS -X POST http://localhost:3000/api/programs \
-H 'content-type: application/json' \
-d '{
"name":"Agent Data Feeds",
"handle":"agent-data-feeds",
"ownerWallet":"0x1111111111111111111111111111111111111111",
"ownerAgentChainId":11155111,
"ownerAgentId":"11155111:80041",
"defaultSplit":{"publisherPct":70,"affiliatePct":29,"protocolPct":1},
"status":"active"
}'# 2) Create offer (use numeric programId from step 1 response)
curl -sS -X POST http://localhost:3000/api/offers \
-H 'content-type: application/json' \
-d '{
"programId":"1",
"title":"Market Signals API",
"payoutModel":"revshare",
"pricePerUnitUsd":0.01,
"revSharePct":20,
"cookieWindowDays":30,
"tags":["finance","low-latency"]
}'# 3) Create affiliate link
curl -sS -X POST http://localhost:3000/api/links \
-H 'content-type: application/json' \
-d '{
"programId":"1",
"affiliateWallet":"0x2222222222222222222222222222222222222222",
"publisherWallet":"0x3333333333333333333333333333333333333333",
"affiliateAgentChainId":11155111,
"affiliateAgentId":"11155111:90001",
"publisherAgentChainId":11155111,
"publisherAgentId":"11155111:90002",
"destinationUrl":"https://example.com/api/market-signals"
}'# 4) Ingest paid x402 event (use link code from step 3)
curl -sS -X POST http://localhost:3000/api/x402/events \
-H 'content-type: application/json' \
-d '{
"programId":"1",
"chainId":1,
"grossAmountUsd":10,
"netAmountUsd":10,
"currency":"USD",
"linkCode":"<aff_code>",
"paymentRef":"x402:tx:0xabc123"
}'# 5) Calculate splits/payout rows
curl -sS -X POST http://localhost:3000/api/payouts/run \
-H 'content-type: application/json' \
-d '{"programId":"1"}'Use the included deploy script:
bash scripts/deploy.shIt outputs:
Preview URL(live deployment)Claim URL(attach deployment to your Vercel account)
Current production deployment:
https://8004engine-7zwaczfgm-tokenizin.vercel.app
Current alias:
https://8004engine.vercel.app
Indexer and read-layer enrichment now read ERC-8004 identity and reputation directly from Sepolia registries (no subgraph required for this overlay):
- IdentityRegistry:
0x8004A818BFB912233c491871b3d84c89A494BD9e - ReputationRegistry:
0x8004B663056A597Dffe9eCcC1965A193B7388713
Enriched fields are attached to program owner-agent and link affiliate/publisher-agent projections in Convex/API payloads.
Use /demo for a direct wallet-driven flow on Sepolia:
- Connect MetaMask/Rabby
- Register temporary ERC-8004 bot
- Create program/offer/link onchain
- Record payment and run payout
Set these public env vars for client-side writes:
NEXT_PUBLIC_AFFILIATE_CHAIN_IDNEXT_PUBLIC_AFFILIATE_RPC_URLNEXT_PUBLIC_AFFILIATE_CONTRACT_ADDRESSNEXT_PUBLIC_ERC8004_IDENTITY_REGISTRY
The PoC stores money amounts as USD6 integers and labels currency as "USDC" in payment events.
It does not yet execute ERC-20 transfers or escrow withdrawals in runPayout.
So USDC is currently accounting metadata + split math, not onchain token movement yet.