Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Subgraph development for The Graph protocol. Includes manifest configuration, GraphQL schema design, AssemblyScript handlers, entity relationships, and deployment to hosted and decentralized networks.
.claude/skills/a5c-ai-subgraph-indexing/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-18 | ✗→✓ | ▲ Improved | 67% | 0% |
| case-01 | ✗→✗ | = Same ✗ | 520% | 0% |
| case-02 | ✗→✗ | = Same ✗ | 100% | 0% |
| case-03 | ✗→✗ | = Same ✗ | 174% | 0% |
| case-04 | ✗→✗ | = Same ✗ | 336% | 0% |
Subgraph development for The Graph protocol, enabling efficient blockchain data indexing and querying.
bash# Install Graph CLI npm install -g @graphprotocol/graph-cli # Verify graph --version
bash# Initialize from existing contract graph init --product subgraph-studio \ --from-contract 0x... \ --network mainnet \ --abi ./abi.json \ my-subgraph cd my-subgraph
my-subgraph/
├── subgraph.yaml # Manifest
├── schema.graphql # GraphQL schema
├── src/
│ └── mapping.ts # Event handlers
├── abis/
│ └── Contract.json # Contract ABIs
├── tests/
│ └── contract.test.ts # Unit tests
└── package.jsonyamlspecVersion: 0.0.5 schema: file: ./schema.graphql dataSources: - kind: ethereum name: Token network: mainnet source: address: "0x..." abi: Token startBlock: 18000000 mapping: kind: ethereum/events apiVersion: 0.0.7 language: wasm/assemblyscript entities: - Transfer - Account abis: - name: Token file: ./abis/Token.json eventHandlers: - event: Transfer(indexed address,indexed address,uint256) handler: handleTransfer - event: Approval(indexed address,indexed address,uint256) handler: handleApproval callHandlers: - function: transfer(address,uint256) handler: handleTransferCall blockHandlers: - handler: handleBlock file: ./src/mapping.ts
graphql# schema.graphql type Token @entity { id: ID! name: String! symbol: String! decimals: Int! totalSupply: BigInt! holders: [Account!]! @derivedFrom(field: "token") } type Account @entity { id: ID! token: Token! balance: BigInt! transfersFrom: [Transfer!]! @derivedFrom(field: "from") transfersTo: [Transfer!]! @derivedFrom(field: "to") } type Transfer @entity { id: ID! from: Account! to: Account! value: BigInt! timestamp: BigInt! blockNumber: BigInt! transactionHash: Bytes! } # For aggregations type DailyVolume @entity { id: ID! # date string date: BigInt! volume: BigInt! txCount: Int! }
typescript// src/mapping.ts import { Transfer as TransferEvent } from "../generated/Token/Token"; import { Token, Account, Transfer, DailyVolume } from "../generated/schema"; import { BigInt, Bytes, Address } from "@graphprotocol/graph-ts"; export function handleTransfer(event: TransferEvent): void { // Create Transfer entity let transfer = new Transfer( event.transaction.hash.toHex() + "-" + event.logIndex.toString() ); transfer.from = getOrCreateAccount(event.params.from).id; transfer.to = getOrCreateAccount(event.params.to).id; transfer.value = event.params.value; transfer.timestamp = event.block.timestamp; transfer.blockNumber = event.block.number; transfer.transactionHash = event.transaction.hash; transfer.save(); // Update account balances updateAccountBalance(event.params.from, event.params.value.neg()); updateAccountBalance(event.params.to, event.params.value); // Update daily volume updateDailyVolume(event.block.timestamp, event.params.value); } function getOrCreateAccount(address: Address): Account { let id = address.toHex(); let account = Account.load(id); if (account == null) { account = new Account(id); account.token = "token-id"; account.balance = BigInt.fromI32(0); account.save(); } return account; } function updateAccountBalance(address: Address, delta: BigInt): void { let account = getOrCreateAccount(address); account.balance = account.balance.plus(delta); account.save(); } function updateDailyVolume(timestamp: BigInt, value: BigInt): void { let dayId = timestamp.toI32() / 86400; let id = dayId.toString(); let volume = DailyVolume.load(id); if (volume == null) { volume = new DailyVolume(id); volume.date = BigInt.fromI32(dayId * 86400); volume.volume = BigInt.fromI32(0); volume.txCount = 0; } volume.volume = volume.volume.plus(value); volume.txCount = volume.txCount + 1; volume.save(); }
yaml# subgraph.yaml - for factory patterns templates: - kind: ethereum name: Pool network: mainnet source: abi: Pool mapping: kind: ethereum/events apiVersion: 0.0.7 language: wasm/assemblyscript entities: - Pool - Swap abis: - name: Pool file: ./abis/Pool.json eventHandlers: - event: Swap(indexed address,uint256,uint256) handler: handleSwap file: ./src/pool.ts
typescript// src/factory.ts import { Pool as PoolTemplate } from "../generated/templates"; export function handlePoolCreated(event: PoolCreated): void { // Create data source for new pool PoolTemplate.create(event.params.pool); // Create Pool entity let pool = new Pool(event.params.pool.toHex()); pool.save(); }
bash# Generate code from schema graph codegen # Build subgraph graph build # Authenticate graph auth --studio <deploy-key> # Deploy to Subgraph Studio graph deploy --studio my-subgraph # Deploy to hosted service (deprecated) graph deploy --node https://api.thegraph.com/deploy/ \ --ipfs https://api.thegraph.com/ipfs/ \ username/my-subgraph
graphql# Example queries query RecentTransfers { transfers(first: 10, orderBy: timestamp, orderDirection: desc) { id from { id balance } to { id balance } value timestamp } } query TopHolders { accounts(first: 10, orderBy: balance, orderDirection: desc) { id balance } } query DailyVolumes { dailyVolumes(first: 30, orderBy: date, orderDirection: desc) { date volume txCount } }
typescript// tests/token.test.ts import { assert, test, clearStore } from "matchstick-as"; import { handleTransfer } from "../src/mapping"; import { createTransferEvent } from "./utils"; test("Creates Transfer entity", () => { let event = createTransferEvent( "0x1234...", "0x5678...", "1000000000000000000" ); handleTransfer(event); assert.entityCount("Transfer", 1); clearStore(); });
| Process | Purpose | |---------|---------| | subgraph-development.js | Subgraph development | | blockchain-indexer-development.js | Indexing pipelines | | dapp-frontend-development.js | Data integration |
skills/wallet-integration/SKILL.md - dApp integrationagents/web3-frontend/AGENT.md - Frontend expert| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 2,584 | 1,242 | -52% | 1 | 1 | 0% | 383 | 2,373 | +520% | 0 | 0 | — |
case-02 | fail→fail | 8,924 | 6,996 | -22% | 1 | 1 | 0% | 1,711 | 3,429 | +100% | 0 | 0 | — |
case-03 | fail→fail | 5,937 | 3,962 | -33% | 1 | 1 | 0% | 1,058 | 2,897 | +174% | 0 | 0 | — |
case-04 | fail→fail | 3,934 | 2,856 | -27% | 1 | 1 | 0% | 614 | 2,678 | +336% | 0 | 0 | — |
case-05 | fail→fail | 8,529 | 3,589 | -58% | 1 | 1 | 0% | 1,563 | 2,735 | +75% | 0 | 0 | — |
case-06 | fail→fail | 10,633 | 6,342 | -40% | 1 | 1 | 0% | 2,098 | 3,526 | +68% | 0 | 0 | — |
case-07 | fail→fail | 2,806 | 1,522 | -46% | 1 | 1 | 0% | 462 | 2,466 | +434% | 0 | 0 | — |
case-08 | fail→fail | 2,972 | 2,026 | -32% | 1 | 1 | 0% | 518 | 2,589 | +400% | 0 | 0 | — |
case-09 | fail→fail | 3,074 | 1,969 | -36% | 1 | 1 | 0% | 510 | 2,420 | +375% | 0 | 0 | — |
case-10 | fail→fail | 3,035 | 1,413 | -53% | 1 | 1 | 0% | 482 | 2,419 | +402% | 0 | 0 | — |
case-11 | fail→fail | 3,552 | 2,497 | -30% | 1 | 1 | 0% | 601 | 2,727 | +354% | 0 | 0 | — |
case-12 | fail→fail | 6,788 | 3,599 | -47% | 1 | 1 | 0% | 1,268 | 2,914 | +130% | 0 | 0 | — |
case-13 | fail→fail | 3,782 | 2,672 | -29% | 1 | 1 | 0% | 709 | 2,694 | +280% | 0 | 0 | — |
case-14 | fail→fail | 4,492 | 4,357 | -3% | 1 | 1 | 0% | 943 | 3,023 | +221% | 0 | 0 | — |
case-15 | fail→fail | 3,026 | 2,468 | -18% | 1 | 1 | 0% | 576 | 2,611 | +353% | 0 | 0 | — |
case-16 | fail→fail | 3,918 | 3,242 | -17% | 1 | 1 | 0% | 649 | 2,850 | +339% | 0 | 0 | — |
case-17 | fail→fail | 2,845 | 2,545 | -11% | 1 | 1 | 0% | 467 | 2,692 | +476% | 0 | 0 | — |
case-18 | fail→pass | 9,588 | 5,978 | -38% | 1 | 1 | 0% | 2,009 | 3,356 | +67% | 0 | 0 | — |
case-19 | fail→fail | 3,014 | 2,382 | -21% | 1 | 1 | 0% | 466 | 2,591 | +456% | 0 | 0 | — |
case-20 | fail→fail | 7,482 | 4,455 | -40% | 1 | 1 | 0% | 1,487 | 3,059 | +106% | 0 | 0 | — |
case-21 | fail→fail | 6,836 | 5,957 | -13% | 1 | 1 | 0% | 1,330 | 3,419 | +157% | 0 | 0 | — |
case-22 | fail→fail | 11,320 | 7,205 | -36% | 1 | 1 | 0% | 1,860 | 3,740 | +101% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.