gRPCurl
grpcurl is like curl
but for gRPC. It is also available as a Go library, but we will use it only as a CLI command for debugging and testing purposes. Follow the instructions in the previous link to install it.
Assuming you already installed sentinelhub, you should be able to run the following command to list the Protobuf services available (you can replace grpc.sentinel.co:9090
by the gRPC server endpoint of another node such as another provider or your own node).
Listing all the methods from the mainnet
grpcurl -plaintext grpc.sentinel.co:9090 list
Output will look like:
cosmos.auth.v1beta1.Query
cosmos.authz.v1beta1.Query
cosmos.bank.v1beta1.Query
cosmos.base.reflection.v1beta1.ReflectionService
cosmos.base.reflection.v2alpha1.ReflectionService
cosmos.base.tendermint.v1beta1.Service
cosmos.distribution.v1beta1.Query
cosmos.evidence.v1beta1.Query
cosmos.feegrant.v1beta1.Query
cosmos.gov.v1beta1.Query
cosmos.mint.v1beta1.Query
cosmos.params.v1beta1.Query
cosmos.slashing.v1beta1.Query
cosmos.staking.v1beta1.Query
cosmos.tx.v1beta1.Service
cosmos.upgrade.v1beta1.Query
cosmwasm.wasm.v1.Query
grpc.reflection.v1alpha.ServerReflection
ibc.applications.fee.v1.Query
ibc.applications.interchain_accounts.controller.v1.Query
ibc.applications.interchain_accounts.host.v1.Query
ibc.applications.transfer.v1.Query
ibc.core.channel.v1.Query
ibc.core.client.v1.Query
ibc.core.connection.v1.Query
sentinel.deposit.v1.QueryService
sentinel.node.v2.QueryService
sentinel.plan.v2.QueryService
sentinel.provider.v2.QueryService
sentinel.session.v2.QueryService
sentinel.subscription.v2.QueryService
sentinel.swap.v1.QueryService
You should see a list of gRPC services, such as cosmos.bank.v1beta1.Query
. This is called reflection, which is a Protobuf endpoint returning a description of all available endpoints. Each of these represents a different Protobuf service, and each service exposes multiple RPC methods you can query against.
In order to get a description of the service you can run the following command:
grpcurl -plaintext \
grpc.sentinel.co:9090 \
describe <grpc_service>
The methods for every gRPC service are the followings:
sentinel.deposit.v1.QueryService
These are the methods of sentinel.deposit.v1.QueryService
service QueryService {
rpc QueryDeposit ( .sentinel.deposit.v1.QueryDepositRequest ) returns ( .sentinel.deposit.v1.QueryDepositResponse ) {
option (.google.api.http) = { get: "/sentinel/deposits/{address}" };
}
rpc QueryDeposits ( .sentinel.deposit.v1.QueryDepositsRequest ) returns ( .sentinel.deposit.v1.QueryDepositsResponse ) {
option (.google.api.http) = { get: "/sentinel/deposits" };
}
}
sentinel.node.v2.QueryService
These are the methods of sentinel.node.v2.QueryService
service QueryService {
rpc QueryNode ( .sentinel.node.v2.QueryNodeRequest ) returns ( .sentinel.node.v2.QueryNodeResponse ) {
option (.google.api.http) = { get: "/sentinel/nodes/{address}" };
}
rpc QueryNodes ( .sentinel.node.v2.QueryNodesRequest ) returns ( .sentinel.node.v2.QueryNodesResponse ) {
option (.google.api.http) = { get: "/sentinel/nodes" };
}
rpc QueryNodesForPlan ( .sentinel.node.v2.QueryNodesForPlanRequest ) returns ( .sentinel.node.v2.QueryNodesForPlanResponse ) {
option (.google.api.http) = { get: "/sentinel/plans/{id}/nodes" };
}
rpc QueryParams ( .sentinel.node.v2.QueryParamsRequest ) returns ( .sentinel.node.v2.QueryParamsResponse ) {
option (.google.api.http) = { get: "/sentinel/modules/node/params" };
}
}
sentinel.plan.v2.QueryService
These are the methods of sentinel.plan.v2.QueryService
service QueryService {
rpc QueryPlan ( .sentinel.plan.v2.QueryPlanRequest ) returns ( .sentinel.plan.v2.QueryPlanResponse ) {
option (.google.api.http) = { get: "/sentinel/plans/{id}" };
}
rpc QueryPlans ( .sentinel.plan.v2.QueryPlansRequest ) returns ( .sentinel.plan.v2.QueryPlansResponse ) {
option (.google.api.http) = { get: "/sentinel/plans" };
}
rpc QueryPlansForProvider ( .sentinel.plan.v2.QueryPlansForProviderRequest ) returns ( .sentinel.plan.v2.QueryPlansForProviderResponse ) {
option (.google.api.http) = { get: "/sentinel/providers/{address}/plans" };
}
}
sentinel.sentinel.provider.v2.QueryService
These are the methods of sentinel.provider.v2.QueryService
service QueryService {
rpc QueryParams ( .sentinel.provider.v2.QueryParamsRequest ) returns ( .sentinel.provider.v2.QueryParamsResponse ) {
option (.google.api.http) = { get: "/sentinel/params/provider" };
}
rpc QueryProvider ( .sentinel.provider.v2.QueryProviderRequest ) returns ( .sentinel.provider.v2.QueryProviderResponse ) {
option (.google.api.http) = { get: "/sentinel/providers/{address}" };
}
rpc QueryProviders ( .sentinel.provider.v2.QueryProvidersRequest ) returns ( .sentinel.provider.v2.QueryProvidersResponse ) {
option (.google.api.http) = { get: "/sentinel/providers" };
}
}
sentinel.session.v2.QueryService
These are the methods of sentinel.session.v2.QueryService
service QueryService {
rpc QueryParams ( .sentinel.session.v2.QueryParamsRequest ) returns ( .sentinel.session.v2.QueryParamsResponse ) {
option (.google.api.http) = { get: "/sentinel/modules/session/params" };
}
rpc QuerySession ( .sentinel.session.v2.QuerySessionRequest ) returns ( .sentinel.session.v2.QuerySessionResponse ) {
option (.google.api.http) = { get: "/sentinel/sessions/{id}" };
}
rpc QuerySessions ( .sentinel.session.v2.QuerySessionsRequest ) returns ( .sentinel.session.v2.QuerySessionsResponse ) {
option (.google.api.http) = { get: "/sentinel/sessions" };
}
rpc QuerySessionsForAccount ( .sentinel.session.v2.QuerySessionsForAccountRequest ) returns ( .sentinel.session.v2.QuerySessionsForAccountResponse ) {
option (.google.api.http) = { get: "/sentinel/accounts/{address}/sessions" };
}
rpc QuerySessionsForAllocation ( .sentinel.session.v2.QuerySessionsForAllocationRequest ) returns ( .sentinel.session.v2.QuerySessionsForAllocationResponse ) {
option (.google.api.http) = {
get: "/sentinel/subscriptions/{id}/allocations/{address}/sessions"
};
}
rpc QuerySessionsForNode ( .sentinel.session.v2.QuerySessionsForNodeRequest ) returns ( .sentinel.session.v2.QuerySessionsForNodeResponse ) {
option (.google.api.http) = { get: "/sentinel/nodes/{address}/sessions" };
}
rpc QuerySessionsForSubscription ( .sentinel.session.v2.QuerySessionsForSubscriptionRequest ) returns ( .sentinel.session.v2.QuerySessionsForSubscriptionResponse ) {
option (.google.api.http) = { get: "/sentinel/subscriptions/{id}/sessions" };
}
}
sentinel.subscription.v2.QueryService
These are the methods of sentinel.subscription.v2.QueryService
service QueryService {
rpc QueryAllocation ( .sentinel.subscription.v2.QueryAllocationRequest ) returns ( .sentinel.subscription.v2.QueryAllocationResponse ) {
option (.google.api.http) = {
get: "/sentinel/subscriptions/{id}/allocations/{address}"
};
}
rpc QueryAllocations ( .sentinel.subscription.v2.QueryAllocationsRequest ) returns ( .sentinel.subscription.v2.QueryAllocationsResponse ) {
option (.google.api.http) = {
get: "/sentinel/subscriptions/{id}/allocations"
};
}
rpc QueryParams ( .sentinel.subscription.v2.QueryParamsRequest ) returns ( .sentinel.subscription.v2.QueryParamsResponse ) {
option (.google.api.http) = { get: "/sentinel/modules/subscription/params" };
}
rpc QueryPayout ( .sentinel.subscription.v2.QueryPayoutRequest ) returns ( .sentinel.subscription.v2.QueryPayoutResponse ) {
option (.google.api.http) = { get: "/sentinel/payouts/{id}" };
}
rpc QueryPayouts ( .sentinel.subscription.v2.QueryPayoutsRequest ) returns ( .sentinel.subscription.v2.QueryPayoutsResponse ) {
option (.google.api.http) = { get: "/sentinel/payouts" };
}
rpc QueryPayoutsForAccount ( .sentinel.subscription.v2.QueryPayoutsForAccountRequest ) returns ( .sentinel.subscription.v2.QueryPayoutsForAccountResponse ) {
option (.google.api.http) = { get: "/sentinel/accounts/{address}/payouts" };
}
rpc QueryPayoutsForNode ( .sentinel.subscription.v2.QueryPayoutsForNodeRequest ) returns ( .sentinel.subscription.v2.QueryPayoutsForNodeResponse ) {
option (.google.api.http) = { get: "/sentinel/nodes/{address}/payouts" };
}
rpc QuerySubscription ( .sentinel.subscription.v2.QuerySubscriptionRequest ) returns ( .sentinel.subscription.v2.QuerySubscriptionResponse ) {
option (.google.api.http) = { get: "/sentinel/subscriptions/{id}" };
}
rpc QuerySubscriptions ( .sentinel.subscription.v2.QuerySubscriptionsRequest ) returns ( .sentinel.subscription.v2.QuerySubscriptionsResponse ) {
option (.google.api.http) = { get: "/sentinel/subscriptions" };
}
rpc QuerySubscriptionsForAccount ( .sentinel.subscription.v2.QuerySubscriptionsForAccountRequest ) returns ( .sentinel.subscription.v2.QuerySubscriptionsForAccountResponse ) {
option (.google.api.http) = {
get: "/sentinel/accounts/{address}/subscriptions"
};
}
rpc QuerySubscriptionsForNode ( .sentinel.subscription.v2.QuerySubscriptionsForNodeRequest ) returns ( .sentinel.subscription.v2.QuerySubscriptionsForNodeResponse ) {
option (.google.api.http) = { get: "/sentinel/nodes/{address}/subscriptions" };
}
rpc QuerySubscriptionsForPlan ( .sentinel.subscription.v2.QuerySubscriptionsForPlanRequest ) returns ( .sentinel.subscription.v2.QuerySubscriptionsForPlanResponse ) {
option (.google.api.http) = { get: "/sentinel/plans/{id}/subscriptions" };
}
}
sentinel.swap.v1.QueryService
These are the methods of sentinel.swap.v1.QueryService
service QueryService {
rpc QueryParams ( .sentinel.swap.v1.QueryParamsRequest ) returns ( .sentinel.swap.v1.QueryParamsResponse ) {
option (.google.api.http) = { get: "/sentinel/modules/swap/params" };
}
rpc QuerySwap ( .sentinel.swap.v1.QuerySwapRequest ) returns ( .sentinel.swap.v1.QuerySwapResponse ) {
option (.google.api.http) = { get: "/sentinel/swaps/{tx_hash}" };
}
rpc QuerySwaps ( .sentinel.swap.v1.QuerySwapsRequest ) returns ( .sentinel.swap.v1.QuerySwapsResponse ) {
option (.google.api.http) = { get: "/sentinel/swaps" };
}
}
The list of all available gRPC query endpoints and API exploration is possible with the help of buf studio.
Query for historical state using grpcurl
You may also query for historical data by passing some gRPC metadata to the query: the x-cosmos-block-height
metadata should contain the block to query. Using grpcurl as above, the command looks like:
grpcurl \
-plaintext \
-H "x-sentinel-block-height: 13000000" \
-d '{"address":"sent1uddk4mfqq3uyu2yzhym8spheqatqs30fzh5tmr"}' \
grpc.sentinel.co:9090 \
cosmos.bank.v1beta1.Query/AllBalances
Assuming the state at that block has not yet been pruned by the node, this query should return a non-empty response.