Predicate design

Create, validate, and manage Chainhook predicates.


The Chainhook CLI provides commands to create, validate, and manage predicates that define what blockchain events to monitor.

Generate predicates

Create a new predicate template for your target blockchain:

Terminal
$
chainhook predicates new my-predicate.json --stacks
[32mCreated predicate template[0m [1mmy-predicate.json[0m

Use --bitcoin for Bitcoin predicates:

Terminal
$
chainhook predicates new btc-predicate.json --bitcoin
[32mCreated predicate template[0m [1mbtc-predicate.json[0m

Validate predicates

Check your predicate syntax and configuration before deployment:

Terminal
$
chainhook predicates check my-predicate.json --mainnet
[32m✓ Valid predicate structure[0m
[32m✓ Network configuration found for mainnet[0m
[32m✓ Scope 'contract_call' is valid[0m

Common validation errors:

ErrorSolution
Invalid JSON structureCheck JSON syntax with a validator
Missing required field 'uuid'Add unique identifier to predicate
Unknown scope 'invalid_scope'Use valid scope for your blockchain
Network not configuredAdd network configuration section

List registered predicates

View all predicates registered with a running Chainhook service:

Terminal
$
chainhook predicates list
[1mRegistered predicates:[0m
1. STX_Transfer_Monitor (uuid: abc-123)
Status: Active
Network: mainnet
2. NFT_Mint_Tracker (uuid: def-456)
Status: Paused
Network: testnet

Enable/disable predicates

Control predicate execution without removing them:

Terminal
$
chainhook predicates disable abc-123
[32mPredicate 'STX_Transfer_Monitor' disabled[0m
$
chainhook predicates enable abc-123
[32mPredicate 'STX_Transfer_Monitor' enabled[0m

Remove predicates

Unregister predicates from the service:

Terminal
$
chainhook predicates remove abc-123
[33mAre you sure you want to remove 'STX_Transfer_Monitor'? (y/n)[0m y
[32mPredicate removed successfully[0m

Common patterns

Multi-network predicates

Configure predicates for multiple networks in one file:

predicate-multi-network.json
{
"chain": "stacks",
"uuid": "multi-net-123",
"name": "Multi Network Monitor",
"version": 1,
"networks": {
"mainnet": {
"if_this": {
"scope": "stx_event",
"actions": ["transfer"]
},
"then_that": {
"http_post": {
"url": "https://api.prod.example.com/webhook"
}
}
},
"testnet": {
"if_this": {
"scope": "stx_event",
"actions": ["transfer", "mint"]
},
"then_that": {
"http_post": {
"url": "https://api.test.example.com/webhook"
}
}
}
}
}

Filtered contract calls

Monitor specific contract functions:

contract-monitor.json
{
"if_this": {
"scope": "contract_call",
"contract_identifier": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-dao",
"method": "stake"
}
}

NFT activity tracking

Track all NFT operations for a collection:

nft-tracker.json
{
"if_this": {
"scope": "nft_event",
"asset_identifier": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.bitcoin-monkeys::bitcoin-monkeys",
"actions": ["mint", "transfer", "burn"]
}
}

Best practices

  1. 1Version your predicates - Increment version numbers when updating
  2. 2Use descriptive names - Make predicate purpose clear
  3. 3Test on testnet first - Validate behavior before mainnet
  4. 4Set block ranges - Limit scanning scope for performance
  5. 5Monitor predicate health - Check logs for processing errors

Next steps