Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/authz grants #5

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .project-cid

This file was deleted.

25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# SubQuery - Xion Chain Indexer



[SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network).

This project is a working example of a SubQuery project that indexes data from the Xion Chain network. It is a good starting point for you to learn how to build your own SubQuery project for Xion Chain, or to fork and customise for your own needs.

Currently, this project indexes the following contracts:

- [Smart Accounts](https://github.com/burnt-labs/contracts)
- [Hubs and seats](https://github.com/burnt-labs/burnt-cw-hubs)

Expand Down Expand Up @@ -35,12 +34,14 @@ _If you get stuck, find out how to get help below._
The simplest way to run your project is by running `yarn dev` or `npm run-script dev`. This does all of the following:

1. `yarn codegen` - Generates types from the GraphQL schema definition and contract ABIs and saves them in the `/src/types` directory. This must be done after each change to the `schema.graphql` file or the contract ABIs
2. `yarn build` - Builds and packages the SubQuery project into the `/dist` directory
3. `docker-compose pull && docker-compose up` - Runs a Docker container with an indexer, PostgeSQL DB, and a query service. This requires [Docker to be installed](https://docs.docker.com/engine/install) and running locally. The configuration for this container is set from your `docker-compose.yml`
2. `yarn generate:proto:types` - Generates types from the protobuf files and saves them in the `/src/types` directory. This must be done after each change to the `proto` files. First argument to the script is the proto file or all proto file (proto/\*_/_.proto).
3. `yarn build` - Builds and packages the SubQuery project into the `/dist` directory
4. `docker-compose pull && docker-compose up` - Runs a Docker container with an indexer, PostgeSQL DB, and a query service. This requires [Docker to be installed](https://docs.docker.com/engine/install) and running locally. The configuration for this container is set from your `docker-compose.yml`

You can observe the three services start, and once all are running (it may take a few minutes on your first start), please open your browser and head to [http://localhost:3000](http://localhost:3000) - you should see a GraphQL playground showing with the schemas ready to query. [Read the docs for more information](https://academy.subquery.network/run_publish/run.html) or [explore the possible service configuration for running SubQuery](https://academy.subquery.network/run_publish/references.html).

## Deploy contracts and update your project

1. `cp .env.example .env`
2. Fill in the `.env` file with your own values

Expand All @@ -50,17 +51,17 @@ For this project, you can try to query with the following GraphQL code to get a

```graphql
query {
smartAccounts {
smartAccounts {
nodes {
id
authenticators {
nodes {
id
authenticators {
nodes {
id
type
}
}
id
type
}
}
}
}
}
```

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "This is the indexer solution for the xion chain",
"main": "dist/index.js",
"scripts": {
"build": "subql build",
"build": "rm -rf dist && subql build",
"generate:proto:types": "rm -rf src/proto_types/* && protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=src/proto_types/ --ts_proto_opt=useDate=false --proto_path proto $1",
"build:docker": "dotenv -c docker subql build",
"codegen": "subql codegen",
"start:docker": "docker-compose pull && docker-compose up --remove-orphans",
Expand All @@ -26,7 +27,6 @@
"license": "MIT",
"devDependencies": {
"@cosmjs/stargate": "^0.28.9",
"@subql/cli": "^4.0.5",
"@subql/node-cosmos": "latest",
"@subql/testing": "latest",
"@types/uuid": "^9.0.5",
Expand All @@ -39,7 +39,7 @@
"@types/node": "^17.0.21",
"osmojs": "^15.2.1",
"pino": "^7.8.0",
"ts-proto": "^1.112.1",
"ts-proto": "^1.174.0",
"tslib": "^2.3.1",
"uuid": "^9.0.1"
}
Expand Down
97 changes: 89 additions & 8 deletions project.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import {
CosmosDatasourceKind,
CosmosHandlerKind,
CosmosProject,
CosmosProjectManifestV1_0_0,
} from "@subql/types-cosmos";

// These defaults are the testnet values
const HUB_CONTRACT_CODE_ID = process.env.HUB_CONTRACT_CODE_ID || "7";
const SMART_ACCOUNT_CONTRACT_CODE_ID =
process.env.SMART_ACCOUNT_CONTRACT_CODE_ID || "21";
process.env.SMART_ACCOUNT_CONTRACT_CODE_ID || "327";

const CHAIN_ID = process.env.CHAIN_ID || "xion-testnet-1";
const ENDPOINT_URL =
process.env.ENDPOINT_URL || "https://rpc.xion-testnet-1.burnt.com:443";
const START_BLOCK = Number(process.env.START_BLOCK || "3371922");
const START_BLOCK = Number(process.env.START_BLOCK || "7789710");

const project: CosmosProject = {
const project: CosmosProjectManifestV1_0_0 = {
specVersion: "1.0.0",
version: "1.0.0",
name: "xion-indexer",
description:
"Xion SubQuery project for account abstraction and hub/seat contracts.",
runner: {
node: {
name: "@subql/node-cosmos",
Expand All @@ -30,6 +27,10 @@ const project: CosmosProject = {
version: "*",
},
},
name: "xion-indexer",
description:
"Xion SubQuery project for account abstraction and hub/seat contracts.",
repository: "https://github.com/burnt-labs/xion-indexer",
schema: {
file: "./schema.graphql",
},
Expand All @@ -42,7 +43,7 @@ const project: CosmosProject = {
* When developing your project we suggest getting a private API key
* We suggest providing an array of endpoints for increased speed and reliability
*/
endpoint: [ENDPOINT_URL],
endpoint: ENDPOINT_URL,
chaintypes: new Map([
[
"abstractaccount.v1",
Expand All @@ -60,6 +61,79 @@ const project: CosmosProject = {
messages: ["Coin"],
},
],
[
"cosmos.feegrant.v1beta1",
{
file: "./proto/cosmos/feegrant/v1beta1/feegrant.proto",
messages: [
"Grant",
"AllowedMsgAllowance",
"BasicAllowance",
"PeriodicAllowance",
],
},
],
[
"cosmos.feegrant.tx",
{
file: "./proto/cosmos/feegrant/tx/tx.proto",
messages: ["MsgGrantAllowance", "MsgRevokeAllowance"],
},
],
[
"cosmos.authz.v1beta1",
{
file: "./proto/cosmos/authz/v1beta1/tx.proto",
messages: ["MsgGrant", "MsgRevoke"],
},
],
[
"cosmos.authz",
{
file: "./proto/cosmos/authz/authz.proto",
messages: ["Grant"],
},
],
[
"google.protobuf.any",
{
file: "./proto/google/protobuf/any/any.proto",
messages: ["Any"],
},
],
[
"google.protobuf.timestamp",
{
file: "./proto/google/protobuf/timestamp/timestamp.proto",
messages: ["Timestamp"],
},
],
[
"cosmos.authz.event",
{
file: "./proto/cosmos/authz/event/event.proto",
messages: ["EventGrant", "EventRevoke"],
},
],
[
"cosmwasm.wasm.v1",
{
file: "./proto/cosmwasm/wasm/v1/authz.proto",
messages: [
"StoreCodeAuthorization",
"ContractExecutionAuthorization",
"ContractMigrationAuthorization",
"CodeGrant",
"ContractGrant",
"MaxCallsLimit",
"MaxFundsLimit",
"CombinedLimit",
"AllowAllMessagesFilter",
"AcceptedMessageKeysFilter",
"AcceptedMessagesFilter",
],
},
],
]),
},
dataSources: [
Expand Down Expand Up @@ -157,6 +231,13 @@ const project: CosmosProject = {
},
},
},
{
handler: "handleAuthzMsgGrant",
kind: CosmosHandlerKind.Message,
filter: {
type: "/cosmos.authz.v1beta1.MsgGrant",
},
},
],
},
},
Expand Down
75 changes: 75 additions & 0 deletions proto/amino/amino.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
syntax = "proto3";

package amino;

import "google/protobuf/descriptor.proto";

extend google.protobuf.MessageOptions {
// name is the string used when registering a concrete
// type into the Amino type registry, via the Amino codec's
// `RegisterConcrete()` method. This string MUST be at most 39
// characters long, or else the message will be rejected by the
// Ledger hardware device.
string name = 11110001;

// encoding describes the encoding format used by Amino for the given
// message. The field type is chosen to be a string for
// flexibility, but it should ideally be short and expected to be
// machine-readable, for example "base64" or "utf8_json". We
// highly recommend to use underscores for word separation instead of spaces.
//
// If left empty, then the Amino encoding is expected to be the same as the
// Protobuf one.
//
// This annotation should not be confused with the `encoding`
// one which operates on the field level.
string message_encoding = 11110002;
}

extend google.protobuf.FieldOptions {
// encoding describes the encoding format used by Amino for
// the given field. The field type is chosen to be a string for
// flexibility, but it should ideally be short and expected to be
// machine-readable, for example "base64" or "utf8_json". We
// highly recommend to use underscores for word separation instead of spaces.
//
// If left empty, then the Amino encoding is expected to be the same as the
// Protobuf one.
//
// This annotation should not be confused with the
// `message_encoding` one which operates on the message level.
string encoding = 11110003;

// field_name sets a different field name (i.e. key name) in
// the amino JSON object for the given field.
//
// Example:
//
// message Foo {
// string bar = 1 [(amino.field_name) = "baz"];
// }
//
// Then the Amino encoding of Foo will be:
// `{"baz":"some value"}`
string field_name = 11110004;

// dont_omitempty sets the field in the JSON object even if
// its value is empty, i.e. equal to the Golang zero value. To learn what
// the zero values are, see https://go.dev/ref/spec#The_zero_value.
//
// Fields default to `omitempty`, which is the default behavior when this
// annotation is unset. When set to true, then the field value in the
// JSON object will be set, i.e. not `undefined`.
//
// Example:
//
// message Foo {
// string bar = 1;
// string baz = 2 [(amino.dont_omitempty) = true];
// }
//
// f := Foo{};
// out := AminoJSONEncoder(&f);
// out == {"baz":""}
bool dont_omitempty = 11110005;
}
48 changes: 48 additions & 0 deletions proto/cosmos/authz/authz.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Since: cosmos-sdk 0.43
syntax = "proto3";
package cosmos.authz;

import "amino/amino.proto";
import "cosmos_proto/cosmos.proto";
import "google/protobuf/timestamp/timestamp.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any/any.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/authz";
option (gogoproto.goproto_getters_all) = false;

// GenericAuthorization gives the grantee unrestricted permissions to execute
// the provided method on behalf of the granter's account.
message GenericAuthorization {
option (amino.name) = "cosmos-sdk/GenericAuthorization";
option (cosmos_proto.implements_interface) = "cosmos.authz.v1beta1.Authorization";

// Msg, identified by it's type URL, to grant unrestricted permissions to execute
string msg = 1;
}

// Grant gives permissions to execute
// the provide method with expiration time.
message Grant {
google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "cosmos.authz.v1beta1.Authorization"];
// time when the grant will expire and will be pruned. If null, then the grant
// doesn't have a time expiration (other conditions in `authorization`
// may apply to invalidate the grant)
google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = true];
}

// GrantAuthorization extends a grant with both the addresses of the grantee and granter.
// It is used in genesis.proto and query.proto
message GrantAuthorization {
string granter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string grantee = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];

google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "cosmos.authz.v1beta1.Authorization"];
google.protobuf.Timestamp expiration = 4 [(gogoproto.stdtime) = true];
}

// GrantQueueItem contains the list of TypeURL of a sdk.Msg.
message GrantQueueItem {
// msg_type_urls contains the list of TypeURL of a sdk.Msg.
repeated string msg_type_urls = 1;
}
27 changes: 27 additions & 0 deletions proto/cosmos/authz/event/event.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Since: cosmos-sdk 0.43
syntax = "proto3";
package cosmos.authz.event;

import "cosmos_proto/cosmos.proto";

option go_package = "github.com/cosmos/cosmos-sdk/x/authz";

// EventGrant is emitted on Msg/Grant
message EventGrant {
// Msg type URL for which an autorization is granted
string msg_type_url = 2;
// Granter account address
string granter = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Grantee account address
string grantee = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// EventRevoke is emitted on Msg/Revoke
message EventRevoke {
// Msg type URL for which an autorization is revoked
string msg_type_url = 2;
// Granter account address
string granter = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// Grantee account address
string grantee = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
Loading
Loading