$npx -y skills add basezh/agent-skills-on-base --skill query-onchain-dataQuery onchain data on Base using the CDP SQL API via x402. Use when you or your user want to view onchain information about decoded blocks, transactions, and event.
| 1 | # Query Onchain Data on Base |
| 2 | |
| 3 | Use the CDP SQL API to query onchain data (events, transactions, blocks, transfers) on Base. Queries are executed via x402 and are charged per query. |
| 4 | |
| 5 | ## Confirm wallet is initialized and authed |
| 6 | |
| 7 | ```bash |
| 8 | npx awal@2.0.3 status |
| 9 | ``` |
| 10 | |
| 11 | If the wallet is not authenticated, refer to the `authenticate-wallet` skill. |
| 12 | |
| 13 | ## Executing a Query |
| 14 | |
| 15 | ```bash |
| 16 | npx awal@2.0.3 x402 pay https://x402.cdp.coinbase.com/platform/v2/data/query/run -X POST -d '{"sql": "<YOUR_QUERY>"}' --json |
| 17 | ``` |
| 18 | |
| 19 | **IMPORTANT**: Always single-quote the `-d` JSON string to prevent bash variable expansion. |
| 20 | |
| 21 | ## Input Validation |
| 22 | |
| 23 | Before constructing the command, validate inputs to prevent shell injection: |
| 24 | |
| 25 | - **SQL query**: Always embed the query inside a single-quoted JSON string (`-d '{"sql": "..."}'`). Never use double quotes for the outer `-d` wrapper, as this enables shell expansion of `$` and backticks within the query. |
| 26 | - **Addresses**: Must be valid `0x` hex addresses (`^0x[0-9a-fA-F]{40}$`). Reject any value containing shell metacharacters. |
| 27 | |
| 28 | Do not pass unvalidated user input into the command. |
| 29 | |
| 30 | ## CRITICAL: Indexed Fields |
| 31 | |
| 32 | Queries against `base.events` **MUST** filter on indexed fields to avoid full table scans. The indexed fields are: |
| 33 | |
| 34 | | Indexed Field | Use For | |
| 35 | | --- | --- | |
| 36 | | `event_signature` | Filter by event type. Use this instead of `event_name` for performance. | |
| 37 | | `address` | Filter by contract address. | |
| 38 | | `block_timestamp` | Filter by time range. | |
| 39 | |
| 40 | **Always include at least one indexed field in your WHERE clause.** Combining all three gives the best performance. |
| 41 | |
| 42 | ## CoinbaseQL Syntax |
| 43 | |
| 44 | CoinbaseQL is a SQL dialect based on ClickHouse. Supported features: |
| 45 | |
| 46 | - **Clauses**: SELECT (DISTINCT), FROM, WHERE, GROUP BY, ORDER BY (ASC/DESC), LIMIT, WITH (CTEs), UNION (ALL/DISTINCT) |
| 47 | - **Joins**: INNER, LEFT, RIGHT, FULL with ON |
| 48 | - **Operators**: `=`, `!=`, `<>`, `<`, `>`, `<=`, `>=`, `+`, `-`, `*`, `/`, `%`, AND, OR, NOT, BETWEEN, IN, IS NULL, LIKE |
| 49 | - **Expressions**: CASE/WHEN/THEN/ELSE, CAST (both `CAST()` and `::` syntax), subqueries, array/map indexing with `[]`, dot notation |
| 50 | - **Literals**: Array `[...]`, Map `{...}`, Tuple `(...)` |
| 51 | - **Functions**: Standard SQL functions, lambda functions with `->` syntax |
| 52 | |
| 53 | ## Available Tables |
| 54 | |
| 55 | ### base.events |
| 56 | |
| 57 | Decoded event logs from smart contract interactions. **This is the primary table for most queries.** |
| 58 | |
| 59 | | Column | Type | Description | |
| 60 | | --- | --- | --- | |
| 61 | | log_id | String | Unique log identifier | |
| 62 | | block_number | UInt64 | Block number | |
| 63 | | block_hash | FixedString(66) | Block hash | |
| 64 | | block_timestamp | DateTime64(3, 'UTC') | Block timestamp (**INDEXED**) | |
| 65 | | transaction_hash | FixedString(66) | Transaction hash | |
| 66 | | transaction_to | FixedString(42) | Transaction recipient | |
| 67 | | transaction_from | FixedString(42) | Transaction sender | |
| 68 | | log_index | UInt32 | Log index within block | |
| 69 | | address | FixedString(42) | Contract address (**INDEXED**) | |
| 70 | | topics | Array(FixedString(66)) | Event topics | |
| 71 | | event_name | LowCardinality(String) | Decoded event name | |
| 72 | | event_signature | LowCardinality(String) | Event signature (**INDEXED** - prefer over event_name) | |
| 73 | | parameters | Map(String, Variant(Bool, Int256, String, UInt256)) | Decoded event parameters | |
| 74 | | parameter_types | Map(String, String) | ABI types for parameters | |
| 75 | | action | Enum8('removed' = -1, 'added' = 1) | Added or removed (reorg) | |
| 76 | |
| 77 | ### base.transactions |
| 78 | |
| 79 | Complete transaction data. |
| 80 | |
| 81 | | Column | Type | Description | |
| 82 | | --- | --- | --- | |
| 83 | | block_number | UInt64 | Block number | |
| 84 | | block_hash | String | Block hash | |
| 85 | | transaction_hash | String | Transaction hash | |
| 86 | | transaction_index | UInt64 | Index in block | |
| 87 | | from_address | String | Sender address | |
| 88 | | to_address | String | Recipient address | |
| 89 | | value | String | Value transferred (wei) | |
| 90 | | gas | UInt64 | Gas limit | |
| 91 | | gas_price | UInt64 | Gas price | |
| 92 | | input | String | Input data | |
| 93 | | nonce | UInt64 | Sender nonce | |
| 94 | | type | UInt64 | Transaction type | |
| 95 | | max_fee_per_gas | UInt64 | EIP-1559 max fee | |
| 96 | | max_priority_fee_per_gas | UInt64 | EIP-1559 priority fee | |
| 97 | | chain_id | UInt64 | Chain ID | |
| 98 | | v | String | Signature v | |
| 99 | | r | String | Signature r | |
| 100 | | s | String | Signature s | |
| 101 | | is_system_tx | Bool | System transaction flag | |
| 102 | | max_fee_per_blob_gas | String | Blob gas fee | |
| 103 | | blob_versioned_hashes | Array(String) | Blob hashes | |
| 104 | | timestamp | DateTime | Block timestamp | |
| 105 | | action | Int8 | Added (1) or removed (-1) | |
| 106 | |
| 107 | ### base.blocks |
| 108 | |
| 109 | Block-level metadata. |
| 110 | |
| 111 | | Column | Type | Description | |
| 112 | | --- | --- | --- | |
| 113 | | block_number | UInt64 | Block number | |
| 114 | | block_hash | String | Block hash | |
| 115 | | parent_hash | String |