@dilukangelo/web3-ai-skills 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dilukangelo/web3-ai-skills",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "CLI to initialize Web3 AI Agent Skills — Solidity, Rust, DApp frontends, auditing, RPC, and indexing for 2026",
5
5
  "main": "bin/cli.js",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: subgraph-indexing
3
- description: Chain indexing with The Graph, Ponder, Envio, and custom indexers. Event-driven data, GraphQL APIs, entity relationships, and real-time sync.
3
+ description: Chain indexing with The Graph, Ponder, Subsquid, Envio, and custom indexers. Event-driven data, GraphQL APIs, entity relationships, and real-time sync.
4
4
  ---
5
5
 
6
6
  # Subgraph & Indexing — Blockchain Data Access
@@ -10,7 +10,7 @@ Expert knowledge for building efficient blockchain data indexing solutions.
10
10
  ## Use this skill when
11
11
 
12
12
  - Building subgraphs for The Graph
13
- - Setting up Ponder or Envio indexers
13
+ - Setting up Ponder, Subsquid, or Envio indexers
14
14
  - Creating real-time data feeds from on-chain events
15
15
  - Designing entity schemas for blockchain data
16
16
  - Querying historical blockchain data efficiently
@@ -165,16 +165,215 @@ ponder.on('Token:Transfer', async ({ event, context }) => {
165
165
 
166
166
  ---
167
167
 
168
+ ## Subsquid (SQD / Squid SDK)
169
+
170
+ ### Overview
171
+ Subsquid is a batch-processing blockchain indexer optimized for high-throughput multi-chain data. Uses the **SQD Network** as a decentralized data lake.
172
+
173
+ ### Project Structure
174
+ ```
175
+ squid/
176
+ ├── src/
177
+ │ ├── processor.ts # EvmBatchProcessor config
178
+ │ ├── main.ts # Processing logic
179
+ │ ├── model/ # TypeORM entities
180
+ │ └── abi/ # Generated type-safe ABI wrappers
181
+ ├── db/
182
+ │ └── migrations/ # Database migrations
183
+ ├── schema.graphql # Entity definitions (generates model/)
184
+ ├── squid.yaml # Deployment manifest
185
+ ├── commands.json # CLI commands
186
+ └── docker-compose.yml # Local Postgres + GraphQL
187
+ ```
188
+
189
+ ### Installation
190
+ ```bash
191
+ # Install Squid CLI
192
+ npm i -g @subsquid/cli
193
+
194
+ # Create new squid from EVM template
195
+ sqd init my-squid -t evm
196
+
197
+ # Generate ABI types
198
+ npx squid-evm-typegen src/abi erc721.json
199
+ # or from Etherscan:
200
+ npx squid-evm-typegen src/abi 0x...contractAddress --etherscan-api https://api.etherscan.io/api
201
+ ```
202
+
203
+ ### Processor Configuration
204
+ ```typescript
205
+ // src/processor.ts
206
+ import { EvmBatchProcessor } from '@subsquid/evm-processor'
207
+ import { lookupArchive } from '@subsquid/archive-registry'
208
+
209
+ export const processor = new EvmBatchProcessor()
210
+ // Use SQD Network for fast batch data access
211
+ .setGateway(lookupArchive('eth-mainnet'))
212
+ // Also connect to RPC for real-time blocks
213
+ .setRpcEndpoint(process.env.RPC_ENDPOINT)
214
+ .setFinalityConfirmation(75)
215
+ .setBlockRange({ from: 18_000_000 })
216
+ .addLog({
217
+ address: ['0x...'], // Contract address
218
+ topic0: [
219
+ // Transfer(address,address,uint256)
220
+ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
221
+ ],
222
+ })
223
+ .addTransaction({
224
+ to: ['0x...'],
225
+ sighash: ['0xa9059cbb'], // transfer(address,uint256)
226
+ })
227
+ .setFields({
228
+ log: { transactionHash: true },
229
+ transaction: { from: true, value: true, hash: true },
230
+ })
231
+ ```
232
+
233
+ ### Entity Schema
234
+ ```graphql
235
+ # schema.graphql — generates TypeORM entities
236
+ type Token @entity {
237
+ id: ID!
238
+ name: String!
239
+ symbol: String!
240
+ totalSupply: BigInt!
241
+ transfers: [Transfer!]! @derivedFrom(field: "token")
242
+ }
243
+
244
+ type Transfer @entity {
245
+ id: ID!
246
+ token: Token!
247
+ from: String! @index
248
+ to: String! @index
249
+ value: BigInt!
250
+ blockNumber: Int!
251
+ timestamp: DateTime!
252
+ }
253
+ ```
254
+ ```bash
255
+ # Generate TypeORM entities from schema
256
+ npx squid-typeorm-codegen
257
+ npx squid-typeorm-migration generate
258
+ ```
259
+
260
+ ### Batch Processing Logic
261
+ ```typescript
262
+ // src/main.ts
263
+ import { TypeormDatabase } from '@subsquid/typeorm-store'
264
+ import { processor } from './processor'
265
+ import { Transfer } from './model'
266
+ import * as erc721 from './abi/erc721'
267
+
268
+ processor.run(new TypeormDatabase(), async (ctx) => {
269
+ const transfers: Transfer[] = []
270
+
271
+ for (const block of ctx.blocks) {
272
+ for (const log of block.logs) {
273
+ if (log.topics[0] === erc721.events.Transfer.topic) {
274
+ const { from, to, tokenId } = erc721.events.Transfer.decode(log)
275
+
276
+ transfers.push(new Transfer({
277
+ id: log.id,
278
+ from,
279
+ to,
280
+ tokenId: tokenId.toString(),
281
+ blockNumber: block.header.height,
282
+ timestamp: new Date(block.header.timestamp),
283
+ }))
284
+ }
285
+ }
286
+ }
287
+
288
+ // Batch insert — much faster than individual saves
289
+ await ctx.store.insert(transfers)
290
+ })
291
+ ```
292
+
293
+ ### Deployment
294
+ ```bash
295
+ # Local development
296
+ docker compose up -d # Start Postgres
297
+ npx squid-typeorm-migration apply
298
+ node -r dotenv/config lib/main.js
299
+
300
+ # Deploy to SQD Cloud
301
+ sqd deploy .
302
+ ```
303
+
304
+ ### Key Advantages
305
+ | Feature | Detail |
306
+ |---------|--------|
307
+ | **Batch Processing** | Process 1000s of blocks per batch (faster than event-by-event) |
308
+ | **SQD Network** | Decentralized data lake, no RPC needed for historical data |
309
+ | **Multi-chain** | 100+ EVM and Substrate networks supported |
310
+ | **Type-safe** | ABI typegen for events, functions, and multicall |
311
+ | **Multicall Support** | Built-in `Multicall` facade for batch RPC reads |
312
+ | **Real-time** | Connect RPC endpoint for latest blocks |
313
+
314
+ ---
315
+
316
+ ## Envio (HyperSync)
317
+
318
+ ### Setup
319
+ ```bash
320
+ npx envio init
321
+
322
+ # envio.config.ts
323
+ export default {
324
+ networks: [{
325
+ id: 1,
326
+ rpc_url: process.env.ETH_RPC_URL,
327
+ contracts: [{
328
+ name: 'Token',
329
+ address: '0x...',
330
+ abi_file_path: './abis/Token.json',
331
+ events: ['Transfer'],
332
+ start_block: 18_000_000,
333
+ }],
334
+ }],
335
+ }
336
+ ```
337
+
338
+ ### Event Handlers (Envio)
339
+ ```typescript
340
+ import { TokenContract } from '../generated/src/Handlers.gen'
341
+
342
+ TokenContract.Transfer.handler(async ({ event, context }) => {
343
+ const transfer = {
344
+ id: event.transactionHash + '-' + event.logIndex,
345
+ from: event.params.from,
346
+ to: event.params.to,
347
+ value: event.params.value,
348
+ }
349
+ context.Transfer.set(transfer)
350
+ })
351
+ ```
352
+
353
+ ### HyperSync Advantage
354
+ - **100x faster** than RPC for historical data
355
+ - Raw data streamed from Envio's optimized indices
356
+ - No rate limits or throttling
357
+
358
+ ---
359
+
168
360
  ## Indexer Selection Guide
169
361
 
170
- | Tool | Best For | Language | Hosting |
171
- |------|----------|----------|---------|
172
- | **The Graph** | Decentralized, production | AssemblyScript | Decentralized |
173
- | **Ponder** | TypeScript-native, fast dev | TypeScript | Self-hosted |
174
- | **Envio** | High-performance, HyperSync | TypeScript | Managed |
175
- | **Goldsky** | Mirror + Subgraphs | GraphQL | Managed |
176
- | **Subsquid** | Multi-chain, archive data | TypeScript | Managed |
177
- | **Custom** | Full control | Any | Self-hosted |
362
+ | Tool | Best For | Language | Speed | Hosting | Multi-chain |
363
+ |------|----------|----------|-------|---------|-------------|
364
+ | **The Graph** | Decentralized, production | AssemblyScript | Medium | Decentralized | ✅ |
365
+ | **Ponder** | TypeScript-native, fast dev | TypeScript | Fast | Self-hosted | ✅ |
366
+ | **Subsquid** | High-throughput, archive data | TypeScript | Very Fast | SQD Cloud | ✅ 100+ |
367
+ | **Envio** | Ultra-fast historical sync | TypeScript | Fastest | Managed | ✅ |
368
+ | **Goldsky** | Mirror + Subgraphs | GraphQL | Fast | Managed | ✅ |
369
+ | **Custom** | Full control | Any | Variable | Self-hosted | Manual |
370
+
371
+ ### When to Use What
372
+ - **Decentralized & battle-tested?** → The Graph
373
+ - **TypeScript-native, fast iteration?** → Ponder
374
+ - **Multi-chain with batch processing?** → Subsquid
375
+ - **Fastest historical sync possible?** → Envio (HyperSync)
376
+ - **Need subgraphs + real-time streams?** → Goldsky
178
377
 
179
378
  ---
180
379
 
@@ -210,16 +409,33 @@ query TopHolders($token: Bytes!) {
210
409
  transferCount
211
410
  }
212
411
  }
412
+
413
+ # Subsquid-style query with pagination
414
+ query NFTTransfers($owner: String!, $offset: Int) {
415
+ transfers(
416
+ where: { to_eq: $owner }
417
+ limit: 50
418
+ offset: $offset
419
+ orderBy: blockNumber_DESC
420
+ ) {
421
+ tokenId
422
+ from
423
+ to
424
+ blockNumber
425
+ timestamp
426
+ }
427
+ }
213
428
  ```
214
429
 
215
430
  ---
216
431
 
217
432
  ## Best Practices
218
433
 
219
- - Use `immutable: true` for event entities (never need updates)
434
+ - Use `immutable: true` (Graph) or batch inserts (Subsquid) for event entities
220
435
  - Cache derived values instead of computing in queries
221
- - Use `@derivedFrom` for reverse lookups
436
+ - Use `@derivedFrom` / `@index` for relationship lookups
222
437
  - Index only the data you need — less storage, faster sync
223
- - Handle chain reorgs gracefully
224
- - Test handlers with Matchstick or local tests
225
- - Monitor indexing health and sync lag
438
+ - Handle chain reorgs gracefully (use finality confirmations)
439
+ - Test handlers with Matchstick (Graph) or unit tests (others)
440
+ - Monitor indexing health, sync lag, and data freshness
441
+ - Use multicall for batch on-chain reads during indexing