# Subgraph on local graph node with firehose for cosmos
## Firehose-cosmos
Check [Syncing docs](https://firehose.streamingfast.io/operate/guides/cosmos/syncing/) for more details.
> This fork has added some config to the `bootstrap.sh` to launch a new localnet with a single validator and 2 accounts.
### Install
```bash=
git clone https://github.com/angelorc/firehose-cosmos.git
cd firehose-cosmos && make install
```
### Bootstrap `cosmoshub4` localnet
```bash=
./devel/cosmoshub4/bootstrap.sh
```
~~~md
Using LOCALNET
Setting up working directory
~/IdeaProjects/work/subgraph/firehose-cosmos/tmp ~/IdeaProjects/work/subgraph/firehose-cosmos
Your platform is Darwin/arm64
Downloading gaiad v7.0.0 binary
Configuring home directory
Adding genesis accounts...
- name: validator
type: local
address: cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v
pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AvzwBOriY8sVwEXrXf1gXanhT9imlfWeUWLQ8pMxrRsg"}'
mnemonic: ""
- name: user1
type: local
address: cosmos1mzgucqnfr2l8cj5apvdpllhzt4zeuh2cshz5xu
pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AuXpdpSX+8fH7lerOczty2EgGFd9MMoJADPcZ7pdaLir"}'
mnemonic: ""
- name: user2
type: local
address: cosmos185fflsvwrz0cx46w6qada7mdy92m6kx4gqx0ny
pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AuFUt9g9uckLNgVlO7BCzqUCOL8OUg+zIgeHTxxeG4Fy"}'
mnemonic: ""
Creating and collecting gentx...
Genesis transaction written to "gaia_home/config/gentx/gentx-d5e8d1147ba231bbe18f6d43acf52c885062ef8e.json"
{"app_message":{"auth":{"accounts":[{"@type":"/cosmos.auth.v1beta1.BaseAccount","account_number":"0","address":"cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v","pub_key":null,"sequence":"0"},{"@type":"/cosmos.auth.v1beta1.BaseAccount","account_number":"0","address":"cosmos1mzgucqnfr2l8cj5apvdpllhzt4zeuh2cshz5xu","pub_key":null,"sequence":"0"},{"@type":"/cosmos.auth.v1beta1.BaseAccount","account_number":"0","address":"cosmos185fflsvwrz0cx46w6qada7mdy92m6kx4gqx0ny","pub_key":null,"sequence":"0"}],"params":{"max_memo_characters":"256","sig_verify_cost_ed25519":"590","sig_verify_cost_secp256k1":"1000","tx_sig_limit":"7","tx_size_cost_per_byte":"10"}},"authz":{"authorization":[]},"bank":{"balances":[{"address":"cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v","coins":[{"amount":"1000000000000000","denom":"stake"}]},{"address":"cosmos185fflsvwrz0cx46w6qada7mdy92m6kx4gqx0ny","coins":[{"amount":"1000000000000000","denom":"stake"}]},{"address":"cosmos1mzgucqnfr2l8cj5apvdpllhzt4zeuh2cshz5xu","coins":[{"amount":"1000000000000000","denom":"stake"}]}],"denom_metadata":[],"params":{"default_send_enabled":true,"send_enabled":[]},"supply":[{"amount":"3000000000000000","denom":"stake"}]},"capability":{"index":"1","owners":[]},"crisis":{"constant_fee":{"amount":"1000","denom":"stake"}},"distribution":{"delegator_starting_infos":[],"delegator_withdraw_infos":[],"fee_pool":{"community_pool":[]},"outstanding_rewards":[],"params":{"base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","community_tax":"0.020000000000000000","withdraw_addr_enabled":true},"previous_proposer":"","validator_accumulated_commissions":[],"validator_current_rewards":[],"validator_historical_rewards":[],"validator_slash_events":[]},"evidence":{"evidence":[]},"feegrant":{"allowances":[]},"genutil":{"gen_txs":[{"auth_info":{"fee":{"amount":[],"gas_limit":"200000","granter":"","payer":""},"signer_infos":[{"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AvzwBOriY8sVwEXrXf1gXanhT9imlfWeUWLQ8pMxrRsg"},"sequence":"0"}]},"body":{"extension_options":[],"memo":"d5e8d1147ba231bbe18f6d43acf52c885062ef8e@10.128.10.28:26656","messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","commission":{"max_change_rate":"0.010000000000000000","max_rate":"0.200000000000000000","rate":"0.100000000000000000"},"delegator_address":"cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v","description":{"details":"","identity":"","moniker":"Nabaruns-MacBook-Pro.local","security_contact":"","website":""},"min_self_delegation":"1","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"a2yoVTs57qTgbIWHuEPORchabRICD3q6csl2qSS92Wg="},"validator_address":"cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl","value":{"amount":"1000000000","denom":"stake"}}],"non_critical_extension_options":[],"timeout_height":"0"},"signatures":["p6jXWuzkhx9ihWTp6ZoDA/+sXEaMnm4wEL7/tWSmJh8dlFjy8J4+HIhaIg+QFiGiQPXZDgWv0LD6NPxDCvliAg=="]}]},"gov":{"deposit_params":{"max_deposit_period":"172800s","min_deposit":[{"amount":"10000000","denom":"stake"}]},"deposits":[],"proposals":[],"starting_proposal_id":"1","tally_params":{"quorum":"0.334000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"},"votes":[],"voting_params":{"voting_period":"172800s"}},"ibc":{"channel_genesis":{"ack_sequences":[],"acknowledgements":[],"channels":[],"commitments":[],"next_channel_sequence":"0","receipts":[],"recv_sequences":[],"send_sequences":[]},"client_genesis":{"clients":[],"clients_consensus":[],"clients_metadata":[],"create_localhost":false,"next_client_sequence":"0","params":{"allowed_clients":["06-solomachine","07-tendermint"]}},"connection_genesis":{"client_connection_paths":[],"connections":[],"next_connection_sequence":"0","params":{"max_expected_time_per_block":"30000000000"}}},"interchainaccounts":{"controller_genesis_state":{"active_channels":[],"interchain_accounts":[],"params":{"controller_enabled":true},"ports":[]},"host_genesis_state":{"active_channels":[],"interchain_accounts":[],"params":{"allow_messages":[],"host_enabled":true},"port":"icahost"}},"liquidity":{"params":{"circuit_breaker_enabled":false,"init_pool_coin_mint_amount":"1000000","max_order_amount_ratio":"0.100000000000000000","max_reserve_coin_amount":"0","min_init_deposit_amount":"1000000","pool_creation_fee":[{"amount":"40000000","denom":"stake"}],"pool_types":[{"description":"Standard liquidity pool with pool price function X/Y, ESPM constraint, and two kinds of reserve coins","id":1,"max_reserve_coin_num":2,"min_reserve_coin_num":2,"name":"StandardLiquidityPool"}],"swap_fee_rate":"0.003000000000000000","unit_batch_height":1,"withdraw_fee_rate":"0.000000000000000000"},"pool_records":[]},"mint":{"minter":{"annual_provisions":"0.000000000000000000","inflation":"0.130000000000000000"},"params":{"blocks_per_year":"6311520","goal_bonded":"0.670000000000000000","inflation_max":"0.200000000000000000","inflation_min":"0.070000000000000000","inflation_rate_change":"0.130000000000000000","mint_denom":"stake"}},"packetfowardmiddleware":{"params":{"fee_percentage":"0.000000000000000000"}},"params":null,"slashing":{"missed_blocks":[],"params":{"downtime_jail_duration":"600s","min_signed_per_window":"0.500000000000000000","signed_blocks_window":"100","slash_fraction_double_sign":"0.050000000000000000","slash_fraction_downtime":"0.010000000000000000"},"signing_infos":[]},"staking":{"delegations":[],"exported":false,"last_total_power":"0","last_validator_powers":[],"params":{"bond_denom":"stake","historical_entries":10000,"max_entries":7,"max_validators":100,"unbonding_time":"1814400s"},"redelegations":[],"unbonding_delegations":[],"validators":[]},"transfer":{"denom_traces":[],"params":{"receive_enabled":true,"send_enabled":true},"port_id":"transfer"},"upgrade":{},"vesting":{}},"chain_id":"localnet","gentxs_dir":"gaia_home/config/gentx","moniker":"Nabaruns-MacBook-Pro.local","node_id":"d5e8d1147ba231bbe18f6d43acf52c885062ef8e"}
~~~
### Start `cosmoshub4` localnet
```bash=
./devel/cosmoshub4/start.sh
```
### Check streaming blocks with:
```bash=
grpcurl -plaintext localhost:9030 sf.firehose.v1.Stream.Blocks | jq
```
## Graph-Node setup
For reference, check [Running a Local Graph Node](https://github.com/graphprotocol/graph-node#running-a-local-graph-node).
## Postgres
### Install
```bash=
brew install postgresql
brew start service postgresql
```
### Createdb
```bash=
createdb graph-node
```
### Dropdb
only when necessary
```
psql -U nabarunsarkar -d postgres
DROP DATABASE graphnode;
\q
```
## IPFS
### Install
after installing ipfs
```bash=
ipfs init
```
### Start
```bash=
ipfs daemon
```
~~~md
Initializing daemon...
go-ipfs version: 0.13.1
Repo version: 12
System version: arm64/darwin
Golang version: go1.18.3
Swarm listening on /ip4/10.128.10.28/tcp/4001
Swarm listening on /ip4/10.128.10.28/udp/4001/quic
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/127.0.0.1/udp/4001/quic
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /ip6/::1/udp/4001/quic
Swarm listening on /p2p-circuit
Swarm announcing /ip4/10.128.10.28/tcp/4001
Swarm announcing /ip4/10.128.10.28/udp/4001/quic
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip4/127.0.0.1/udp/4001/quic
Swarm announcing /ip4/5.32.126.2/tcp/4001
Swarm announcing /ip4/5.32.126.2/udp/4001/quic
Swarm announcing /ip6/::1/tcp/4001
Swarm announcing /ip6/::1/udp/4001/quic
API server listening on /ip4/127.0.0.1/tcp/5001
WebUI: http://127.0.0.1:5001/webui
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready
~~~
## Rust
### Install
Make sure Rust is installed.
## Start Graph-Node
### Install
```bash=
git clone https://github.com/graphprotocol/graph-node.git
cd graph-node
```
### Config
Create `config.toml` and add following lines
```bash=
[deployment]
[[deployment.rule]]
shard = "primary"
indexers = [ "index_node_cosmos_1" ]
[store]
[store.primary]
connection = "postgresql://nabarunsarkar:[PASSWORD]@localhost:5432/graph-node"
pool_size = 10
[chains]
ingestor = "block_ingestor_node"
[chains.localnet]
shard = "primary"
protocol = "cosmos"
provider = [
{ label = "localnet", details = { type = "firehose", url = "http://0.0.0.0:9030/" }},
]
```
### Start
```bash=
cargo +nightly run -p graph-node --release -- \
--config config.toml \
--ipfs 127.0.0.1:5001 \
--node-id index_node_cosmos_1
```
~~~md
Running `target/release/graph-node --config config.toml --ipfs '127.0.0.1:5001' --node-id index_node_cosmos_1`
Jul 21 12:40:10.500 INFO Graph Node version: 0.26.0 :: hosted-current+106 (a66caafe0 2022-07-12) dirty 3 modifications
Jul 21 12:40:10.501 WARN GRAPH_POI_ACCESS_TOKEN not set; might leak POIs to the public via GraphQL
Jul 21 12:40:10.501 INFO Reading configuration file `config.toml`
Jul 21 12:40:10.502 WARN No fork base URL specified, subgraph forking is disabled
Jul 21 12:40:10.502 INFO Starting up
Jul 21 12:40:10.502 INFO Trying IPFS node at: http://127.0.0.1:5001/
Jul 21 12:40:10.504 INFO Creating firehose endpoint, url: http://0.0.0.0:9030/, provider: localnet
Jul 21 12:40:10.505 INFO Successfully connected to IPFS node at: http://127.0.0.1:5001/
Jul 21 12:40:10.558 INFO Connecting to Postgres, weight: 1, conn_pool_size: 10, url: postgresql://nabarunsarkar:HIDDEN_PASSWORD@localhost:5432/graph-node, pool: main, shard: primary
Jul 21 12:40:10.558 INFO Pool successfully connected to Postgres, pool: main, shard: primary, component: Store
Jul 21 12:40:10.606 INFO Setting up fdw, pool: main, shard: primary, component: ConnectionPool
Jul 21 12:40:10.633 INFO Running migrations, pool: main, shard: primary, component: ConnectionPool
Jul 21 12:40:10.900 INFO Migrations finished, pool: main, shard: primary, component: ConnectionPool
Jul 21 12:40:10.902 INFO Mapping primary, pool: main, shard: primary, component: ConnectionPool
Jul 21 12:40:10.947 INFO Connecting to Firehose to get chain identifier, url: http://0.0.0.0:9030/, provider: localnet
Jul 21 12:40:10.947 INFO Requesting genesis block from firehose, provider: localnet
Jul 21 12:40:10.955 INFO Connected to Firehose, genesis_block: #1 (9090703dce907d57b2915d29077962652cdfd445c6286e48d2838155392b5c7d), uri: http://0.0.0.0:9030/, provider: localnet
Jul 21 12:40:11.451 INFO Creating LoadManager in disabled mode, component: LoadManager
Jul 21 12:40:11.451 INFO Starting firehose block ingestors with 0 chains []
Jul 21 12:40:11.451 INFO Starting firehose block ingestors with 0 chains []
Jul 21 12:40:11.451 INFO Starting firehose block ingestors with 1 chains [localnet]
Jul 21 12:40:11.451 INFO Starting firehose block ingestor for network, network_name: localnet
Jul 21 12:40:11.455 INFO Starting job runner with 4 jobs, component: JobRunner
Jul 21 12:40:11.457 INFO Starting JSON-RPC admin server at: http://localhost:8020, component: JsonRpcServer
Jul 21 12:40:11.458 INFO Starting GraphQL HTTP server at: http://localhost:8000, component: GraphQLServer
Jul 21 12:40:11.458 INFO Starting index node server at: http://localhost:8030, component: IndexNodeServer
Jul 21 12:40:11.458 INFO Starting metrics server at: http://localhost:8040, component: MetricsServer
Jul 21 12:40:11.458 INFO Starting GraphQL WebSocket server at: ws://localhost:8001, component: SubscriptionServer
Jul 21 12:40:11.458 INFO Blockstream disconnected, connecting, cursor: , endpoint uri: http://0.0.0.0:9030/, provider: localnet, component: FirehoseBlockIngestor
Jul 21 12:40:11.459 INFO Started all assigned subgraphs, node_id: index_node_cosmos_1, count: 0, component: SubgraphRegistrar
~~~
## Subgraph example
### Clone
```bash=
git clone https://github.com/angelorc/example-subgraph.git
cd example-subgraph && git checkout cosmos-validator-rewards
```
For using on localnet, `config/cosmoshub.json` is modified as
```json
- "network": "cosmoshub-4"
+ "network": "localnet"
```
### Prepare and generate schema
```
yarn install && yarn prepare:cosmoshub
yarn codegen && yarn build
```
~~~md
yarn install v1.22.19
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
✨ Done in 2.25s.
yarn run v1.22.19
$ mustache config/cosmoshub.json subgraph.template.yaml > subgraph.yaml
✨ Done in 0.85s.
yarn run v1.22.19
$ graph codegen
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
Skip migration: Bump mapping apiVersion from 0.0.5 to 0.0.6
Skip migration: Bump mapping apiVersion from 0.0.6 to 0.0.7
Skip migration: Bump manifest specVersion from 0.0.1 to 0.0.2
Skip migration: Bump manifest specVersion from 0.0.2 to 0.0.4
Skip migration: Bump manifest specVersion from 0.0.4 to 0.0.5
✔ Apply migrations
⚠ Warnings while loading subgraph from subgraph.yaml: Warnings in subgraph.yaml:
Path: repository
The repository is still set to https://github.com/graphprotocol/example-subgraph.
Please replace it with a link to your subgraph source code.
✔ Load subgraph from subgraph.yaml
✔ Generate types for data source templates
✔ Load GraphQL schema from schema.graphql
Write types to generated/schema.ts
✔ Generate types for GraphQL schema
Types generated successfully
✨ Done in 1.40s.
yarn run v1.22.19
$ graph build
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
Skip migration: Bump mapping apiVersion from 0.0.5 to 0.0.6
Skip migration: Bump mapping apiVersion from 0.0.6 to 0.0.7
Skip migration: Bump manifest specVersion from 0.0.1 to 0.0.2
Skip migration: Bump manifest specVersion from 0.0.2 to 0.0.4
Skip migration: Bump manifest specVersion from 0.0.4 to 0.0.5
✔ Apply migrations
⚠ Warnings loading subgraph from subgraph.yaml: Warnings in subgraph.yaml:
Path: repository
The repository is still set to https://github.com/graphprotocol/example-subgraph.
Please replace it with a link to your subgraph source code.
✔ Load subgraph from subgraph.yaml
Compile data source: CosmosHub => build/CosmosHub/CosmosHub.wasm
✔ Compile subgraph
Copy schema file build/schema.graphql
Write subgraph manifest build/subgraph.yaml
✔ Write compiled subgraph to build/
Build completed: /Users/nabarunsarkar/IdeaProjects/work/subgraph/example-subgraph/build/subgraph.yaml
✨ Done in 3.68s.
~~~
### Deploy
```
yarn create-local && yarn deploy-local
```
~~~md
yarn run v1.22.19
$ graph create cosmos-validator-rewards --node http://localhost:8020
Created subgraph: cosmos-validator-rewards
✨ Done in 2.23s.
yarn run v1.22.19
$ graph deploy cosmos-validator-rewards -l v0.1.0 --ipfs http://localhost:5001 --node http://localhost:8020
Skip migration: Bump mapping apiVersion from 0.0.1 to 0.0.2
Skip migration: Bump mapping apiVersion from 0.0.2 to 0.0.3
Skip migration: Bump mapping apiVersion from 0.0.3 to 0.0.4
Skip migration: Bump mapping apiVersion from 0.0.4 to 0.0.5
Skip migration: Bump mapping apiVersion from 0.0.5 to 0.0.6
Skip migration: Bump mapping apiVersion from 0.0.6 to 0.0.7
Skip migration: Bump manifest specVersion from 0.0.1 to 0.0.2
Skip migration: Bump manifest specVersion from 0.0.2 to 0.0.4
Skip migration: Bump manifest specVersion from 0.0.4 to 0.0.5
✔ Apply migrations
⚠ Warnings loading subgraph from subgraph.yaml: Warnings in subgraph.yaml:
Path: repository
The repository is still set to https://github.com/graphprotocol/example-subgraph.
Please replace it with a link to your subgraph source code.
✔ Load subgraph from subgraph.yaml
Compile data source: CosmosHub => build/CosmosHub/CosmosHub.wasm
✔ Compile subgraph
Copy schema file build/schema.graphql
Write subgraph manifest build/subgraph.yaml
✔ Write compiled subgraph to build/
Add file to IPFS build/schema.graphql
.. QmYhYJM19TF5pdNAyai7VyVhAR86YYyU6nKDsxMiiVkqcq
Add file to IPFS build/CosmosHub/CosmosHub.wasm
.. QmWsjFGfho3ZHNu1Y2xSFvkH933AFH2z5n1a45LfGnZKNJ
✔ Upload subgraph to IPFS
Build completed: QmbZi8MZ8Z2umk6aJdb17JvGHy2swyDqwTPiKkQ1FF7cn3
Deployed to http://localhost:8000/subgraphs/name/cosmos-validator-rewards/graphql
Subgraph endpoints:
Queries (HTTP): http://localhost:8000/subgraphs/name/cosmos-validator-rewards
✨ Done in 3.24s.
~~~
On terminal with graph-node running, we can see following:
~~~md
Jul 21 12:41:13.743 INFO Received subgraph_create request, params: SubgraphCreateParams { name: SubgraphName("cosmos-validator-rewards") }, component: JsonRpcServer
Jul 21 12:41:24.110 INFO Received subgraph_deploy request, params: SubgraphDeployParams { name: SubgraphName("cosmos-validator-rewards"), ipfs_hash: DeploymentHash("QmbZi8MZ8Z2umk6aJdb17JvGHy2swyDqwTPiKkQ1FF7cn3"), node_id: None, debug_fork: None }, component: JsonRpcServer
Jul 21 12:41:24.111 INFO Resolve schema, link: /ipfs/QmYhYJM19TF5pdNAyai7VyVhAR86YYyU6nKDsxMiiVkqcq, sgd: 0, subgraph_id: QmbZi8MZ8Z2umk6aJdb17JvGHy2swyDqwTPiKkQ1FF7cn3, component: SubgraphRegistrar
~~~
### Remove
only in local env
```
yarn remove-local
```
## Graphql query
Open `http://localhost:8000` to access UI for graphql
>Access deployed subgraphs by deployment ID at /subgraphs/id/<ID> or by name at /subgraphs/name/<NAME>
Example: `http://localhost:8000/subgraphs/id/QmbZi8MZ8Z2umk6aJdb17JvGHy2swyDqwTPiKkQ1FF7cn3/graphql`
### Query
```bash
query {
rewards{
validator,
amount
}
}
```
~~~md
{
"data": {
"rewards": [
{
"validator": "cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl",
"amount": "57466438.170000000000000000stake"
},
{
"validator": "cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl",
"amount": "57467364.450000000000000000stake"
},
{
"validator": "cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl",
"amount": "57467374.680000000000000000stake"
},
{
"validator": "cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl",
"amount": "57467384.910000000000000000stake"
},
{
"validator": "cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl",
"amount": "57467395.140000000000000000stake"
},
{
"validator": "cosmosvaloper1zaavvzxez0elundtn32qnk9lkm8kmcsz8ycjrl",
"amount": "57467405.370000000000000000stake"
},
]
}
}
~~~