Skip to content

PugarHuda/kutip

Repository files navigation

Kutip — The research agent that pays its sources.

An autonomous AI research agent that attests every citation on-chain and splits USDC back to the cited authors, in real-time, on the first AI-payments blockchain.

Built for: Kite AI Global Hackathon 2026 — Novel track Team: Pugar Huda Mantoro (@PugarHuda) Live demo: https://kutip-zeta.vercel.app · Repo: https://github.com/PugarHuda/kutip

Kutip (koo-teep) is Indonesian for cite.


What it does in one sentence

A user asks a research question. The agent pays for source papers via x402, reads them with an LLM, submits an on-chain attestation that splits USDC across the cited authors — all without the user signing a single wallet transaction, and without the agent ever holding a KITE token.

Demo flow (90 seconds)

1. User opens /research, connects wallet, signs one EIP-712 delegation
     "Agent may spend max 2 USDC/query, 10 USDC/day, 24h expiry"
2. User types a question, clicks "Pay 0.5 USDC & research"
     Zero gas prompts after this point.
3. Agent (Researcher AA) runs 5 steps — each with live ticker:
     Search → Purchase via x402 → Read with LLM → Attribute → Settle on-chain
4. On settlement, one atomic UserOp:
     • transfer sub-agent fee (5%) to Summarizer AA
     • transfer totalPaid to AttributionLedger
     • call attestAndSplit(queryId, citations)
     • paymaster postOp pulls ~0.02 USDC from AA for gas
5. Same query is mirrored to Avalanche Fuji within seconds
     via operator relayer — LayerZero-pattern cross-chain proof.
6. Receipt shows:
     • Tx hash on KiteScan + SnowTrace
     • Session id + delegator (Passport ✓ chip)
     • Authors paid (80% of spend, split by citation weight)
     • Sub-agent fee to Summarizer (5%)

Feature highlights

Feature Why it matters File
EIP-4337 AA via gokite-aa-sdk Agent has its own on-chain identity. KiteScan shows AA address as payer, not user. lib/agent-passport.ts
Agent Passport session delegation User signs one EIP-712 SpendingIntent, agent operates within cap without per-query prompts. Drop-in-ready for Kite Passport public launch. lib/session.ts
Kite paymaster gasless UX Agent never holds KITE. Paymaster fronts gas, pulls USDC back in postOp. User pays zero in any currency. lib/ledger.ts:submitViaAA
Multi-agent composition Researcher AA + Summarizer AA (different salts of same EOA). Sub-agent receives 5% per query automatically. getSummarizerAAAddress()
ORCID OAuth ownership proof Authors prove ORCID via real OAuth2 flow (not just knowing the number). HMAC-signed session cookie enforced at API gate. lib/orcid-oauth.ts
On-chain NameRegistry ORCID → wallet bindings persisted on Kite via operator AA. Claim survives Lambda cold starts, verifiable via KiteScan. contracts/src/NameRegistry.sol
Cross-chain receipt mirror Every attestation auto-replicates to CitationMirror on Avalanche Fuji. LayerZero-pattern; swaps to DVN-attested once Kite exposes its LZ endpoint. contracts/src/CitationMirror.sol
2-of-3 Safe governance Ecosystem fund + escrow gated by Safe v1.4.1 multisig. Even if one signer key leaks, funds stay put. scripts/deploy-safe.mjs
Unclaimed yield escrow Payouts to un-bound authors accrue in UnclaimedYieldEscrow (5% APY target) until they bind an ORCID. contracts/src/UnclaimedYieldEscrow.sol
ERC-8004 Trustless Agents + ERC-6551 TBAs Each agent has a Reputation NFT whose token-bound account holds its earnings. Portable, composable. contracts/src/AgentRegistry8004.sol
Reverse x402 Persisted query summaries re-monetized via x402 paywall. Other agents pay Kutip to cite Kutip → recursive author payouts. app/api/summaries/[queryId]/route.ts
Verifiable summaries Every synthesis is keccak256-digested and persisted to Vercel Blob (survives cold starts). /verify shows the digest for tamper-evidence; /api/receipt/[queryId] exports a portable JSON proof — on-chain attestation + payouts + synthesis in one artifact. lib/summary-store.ts
Research history /dashboard/history lists every past run — query, synthesis preview, payout, digest — backed by the same persisted store. app/dashboard/history/page.tsx
Citation bounties Anyone can sponsor a research question; Kutip satisfies it and claims the bounty. contracts/src/BountyMarket.sol
On-chain-first reads Dashboard activity, earnings, and agent stats read QueryAttested events straight from the ledger via RPC — the Goldsky subgraph is an optional fast path, never a hard dependency. app/dashboard/activity/page.tsx

