Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build & Run

```bash
# Build the binary (requires CGO for BLS crypto)
CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" GO111MODULE=on go build -o ./cmd/flow/flow ./cmd/flow

# Or use Make
make binary

# Run directly without building
go run cmd/flow/main.go [command]
```

## Testing

```bash
# Run all tests
make test
# Equivalent: CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" GO111MODULE=on go test -coverprofile=coverage.txt ./...

# Run a single test package
CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" go test ./internal/accounts/...

# Run a specific test
CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" go test ./internal/accounts/... -run TestFunctionName

# Skip network-dependent tests (e.g. in sandboxed environments)
SKIP_NETWORK_TESTS=1 make test
```

## Linting

```bash
make lint # Run golangci-lint
make fix-lint # Auto-fix lint issues
make check-headers # Verify Apache license headers on all Go files
go generate ./... # Regenerate generated code (required before lint)
```

## Architecture

The CLI is a [Cobra](https://github.com/spf13/cobra)-based application with three main layers:

### Entry Point
`cmd/flow/main.go` — wires all subcommands into the root `flow` command.

### Command Framework (`internal/command/`)
The `command.Command` struct wraps a `cobra.Command` with two execution modes:
- `Run` — for commands that don't need a loaded `flow.json` state
- `RunS` — for commands that require an initialized project state (`*flowkit.State`)

`Command.AddToParent()` handles all shared boilerplate: loading `flow.json`, resolving network/host, creating the gRPC gateway, initializing `flowkit.Services`, version checking, analytics, and error formatting. **All new commands should use this pattern.**

Every command's run function returns a `command.Result` interface with three output methods: `String()` (human-readable), `Oneliner()` (grep-friendly inline), and `JSON()` (structured). The framework handles `--output`, `--filter`, and `--save` flags automatically.

### Command Packages (`internal/`)
Each feature area is its own package with a top-level `Cmd *cobra.Command` that aggregates subcommands. Pattern:
- `accounts.Cmd` (`internal/accounts/`) — registered in `main.go` via `cmd.AddCommand(accounts.Cmd)`
- Subcommands (e.g., `get.go`, `create.go`) define a package-level `var getCommand = &command.Command{...}` and register via `init()` or the parent's `init()`

Key packages:
- `internal/super/` — high-level "super commands": `flow init`, `flow dev`, `flow generate`, `flow flix`
- `internal/super/generator/` — code generation engine for Cadence contracts, scripts, transactions, and tests
- `internal/dependencymanager/` — `flow deps` commands for managing on-chain contract dependencies
- `internal/config/` — `flow config` subcommands for managing `flow.json`
- `internal/emulator/` — wraps the Flow emulator

### flowkit Dependency
The CLI delegates all blockchain interactions to the `github.com/onflow/flowkit/v2` module (external). The `flowkit.Services` interface is the primary abstraction for network calls. The local `flowkit/` directory is a historical artifact (migrated to the external module) and contains only a README and schema.

### Global Flags
Defined in `internal/command/global_flags.go`, applied to every command: `--network`, `--host`, `--log`, `--output`, `--filter`, `--save`, `--config-path`, `--yes`, `--skip-version-check`.

### Configuration
`flow.json` is the project config file. `flowkit.Load()` reads it. The `internal/config/` commands modify it. `state.Networks()`, `state.Accounts()`, etc. provide typed access.

## CLI Design Conventions
- Commands follow `noun verb` pattern (`flow accounts get`)
- Prefer flags over positional args; use args only for the primary required value
- `--output json` must always work for machine-readable output
- Errors go to stderr; normal output to stdout
- Progress indicators for long-running operations via `logger.StartProgress()` / `logger.StopProgress()`
- Long-running commands support `--yes` to skip confirmation prompts

## License Headers
All Go source files must have the Apache 2.0 license header. Run `make check-headers` to verify.
291 changes: 291 additions & 0 deletions skills/query-blockchain/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
---
name: query-blockchain
description: Use when you need to read any data from the Flow blockchain — account state, blocks, events, transaction results, collections, or custom contract state via Cadence scripts.
---

# Querying the Flow Blockchain with flow-cli

## Overview

Use this skill any time you need on-chain data. Choose the right command from the decision table, then run it.

**When the entity commands don't expose what you need, use `flow scripts execute`** — Cadence scripts can query any on-chain state and are the primary tool for anything not covered by the commands below. See [Cadence Scripts](#cadence-scripts).

## Network

Default: **mainnet**. Infer from conversation context:

| Context | Flag |
|---|---|
| Default / production | `--network mainnet` |
| Testnet discussion | `--network testnet` |
| Local development / emulator | `--network emulator` |

Access node endpoints (built-in):
- Mainnet: `access.mainnet.nodes.onflow.org:9000`
- Testnet: `access.devnet.nodes.onflow.org:9000`
- Emulator: `127.0.0.1:3569`

Override with `--host <endpoint>` to point at a custom access node.

## Decision Table

| What you need | Command |
|---|---|
| Account balance, keys, deployed contracts | `flow accounts get` |
| Account staking info | `flow accounts staking-info` |
| Block info | `flow blocks get` |
| Events emitted in a block range | `flow events get` |
| Regular transaction status / result | `flow transactions get` |
| System transaction for a block | `flow transactions get-system` |
| Scheduled transaction details | `flow schedule get` / `flow schedule list` |
| Collection contents | `flow collections get` |
| Network status (online/offline) | `flow status` |
| Protocol state snapshot | `flow snapshot save` |
| Anything not covered above | `flow scripts execute` |

---

## Commands

### Accounts

```bash
flow accounts get <address|name> [--include contracts] [--network mainnet]
```

- `--include contracts` adds deployed contract source code to the output
- Flow addresses must include the `0x` prefix (e.g. `0xf8d6e0586b0a20c7`)
- `<name>` resolves via `flow.json` — only use names when a `flow.json` is present

```bash
flow accounts get 0xe467b9dd11fa00df --network mainnet
flow accounts get 0xe467b9dd11fa00df --include contracts --network mainnet
flow accounts staking-info 0xe467b9dd11fa00df --network mainnet
```

### Blocks

```bash
flow blocks get <block_id|latest|block_height> [--include transactions] [--events <event_name>] [--network mainnet]
```

```bash
flow blocks get latest --network mainnet
flow blocks get 12884163 --include transactions --network mainnet
flow blocks get latest --events A.1654653399040a61.FlowToken.TokensDeposited --network mainnet
```

### Events

```bash
flow events get <event_name> [<event_name2> ...] [--last 10] [--start N --end M] [--network mainnet]
```

- Default: last 10 blocks. Use `--last N` to widen.
- `--start`/`--end` for explicit block height range.
- Multiple event types are fetched in parallel.
- Event name format: `A.<address>.<ContractName>.<EventName>`

```bash
flow events get A.1654653399040a61.FlowToken.TokensDeposited --last 20 --network mainnet
flow events get A.1654653399040a61.FlowToken.TokensDeposited --start 11559500 --end 11559600 --network mainnet
flow events get A.1654653399040a61.FlowToken.TokensDeposited A.1654653399040a61.FlowToken.TokensWithdrawn --network mainnet
```

### Transactions

```bash
# Regular transaction
flow transactions get <tx_id> [--include signatures,code,payload,fee-events] [--exclude events] [--network mainnet]

# System transaction (by block, not tx hash)
flow transactions get-system <block_id|latest|block_height> [tx_id] [--network mainnet]

# Scheduled transactions
flow schedule get <numeric-id> [--network mainnet]
flow schedule list <address|account-name> [--network mainnet]
```

### Collections

```bash
flow collections get <collection_id> [--network mainnet]
```

### Network Status

```bash
flow status --network mainnet
```

---

## Output Format

All commands support `--output json` for machine-readable output.

```bash
flow accounts get 0xe467b9dd11fa00df --output json --network mainnet
flow events get A.1654653399040a61.FlowToken.TokensDeposited --output json --network mainnet
```

Use `--filter <property>` to extract specific fields from results.

---

## Cadence Scripts

`flow scripts execute` is the most powerful read tool. Use it when:

- You need data from a contract that has no dedicated CLI command
- You need to call a `view` function or read a field from a contract
- You need to combine data from multiple contracts in one query
- You need a historical snapshot at a specific block height

```bash
flow scripts execute <script.cdc> [args...] [--args-json '[{"type":"...","value":"..."}]'] [--block-height N] [--block-id <id>] [--network mainnet]
```

- Simple types (Address, UInt64, String, Bool) can be passed as positional args
- Use `--args-json` for complex types (UFix64, optionals, structs, arrays)
- `--block-height` / `--block-id` execute against historical state
- Write a temporary `.cdc` file, execute it, then clean up

### Writing and Running Scripts

Write script to a temp file, execute, clean up:

```bash
# Write
cat > /tmp/query.cdc << 'EOF'
import FungibleToken from 0xf233dcee88fe0abe
import FlowToken from 0x1654653399040a61

access(all) fun main(address: Address): UFix64 {
let account = getAccount(address)
let vaultRef = account.capabilities
.borrow<&{FungibleToken.Balance}>(/public/flowTokenBalance)
?? panic("Could not borrow FungibleToken Balance capability for account \(address) at path /public/flowTokenBalance. Make sure the account has a FlowToken Vault set up properly.")
return vaultRef.balance
}
EOF

# Execute
flow scripts execute /tmp/query.cdc 0xe467b9dd11fa00df --network mainnet

# Clean up
rm /tmp/query.cdc
```

### Passing Arguments

```bash
# Simple types as positional args
flow scripts execute /tmp/query.cdc 0xe467b9dd11fa00df --network mainnet

# Complex types with --args-json (JSON-Cadence encoding)
flow scripts execute /tmp/query.cdc --args-json '[{"type":"UFix64","value":"100.0"},{"type":"Address","value":"0xe467b9dd11fa00df"}]' --network mainnet

# Historical state
flow scripts execute /tmp/query.cdc 0xe467b9dd11fa00df --block-height 12884163 --network mainnet
```

---

## Contract Addresses

| Contract | Mainnet | Testnet | Emulator |
|---|---|---|---|
| FungibleToken | `0xf233dcee88fe0abe` | `0x9a0766d93b6608b7` | `0xee82856bf20e2aa6` |
| FungibleTokenMetadataViews | `0xf233dcee88fe0abe` | `0x9a0766d93b6608b7` | `0xf8d6e0586b0a20c7` |
| FungibleTokenSwitchboard | `0xf233dcee88fe0abe` | `0x9a0766d93b6608b7` | `0xf8d6e0586b0a20c7` |
| Burner | `0xf233dcee88fe0abe` | `0x9a0766d93b6608b7` | `0xf8d6e0586b0a20c7` |
| FlowToken | `0x1654653399040a61` | `0x7e60df042a9c0868` | `0x0ae53cb6e3f42a79` |
| NonFungibleToken | `0x1d7e57aa55817448` | `0x631e88ae7f1d7c20` | `0xf8d6e0586b0a20c7` |
| MetadataViews | `0x1d7e57aa55817448` | `0x631e88ae7f1d7c20` | `0xf8d6e0586b0a20c7` |
| ViewResolver | `0x1d7e57aa55817448` | `0x631e88ae7f1d7c20` | `0xf8d6e0586b0a20c7` |
| FlowFees | `0xf919ee77447b7497` | `0x912d5440f7e3769e` | `0xe5a8b7f23e8b548f` |
| FlowServiceAccount | `0xe467b9dd11fa00df` | `0x8c5303eaa26202d6` | `0xf8d6e0586b0a20c7` |
| FlowStorageFees | `0xe467b9dd11fa00df` | `0x8c5303eaa26202d6` | `0xf8d6e0586b0a20c7` |
| NodeVersionBeacon | `0xe467b9dd11fa00df` | `0x8c5303eaa26202d6` | `0xf8d6e0586b0a20c7` |
| RandomBeaconHistory | `0xe467b9dd11fa00df` | `0x8c5303eaa26202d6` | `0xf8d6e0586b0a20c7` |
| FlowIDTableStaking | `0x8624b52f9ddcd04a` | `0x9eca2b38b18b5dfe` | `0xf8d6e0586b0a20c7` |
| FlowEpoch | `0x8624b52f9ddcd04a` | `0x9eca2b38b18b5dfe` | `0xf8d6e0586b0a20c7` |
| FlowClusterQC | `0x8624b52f9ddcd04a` | `0x9eca2b38b18b5dfe` | `0xf8d6e0586b0a20c7` |
| FlowDKG | `0x8624b52f9ddcd04a` | `0x9eca2b38b18b5dfe` | `0xf8d6e0586b0a20c7` |
| FlowStakingCollection | `0x8d0e87b65159ae63` | `0x95e019a17d0e23d7` | `0xf8d6e0586b0a20c7` |
| LockedTokens | `0x8d0e87b65159ae63` | `0x95e019a17d0e23d7` | `0xf8d6e0586b0a20c7` |
| StakingProxy | `0x62430cf28c26d095` | `0x7aad92e5a0715d21` | `0xf8d6e0586b0a20c7` |
| EVM | `0xe467b9dd11fa00df` | `0x8c5303eaa26202d6` | `0xf8d6e0586b0a20c7` |
| FlowEVMBridge ¹ | `0x1e4aa0b87d10b141` | `0xdfc20aee650fcbdf` | `0xf8d6e0586b0a20c7` |
| NFTStorefrontV2 | `0x1d7e57aa55817448` | `0x2d55b98eb200daef` | `0xf8d6e0586b0a20c7` |
| HybridCustody | `0xd8a7e05a7ac670c0` | `0x294e44e1ec6993c6` | `0xf8d6e0586b0a20c7` |
| CapabilityFactory | `0xd8a7e05a7ac670c0` | `0x294e44e1ec6993c6` | `0xf8d6e0586b0a20c7` |
| CapabilityFilter | `0xd8a7e05a7ac670c0` | `0x294e44e1ec6993c6` | `0xf8d6e0586b0a20c7` |
| CapabilityDelegator | `0xd8a7e05a7ac670c0` | `0x294e44e1ec6993c6` | `0xf8d6e0586b0a20c7` |

¹ The EVM bridge account hosts many contracts beyond FlowEVMBridge itself (FlowEVMBridgeConfig, FlowEVMBridgeUtils, FlowEVMBridgeNFTEscrow, FlowEVMBridgeTokenEscrow, CrossVMNFT, CrossVMToken, and more). Run `flow accounts get 0x1e4aa0b87d10b141 --network mainnet` for the current deployed contract list, or check the [flow-evm-bridge](https://github.com/onflow/flow-evm-bridge) repo for available scripts.

---

## Cadence Script Recipes & Data Structures

See [cadence-scripts.md](cadence-scripts.md) for 20+ ready-to-use Cadence scripts organized by category:
- **Token queries** — FLOW balance, total supply, generic FT balance, FT metadata
- **Account & storage** — storage capacity, available balance, account creation fee, fee parameters
- **Epoch** — counter, phase, metadata, timing config
- **Staking** — node info, staked node IDs, total staked, by role, requirements, rewards, delegator info, staking collections
- **Protocol** — node version beacon, random beacon source
- **NFT** — collection IDs, NFT metadata (Display)
- **Key data structures** — NodeInfo, DelegatorInfo, EpochMetadata, EpochPhase, Node Roles

---

## Common Event Types

| Event | Description |
|---|---|
| `A.f233dcee88fe0abe.FungibleToken.Deposited` | Any fungible token deposited |
| `A.f233dcee88fe0abe.FungibleToken.Withdrawn` | Any fungible token withdrawn |
| `A.f233dcee88fe0abe.FungibleToken.Burned` | Any fungible token burned |
| `A.1d7e57aa55817448.NonFungibleToken.Deposited` | Any NFT deposited to a collection |
| `A.1d7e57aa55817448.NonFungibleToken.Withdrawn` | Any NFT withdrawn from a collection |
| `A.8624b52f9ddcd04a.FlowEpoch.NewEpoch` | New epoch started |
| `A.8624b52f9ddcd04a.FlowEpoch.EpochSetup` | Epoch setup phase began |
| `A.8624b52f9ddcd04a.FlowEpoch.EpochCommit` | Epoch commit phase began |
| `A.8624b52f9ddcd04a.FlowIDTableStaking.NewNodeCreated` | New staking node registered |
| `A.8624b52f9ddcd04a.FlowIDTableStaking.TokensCommitted` | Tokens committed to stake |
| `A.8624b52f9ddcd04a.FlowIDTableStaking.RewardsPaid` | Staking rewards distributed |
| `A.8624b52f9ddcd04a.FlowIDTableStaking.NewDelegatorCreated` | New delegator registered |
| `A.f919ee77447b7497.FlowFees.FeesDeducted` | Transaction fees paid |
| `A.f919ee77447b7497.FlowFees.TokensDeposited` | Fees deposited to fee vault |

---

## Available Script Libraries

For more complex queries, clone these repos to `/tmp` and use their scripts directly:

| Repo | Scripts Path | Use For |
|---|---|---|
| [flow-core-contracts](https://github.com/onflow/flow-core-contracts) | `transactions/*/scripts/` | Staking, epoch, fees, locked tokens, version beacon, random beacon |
| [flow-ft](https://github.com/onflow/flow-ft) | `transactions/scripts/`, `transactions/metadata/scripts/` | FT balances, supply, metadata, switchboard |
| [flow-nft](https://github.com/onflow/flow-nft) | `transactions/scripts/` | NFT collections, metadata views, cross-VM views |
| [flow-evm-bridge](https://github.com/onflow/flow-evm-bridge) | `cadence/scripts/` | Bridge state, onboarding checks, escrow, EVM balances, cross-VM associations |
| [nft-storefront](https://github.com/onflow/nft-storefront) | `scripts/` | Marketplace listings, ghost listings, commission receivers, storefront IDs |
| [hybrid-custody](https://github.com/onflow/hybrid-custody) | `scripts/hybrid-custody/`, `scripts/delegator/`, `scripts/factory/` | Child/parent account relationships, cross-account NFT/FT access, capability delegation |

```bash
# Example: use an existing script from flow-core-contracts
git clone --depth 1 https://github.com/onflow/flow-core-contracts.git /tmp/flow-core-contracts
flow scripts execute /tmp/flow-core-contracts/transactions/idTableStaking/scripts/get_node_info.cdc "abc123...def456" --network mainnet
```

Note: Some repo scripts use `import "ContractName"` syntax (no address). These require a `flow.json` with address mappings. For ad-hoc queries, replace with explicit addresses:
```cadence
// Repo style (requires flow.json aliases):
import "FlowToken"
// Direct style (works without flow.json):
import FlowToken from 0x1654653399040a61
```
Loading
Loading