--- tags: Technical specification order: 4 --- # Interacting with the BandChain There are multiple ways to interact with a BandChain node: using the CLI, using gRPC or using the REST endpoints. The general use case on cosmos-sdk has been described in [here](https://docs.cosmos.network/v0.42/run-node/interact-node.html) ## Using CLI There are 3 common use cases to interact with BandChain via CLI ### 1. Key management for sending a transaction ```sh bandd keys add requester --keyring-backend test # Put the generated address in a variable for later use. REQUESTER=$(bandd keys show requester -a --keyring-backend test) ``` The command above creates a local key-pair that has not yet been registered on the chain. An account is created on-chain the first time when token is received from another account. ### 2. Build a message, sign, and send transaction to node Before using the requester account to send a new transaction, you need to send some tokens to it. In testnet, we provided faucet to get test Band token. This is an example how to send request transaction to Laozi BandChain testnet 2. ```sh= bandd tx oracle request 37 1 1 \ -c '00000002000000034254430000000345544800000000000f4240' \ --from requester \ --keyring-backend test \ --node tcp://rpc-laozi-testnet2.bandchain.org:26657 \ --chain-id band-laozi-testnet2 \ --gas 1000000 ``` ### 3. Query current state from BandChain You should see the detail of request with request id. ```sh bandd query oracle request 1 ``` ## Using gRPC We follow Cosmos SDK standard on how to create the new module by defining messages and queries on our oracle module using Protobuf, write a service on gRPC That allows building client library on various languages. The definition of our Protobuf messages can be found [here](https://github.com/bandprotocol/chain/tree/master/proto/oracle/v1) Since the code generation library largely depends on your own tech stack, we will only present two recommended alternatives: ### 1. Programmatically via Go Since BandChain is imeplemented in Go, type definition of protobuf messages can be imported from BandChain repository directly for querying data. The implementation is quite simple and easy to use as shown below. ```go= package main import ( "context" "fmt" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "google.golang.org/grpc" "google.golang.org/grpc/metadata" oracletypes "github.com/bandprotocol/chain/v2/x/oracle/types" ) // queryRequest queries an oracle request from BandChain Laozi testnet #2 via gRPC func queryRequest(requestID int64) (*oracletypes.QueryRequestResponse, string, error) { // Create a gRPC client grpcConn, err := grpc.Dial( "rpc-laozi-testnet2.bandchain.org:9090", grpc.WithInsecure(), // Cosmos SDK doesn't support secured communication ) if err != nil { return nil, "", err } defer grpcConn.Close() // Query an oracle request var responseHeader metadata.MD oracleClient := oracletypes.NewQueryClient(grpcConn) oracleRes, err := oracleClient.Request( metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, "100000"), // or context.Background() for querying latest block &oracletypes.QueryRequestRequest{ RequestId: requestID, }, grpc.Header(&responseHeader), // Optional, for getting block height ) if err != nil { return nil, "", err } blockHeight := responseHeader.Get(grpctypes.GRPCBlockHeightHeader) return oracleRes, blockHeight[0], nil } func main() { response, blockHeight, err := queryRequest(3) if err != nil { fmt.Println("ERR:", err) return } fmt.Printf("Request: %+v, Height: %v\n", response, blockHeight) } ``` The example above uses `NewQueryClient` in `oracle` module to create new gRPC client. Then, use `Request()` method to query oracle request from BandChain. In order to import `github.com/bandprotocol/chain/v2` package, a dependency need to be replaced, so following line should be added to `go.mod` ``` replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 ``` ### 2. Pyband and bandchain.js. - **Pyband** using [grpcio](https://pypi.org/project/grpcio/) library to generate messages, data types and stub for query data to BandChain node that serve as GRPC server. We also implemented a new `Client` class that make developer can used it simple and same interface on Guanyu version. - **Bandchain.js** has been designed to be used on both browser and node.js, which does not directly connected to GRPC server due to gRPC-web standard, so we have been setup gRPC-web proxy to parse HTTP request to gRPC server instead. The more detail on client-side library will be found this section [link](TODO: add link) ## Using the REST endpoint All gRPC services on the BandChain are made available for more convenient REST-based queries through gRPC-gateway. This allow querying data from BandChain via HTTP requests, but URL path of each endpoint has been changed compared to BandChain GuanYu due to new standard of Cosmos SDK Stargate. As a concrete example, the curl command to query oracle requests is as follow: ```sh curl \ -X GET \ -H "Content-Type: application/json" \ https://laozi-testnet2.bandchain.org/oracle/v1/requests/30 ``` In order to query historical data, adding a header named `X-Cosmos-Block-Height` to the request to specify block height to be queried. ```sh curl \ -X GET \ -H "Content-Type: application/json" \ -H "X-Cosmos-Block-Height: 100000" \ https://laozi-testnet2.bandchain.org/oracle/v1/counts ``` Inside responses, there is a header named `grpc-metadata-x-cosmos-block-height` indicating current block height of the queried data. The examples above uses public REST endpoint of our Laozi testnet #2, so feel free to replace the REST endpoint with the endpoint of your desired BandChain node.