# 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" }, ] } } ~~~