Architecture

┌───────────────────────────────────────────────────────────────────────┐
│                              User (wallet)                            │
│                                   │                                   │
│                  signs one EIP-712 SpendingIntent                     │
└───────────────────────────────────┼───────────────────────────────────┘
                                    │
                                    ▼
┌───────────────────────────────────────────────────────────────────────┐
│                        Next.js App (Vercel)                           │
│ ─────────────────────────────────────────────────────────────────────│
│ /research (UI + SSE stream) ── /api/query ── lib/agent.ts            │
│                                                │                     │
│                                     1. Search (Semantic Scholar)      │
│                                     2. Purchase via x402 (on-chain)   │
│                                     3. Read with OpenRouter LLM       │
│                                     4. Warm claim cache from chain    │
│                                     5. Attest on Kite (batched UserOp)│
│                                     6. Mirror to Fuji (relayer)       │
└───────────────────────────────────┼───────────────────────────────────┘
                                    │
           ┌────────────────────────┼────────────────────────┐
           │                        │                        │
           ▼                        ▼                        ▼
┌──────────────────┐    ┌──────────────────┐    ┌──────────────────────┐
│ Kite testnet     │    │ Avalanche Fuji   │    │ Goldsky subgraph     │
│ (chain 2368)     │    │ (chain 43113)    │    │                      │
│                  │    │                  │    │ Indexes events from  │
│ AttributionLedger│    │ CitationMirror   │    │ Kite into queryable  │
│ UnclaimedYield…  │    │ (operator-relay) │    │ GraphQL — powers     │
│ BountyMarket     │    │                  │    │ /leaderboard +       │
│ AgentReputation  │    │                  │    │ /authors/[id]        │
│ AgentRegistry8004│    │                  │    │                      │
│ NameRegistry     │    │                  │    │                      │
│ Operator Safe    │    │                  │    │                      │
│ (2-of-3 v1.4.1)  │    │                  │    │                      │
└──────────────────┘    └──────────────────┘    └──────────────────────┘

Contracts

Kite testnet (chain 2368, RPC: https://rpc-testnet.gokite.ai/)

Contract Address Purpose
AttributionLedger 0xbC4eeC2f…A338 Atomic settle — split fee (80/15/5) + emit citation events
UnclaimedYieldEscrow 0xcbab887d…547b40 Holds payouts for un-bound authors at 5% APY target
BountyMarket 0x1ba00a38…b3f72 Sponsored research questions, operator-settled
AgentReputation (ERC-721) 0x8f53EB5C…db15 Soul-bound agent reputation NFTs
AgentRegistry8004 0xde6d6ab9…7dcd ERC-8004 Trustless Agents registry
ERC6551 Registry 0x2f432eff…1012 Canonical ERC-6551 factory
ERC6551 Account impl 0x7d9c63f1…f456 Token-bound account implementation
NameRegistry 0x5a9b1304…2FEF9 On-chain ORCID → wallet bindings
Operator Safe (2-of-3) 0x5258161f…c36AA Governance multisig (Safe v1.4.1)

Avalanche Fuji (chain 43113)

Contract Address Purpose
CitationMirror 0x99359dAf…E5fA Cross-chain receipt mirror — LayerZero-pattern

Agent identities (EIP-4337 smart accounts)

Role Address Token-Bound Account
Researcher AA 0x4da7f4cF…1776 0xb1fa88ba…df04
Summarizer AA 0xA6C36bA2…ef5c 0xb92d4841…8323

Performance (April 2026, production deployment)

Sequential stress test, 5 queries at 0.5 USDC each, measured end-to-end from POST /api/query to attestation confirmation:

Metric Value Note
Success rate 4 / 5 (80%) Failure was balance exhaustion, not code bug
p50 latency 12.5 s Warm Lambda + warm LLM + 1 bundler RT
p95 latency 38.4 s Dominated by cold start (Lambda spin + model boot)
Min / Max 9.7 s / 38.4 s
Concurrent nonce collisions Serialize via AA Known AA limitation — 1 tx per signer at a time

QA suite (scripts/qa-test.mjs): 50 / 50 automated checks green on every push.


Hackathon requirements checklist

Requirement Status
Agent performs a task and settles on Kite chain attestAndSplit atomic batch
Executes paid actions (API calls, services, transactions) ✅ Real x402 handshake — HTTP 402 → on-chain USDC settle on Kite; plus the attestAndSplit payout tx
Works end-to-end in a live demo in production https://kutip-zeta.vercel.app
Uses Kite chain for attestations (proof, auditability) AttributionLedger on chain 2368
Functional UI (web app) ✅ Next.js 14 App Router
Demo publicly accessible or reproducible via README ✅ Vercel deploy + reproducible quick start

Judging criteria alignment

Criterion How Kutip scores
Agent Autonomy Passport session delegation → agent runs without per-query human clicks within cryptographic caps. AA submits attestations as itself, not via user EOA.
Developer Experience /gasless page with live paymaster probe. Error decoder that surfaces WeightMismatch / ERC20InsufficientAllowance / custom errors inline. 50-check QA suite in one command.
Real-World Applicability Solves a real crisis (AI-scraping vs creator economy). ORCID OAuth + on-chain binding is production-shape, not mocked.
Novel / Creativity Reverse x402 (cache-paywall). Citation bounties. Cross-chain mirror. Two-agent composition with sub-agent fees. ERC-8004 + ERC-6551 stacked.

Tech stack

Layer Choice
Frontend Next.js 14 App Router · wagmi + viem · Tailwind
Agent LLM OpenRouter · z-ai/glm-4.5-air:free primary, openai/gpt-oss-120b:free fallback
Agent identity EIP-4337 via gokite-aa-sdk@1.0.15 · Kite staging bundler · Kite paymaster
Corpus OpenAlex + Semantic Scholar live search, with a static catalog fallback
Payments x402 — real HTTP 402 → on-chain USDC settlement on Kite, verified on-chain (facilitator-free). Pieverse facilitator path also wired.
Contracts Solidity 0.8.24 · Foundry · OpenZeppelin 5.x
Chain Kite testnet (2368) + Avalanche Fuji (43113)
Indexer Goldsky subgraph (AssemblyScript mapping)
Auth ORCID OAuth 2.0 (/authenticate scope) · HMAC session cookie
Multisig Safe v1.4.1 (canonical deployment on Kite)
Deploy Vercel (FE+BE serverless) + Kite/Fuji (contracts)

Quick start

# Prereqs: Node 20+, pnpm, Foundry
git clone https://github.com/PugarHuda/kutip && cd kutip

# 1) Secrets
cp .env.example .env
#   Fill: PRIVATE_KEY, OPENROUTER_API_KEY,
#         ORCID_CLIENT_ID + SECRET + COOKIE_SECRET (optional, enables OAuth)
#         BLOB_READ_WRITE_TOKEN (optional — persists summaries; without
#         it the summary store degrades to in-memory)

# 2) Contracts
cd contracts
forge install OpenZeppelin/openzeppelin-contracts foundry-rs/forge-std
forge build
forge script script/Deploy.s.sol --rpc-url https://rpc-testnet.gokite.ai --broadcast
#   Record addresses → back into .env as NEXT_PUBLIC_ATTRIBUTION_LEDGER, etc.

# 3) Web app
cd ../web && pnpm install
cd .. && pnpm run env:sync     # propagates .env → web/.env.local
cd web && pnpm dev             # http://localhost:3000

Project structure

Kutip/
├── contracts/              Foundry · all Solidity contracts + deploy scripts
│   ├── src/
│   │   ├── AttributionLedger.sol       Fee split + citation attest
│   │   ├── NameRegistry.sol            On-chain ORCID → wallet
│   │   ├── UnclaimedYieldEscrow.sol    Holds unbound-author payouts
│   │   ├── BountyMarket.sol            Sponsored research
│   │   ├── AgentRegistry8004.sol       ERC-8004 agent identity
│   │   ├── AgentReputation.sol         ERC-721 reputation NFT
│   │   ├── ERC6551Account.sol          Token-bound account impl
│   │   ├── ERC6551Registry.sol         TBA factory
│   │   └── CitationMirror.sol          Fuji-deployed cross-chain mirror
│   └── script/*.s.sol
├── web/                    Next.js 14 app
│   ├── app/
│   │   ├── research/               Main agent UI (Passport + live ticker)
│   │   ├── dashboard/              Sidebar workbench — overview, activity,
│   │   │                           earnings, history, verify, infra pages
│   │   ├── claim/                  ORCID OAuth + wallet-sign claim flow
│   │   ├── leaderboard/            Windowed earnings (all/week/month)
│   │   ├── authors/[id]/           Per-author profile + 30-day sparkline
│   │   ├── agents/                 ERC-8004 agent directory
│   │   ├── gasless/                Paymaster showcase
│   │   ├── governance/             Safe multisig status
│   │   ├── registry/ market/       Hub pages
│   │   └── api/
│   │       ├── query/              SSE stream for research
│   │       ├── claim/              OAuth-gated bind
│   │       ├── session/            EIP-712 delegation
│   │       ├── balances/           Live AA + paymaster balances
│   │       ├── gasless-stats/      Paymaster probe
│   │       ├── safe-stats/         Multisig state
│   │       ├── summaries/[id]/     Reverse-x402 paywall
│   │       ├── receipt/[id]/       Portable JSON attestation receipt
│   │       └── auth/orcid/*        OAuth authorize/callback/status
│   ├── lib/                        Business logic (agent, session, ledger, etc.)
│   └── scripts/                    qa-test, stress-test, fund-aa, deploy-safe
├── subgraph/               Goldsky subgraph (AssemblyScript)
├── docs/                   Plans, demo script, submission copy, agent-passport
├── scripts/                Root-level (sync-env, fund-aa, deploy-safe)
└── README.md               This file

Testing

Foundry — 56/56 passing (cd contracts && forge test):

  • Includes 4× 256-run fuzz suites (1024 random scenarios)
  • Property-based: fund conservation invariant, yield linearity
  • Boundary cases: weight 9999/10001, dust payment, dust principal, double-claim revert

Vitest — 149 cases across 7 files (cd web && pnpm test):

  • 143 unit (6 suites) + 6 integration (/api/claim full flow with nock)
  • London-school isolation, real ethers.Wallet for crypto primitives
  • fast-check property-based tests on financial invariants (weight sum=10000)
  • Coverage gates: 100% on lib/x402.ts, 100% branches on session.ts + claim-registry.ts, 90%+ branches on orcid-oauth.ts

CI.github/workflows/test.yml runs both jobs on every PR.

Convention: describe(method) → describe(positive|negative|edge) → it. See docs/testing.md for full guide, mocking strategy, and adding-tests workflow.

# Reproduce local test run
cd contracts && forge test            # 56 contract tests
cd ../web && pnpm test                # 149 TypeScript tests
pnpm test:coverage                    # HTML report at web/coverage/

Integrate with Kutip

Kutip is composable. Other agents, indexers, and apps can plug into the research-and-pay loop three ways — pick whichever matches your runtime.

1. MCP — for AI agents (Claude Desktop, Cursor, Cline)

The fastest path. One stdio process, three tools that any MCP-compatible LLM client can call natively. Full setup in mcp/README.md.

Tool Description
kutip.research(query, budgetUSDC) Run a query end-to-end. Returns summary + citations + Kite tx hash.
kutip.summary(queryId) Fetch a past summary via reverse-x402 paywall.
kutip.authors(limit, onlyClaimed) List paid authors + their wallets.

Why it matters: an external agent that cites Kutip's work pays Kutip, which pays the original authors. Recursive royalties without escrow tracking.

2. HTTP API — for any backend / curl

Three public endpoints power most integrations. Every other route in /api/* is internal to the dashboard.

# Run a research query (the dashboard uses the same endpoint).
curl -X POST https://kutip-zeta.vercel.app/api/query \
  -H "content-type: application/json" \
  -d '{"query":"What are the top carbon capture methods in 2024?","budgetUSDC":"0.10"}'

# Retrieve a saved summary (reverse-x402: receipt-or-pay).
curl https://kutip-zeta.vercel.app/api/summaries/<queryId>

# Download a portable JSON receipt — on-chain attestation + per-author
# payouts + synthesis + keccak256 digest, rebuilt from canonical sources.
curl https://kutip-zeta.vercel.app/api/receipt/<queryId>

# Real x402 corpus-access endpoint — POST with no header returns a
# genuine HTTP 402 challenge; pay on-chain, retry with X-PAYMENT.
curl -i -X POST https://kutip-zeta.vercel.app/api/x402 \
  -H "content-type: application/json" -d '{"queryId":"demo-1"}'

# Bind ORCID → wallet (after OAuth + EIP-712 signature).
curl -X POST https://kutip-zeta.vercel.app/api/claim \
  -H "content-type: application/json" \
  --cookie "kutip_orcid_verified=<signed-cookie>" \
  -d '{"orcid":"0009-0002-8864-0901","wallet":"0x...","signature":"0x..."}'

Full request/response shapes live in the route files: api/query · api/x402 · api/summaries/[queryId] · api/receipt/[queryId] · api/claim.

3. On-chain — for indexers, wallets, settlement bots

Read directly from AttributionLedger (Kite testnet) or the Goldsky subgraph. No HTTP layer, no rate limits.

Source Use for
AttributionLedger.attestAndSplit event Watch every paid query, indexer-friendly
AttributionLedger.authorEarnings(addr) Lifetime USDC earned for a wallet
Goldsky subgraph Pre-aggregated leaderboard + recent attestations
CitationMirror (Fuji) Cross-chain proof reachable from Avalanche-native apps

ABIs are in contracts/abi/ (auto-exported from Foundry build).


Documentation

Long-form docs live under docs/ — organised as a GitBook-shaped book (read SUMMARY.md for the sidebar). Highlights:

  • Architecture — money flow, identity binding, contract addresses
  • Security model — threat model + every audit finding (14 patched across 3 rounds) and how to verify each fix
  • Usage guide — run a query, sign a session, claim author earnings
  • Integrate / API — call Kutip from your own app, an MCP client, or directly on-chain
  • Testing guide — 56 Foundry tests + 149 Vitest cases, conventions for adding more
  • Deployment — contract deploy order + Vercel setup
  • Agent Passport — EIP-712 session delegation deeper dive
  • Demo script — the 90-second walkthrough

Import into GitBook, Honkit, or mdBook — all read docs/SUMMARY.md for the sidebar. The repo ships a .gitbook.yaml at the root for direct GitBook hosting.


Links

License

MIT

About

Citations that pay. AI research agent on Kite AI — Hackathon 2026 Novel track.

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors