├── .gitattributes
├── x
├── jwk
│ ├── types
│ │ ├── types.go
│ │ ├── errors.go
│ │ ├── keys.go
│ │ ├── key_audience.go
│ │ ├── codec.go
│ │ ├── keys_test.go
│ │ ├── genesis.go
│ │ ├── genesis_test.go
│ │ └── params.go
│ ├── keeper
│ │ ├── query.go
│ │ ├── msg_server.go
│ │ ├── query_params.go
│ │ ├── migrations.go
│ │ ├── params.go
│ │ ├── keeper.go
│ │ ├── query_audience.go
│ │ ├── vulnerability_test.go
│ │ └── audience_test.go
│ ├── migrations
│ │ └── v1
│ │ │ ├── migration.go
│ │ │ └── migration_test.go
│ ├── client
│ │ └── cli
│ │ │ ├── query_params.go
│ │ │ ├── query.go
│ │ │ ├── tx.go
│ │ │ ├── util.go
│ │ │ └── query_validate_jwt.go
│ └── genesis.go
├── globalfee
│ ├── alias.go
│ ├── types
│ │ ├── keys.go
│ │ ├── keys_test.go
│ │ ├── genesis.go
│ │ └── types_test.go
│ ├── README.md
│ ├── keeper
│ │ ├── migrations.go
│ │ └── migrations_test.go
│ ├── ante
│ │ ├── expected_keepers.go
│ │ └── ante_test.go
│ ├── client
│ │ └── cli
│ │ │ └── query.go
│ ├── migrations
│ │ └── v2
│ │ │ └── migration.go
│ ├── querier.go
│ └── querier_test.go
├── xion
│ ├── types
│ │ ├── keys.go
│ │ ├── errors.go
│ │ ├── codec_test.go
│ │ ├── errors_test.go
│ │ ├── genesis.go
│ │ ├── keys_test.go
│ │ ├── expected_keepers.go
│ │ └── codec.go
│ ├── client
│ │ └── cli
│ │ │ ├── query.go
│ │ │ ├── suite_test.go
│ │ │ ├── query_platform_fee.go
│ │ │ └── query_webauthn.go
│ └── keeper
│ │ └── genesis.go
├── mint
│ └── types
│ │ ├── keys.go
│ │ ├── msgs.go
│ │ ├── codec.go
│ │ ├── expected_keepers.go
│ │ ├── codec_test.go
│ │ ├── params_legacy.go
│ │ ├── genesis.go
│ │ └── params_legacy_test.go
└── feeabs
│ └── types
│ ├── events.go
│ ├── errors.go
│ ├── genesis.go
│ ├── epoch.go
│ ├── keys.go
│ ├── events_test.go
│ ├── codec_test.go
│ ├── ibc.go
│ └── errors_test.go
├── benchmarks
├── testdata
│ ├── version.txt
│ ├── cw20_base.wasm
│ ├── cw1_whitelist.wasm
│ └── download_releases.sh
└── cw20_test.go
├── buf.lock
├── .go.work
├── contrib
├── relayer-tests
│ ├── .gitignore
│ ├── configs
│ │ └── wasmd
│ │ │ ├── chains
│ │ │ ├── ibc-0.json
│ │ │ └── ibc-1.json
│ │ │ └── paths
│ │ │ └── demo.json
│ ├── README.md
│ ├── test_ibc_transfer.sh
│ └── init_two_chainz_relayer.sh
├── local
│ ├── start_node.sh
│ ├── README.md
│ ├── 01-accounts.sh
│ ├── 03-grpc-queries.sh
│ └── setup_wasmd.sh
├── devtools
│ └── README.md
└── prometheus
│ ├── prometheus.yaml
│ └── README.md
├── .husky
└── hooks
│ └── pre-commit
├── client
└── docs
│ ├── docs.go
│ └── static
│ └── index.html
├── e2e_tests
├── testdata
│ ├── contracts
│ │ ├── zkemail.wasm
│ │ ├── user_map.wasm
│ │ ├── xion-account.wasm
│ │ ├── tokenfactory_core.wasm
│ │ ├── treasury-aarch64.wasm
│ │ ├── account_updatable-aarch64.wasm
│ │ ├── account_updatable-aarch64-previous.wasm
│ │ └── account-wasm-updatable-event-aarch64.wasm
│ ├── keys
│ │ ├── public.json
│ │ ├── jwtRS256.key.pub
│ │ ├── zkproof.json
│ │ └── vkey.json
│ └── unsigned_msgs
│ │ ├── bank_send_unsigned.json
│ │ └── config.json
├── .gitignore
├── configuredChains.yaml
└── app
│ └── upgrade_test.go
├── .dockerignore
├── buf.work.yaml
├── indexer
├── errors.go
├── config.go
├── authz_decode_test.go
├── noop_service.go
└── multi_raw.go
├── chains.yaml
├── proto
├── buf.gen.gogo.yaml
├── xion
│ ├── jwk
│ │ └── v1
│ │ │ ├── params.proto
│ │ │ ├── genesis.proto
│ │ │ └── audience.proto
│ ├── mint
│ │ └── v1
│ │ │ ├── genesis.proto
│ │ │ ├── event.proto
│ │ │ ├── tx.proto
│ │ │ ├── mint.proto
│ │ │ └── query.proto
│ ├── feeabs
│ │ └── v1beta1
│ │ │ ├── genesis.proto
│ │ │ ├── params.proto
│ │ │ └── proposal.proto
│ ├── v1
│ │ ├── genesis.proto
│ │ └── feegrant.proto
│ └── globalfee
│ │ └── v1
│ │ ├── query.proto
│ │ └── genesis.proto
├── buf.gen.openapi.yaml
├── buf.yaml
├── buf.gen.pulsar.yaml
└── buf.lock
├── scripts
├── README.md
└── release-info.sh
├── .goreleaser
└── integration.yaml
├── cmd
└── xiond
│ └── main.go
├── app
├── params
│ ├── encoding.go
│ ├── doc.go
│ ├── proto.go
│ ├── proto_test.go
│ └── weights.go
├── genesis.go
├── xionapp.go
├── encoding.go
├── config.go
├── config_test.go
└── v25_upgrade
│ └── migrator.go
├── wasmbindings
├── wasm.go
├── test_utils.go
├── grpc_plugin.go
├── query_plugin.go
└── whitelist_all_test.go
├── .github
├── workflows
│ ├── trigger-assets.yaml
│ ├── golangci-lint.yaml
│ ├── tests.yaml
│ ├── trigger-chain-registry.yaml
│ ├── build-test.yaml
│ ├── update-swagger.yaml
│ ├── binaries-darwin.yaml
│ ├── binaries-linux.yaml
│ ├── trigger-homebrew.yaml
│ ├── docker-scout.yaml
│ ├── publish-release.yaml
│ ├── trigger-types.yaml
│ ├── heighliner-alt.yaml
│ ├── build-release-info.yaml
│ ├── build-release.yaml
│ └── create-release.yaml
└── CODEOWNERS
├── .gitignore
├── .coveragerc
├── .codecov.yml
├── make
└── lint.mk
└── .golangci.yml
/.gitattributes:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/x/jwk/types/types.go:
--------------------------------------------------------------------------------
1 | package types
2 |
--------------------------------------------------------------------------------
/benchmarks/testdata/version.txt:
--------------------------------------------------------------------------------
1 | v0.10.0-soon4
2 |
--------------------------------------------------------------------------------
/buf.lock:
--------------------------------------------------------------------------------
1 | # Generated by buf. DO NOT EDIT.
2 | version: v1
3 |
--------------------------------------------------------------------------------
/.go.work:
--------------------------------------------------------------------------------
1 | go 1.25
2 |
3 | use (
4 | .
5 | ./e2e_tests
6 | )
7 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/.gitignore:
--------------------------------------------------------------------------------
1 | # Testing
2 | .relayer
3 | data
4 |
--------------------------------------------------------------------------------
/.husky/hooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | make format && make lint && make test-cover
--------------------------------------------------------------------------------
/client/docs/docs.go:
--------------------------------------------------------------------------------
1 | package docs
2 |
3 | import "embed"
4 |
5 | //go:embed static
6 | var Docs embed.FS
7 |
--------------------------------------------------------------------------------
/benchmarks/testdata/cw20_base.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/benchmarks/testdata/cw20_base.wasm
--------------------------------------------------------------------------------
/benchmarks/testdata/cw1_whitelist.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/benchmarks/testdata/cw1_whitelist.wasm
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/zkemail.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/zkemail.wasm
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/user_map.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/user_map.wasm
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/xion-account.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/xion-account.wasm
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Folders we don't want to copy to Docker daemon in `docker build . -t cosmwasm/xiond:latest`
2 | .github/
3 | .vscode/
4 | devnet/
5 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/tokenfactory_core.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/tokenfactory_core.wasm
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/treasury-aarch64.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/treasury-aarch64.wasm
--------------------------------------------------------------------------------
/x/jwk/keeper/query.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "github.com/burnt-labs/xion/x/jwk/types"
5 | )
6 |
7 | var _ types.QueryServer = Keeper{}
8 |
--------------------------------------------------------------------------------
/buf.work.yaml:
--------------------------------------------------------------------------------
1 | # This workspace file points to the roots found in your
2 | # previous "buf.yaml" configuration.
3 | version: v1
4 | directories:
5 | - proto
6 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/account_updatable-aarch64.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/account_updatable-aarch64.wasm
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/account_updatable-aarch64-previous.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/account_updatable-aarch64-previous.wasm
--------------------------------------------------------------------------------
/e2e_tests/testdata/contracts/account-wasm-updatable-event-aarch64.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/burnt-labs/xion/HEAD/e2e_tests/testdata/contracts/account-wasm-updatable-event-aarch64.wasm
--------------------------------------------------------------------------------
/contrib/local/start_node.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -eu
3 |
4 | wasmd start --rpc.laddr tcp://0.0.0.0:26657 --log_level=info --trace #remove trace flag if you don't wantg the stack trace to be printed
5 |
--------------------------------------------------------------------------------
/indexer/errors.go:
--------------------------------------------------------------------------------
1 | package indexer
2 |
3 | import "errors"
4 |
5 | var (
6 | ErrGrantNotFound = errors.New("grant not found")
7 | ErrAllowanceNotFound = errors.New("allowance not found")
8 | )
9 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/keys/public.json:
--------------------------------------------------------------------------------
1 | [
2 | "17159366307350401517208657413587014704131356894001302493847352957889395820464",
3 | "6632353713085157925504008443078919716322386156160602218536961028046468237192"
4 | ]
--------------------------------------------------------------------------------
/x/globalfee/alias.go:
--------------------------------------------------------------------------------
1 | package globalfee
2 |
3 | import (
4 | "github.com/burnt-labs/xion/x/globalfee/types"
5 | )
6 |
7 | const (
8 | ModuleName = types.ModuleName
9 |
10 | StoreKey = ModuleName
11 | )
12 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/configs/wasmd/chains/ibc-0.json:
--------------------------------------------------------------------------------
1 | {"key":"testkey","chain-id":"ibc-0","rpc-addr":"http://localhost:26657","account-prefix":"wasm","gas-adjustment":1.5,"gas-prices":"0.025stake","trusting-period":"336h"}
2 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/configs/wasmd/chains/ibc-1.json:
--------------------------------------------------------------------------------
1 | {"key":"testkey","chain-id":"ibc-1","rpc-addr":"http://localhost:26557","account-prefix":"wasm","gas-adjustment":1.5,"gas-prices":"0.025stake", "trusting-period":"336h"}
2 |
--------------------------------------------------------------------------------
/x/globalfee/types/keys.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | const (
4 | // ModuleName is the name of the this module
5 | ModuleName = "globalfee"
6 |
7 | StoreKey = ModuleName
8 |
9 | QuerierRoute = ModuleName
10 | )
11 |
--------------------------------------------------------------------------------
/x/jwk/types/errors.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | // DONTCOVER
4 |
5 | import (
6 | errorsmod "cosmossdk.io/errors"
7 | )
8 |
9 | // x/jwk module sentinel errors
10 | var (
11 | ErrInvalidJWK = errorsmod.Register(ModuleName, 1100, "invalid jwk")
12 | )
13 |
--------------------------------------------------------------------------------
/contrib/devtools/README.md:
--------------------------------------------------------------------------------
1 | ## Contributors
2 |
3 | Thanks to the entire Cosmos SDK team and the contributors who put their efforts into making simulation testing
4 | easier to implement. 🤗
5 |
6 | https://github.com/cosmos/cosmos-sdk/blob/master/contrib/devtools/Makefile
--------------------------------------------------------------------------------
/chains.yaml:
--------------------------------------------------------------------------------
1 | # Xion
2 | - name: xion
3 | github-organization: burnt-labs
4 | github-repo: xion
5 | dockerfile: cosmos
6 | pre-build:
7 | apk add --no-cache binutils-gold
8 | build-target: make install
9 | binaries:
10 | - /go/bin/xiond
11 | build-env:
12 | - BUILD_TAGS=muslc
13 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/configs/wasmd/paths/demo.json:
--------------------------------------------------------------------------------
1 | {"src":{"chain-id":"ibc-0","client-id":"","connection-id":"","channel-id":"","port-id":"transfer","order":"unordered","version":"ics20-1"},"dst":{"chain-id":"ibc-1","client-id":"","connection-id":"","channel-id":"","port-id":"transfer","order":"unordered","version":"ics20-1"},"strategy":{"type":"naive"}}
2 |
--------------------------------------------------------------------------------
/proto/buf.gen.gogo.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | plugins:
3 | - name: gocosmos
4 | out: ..
5 | opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/feegrant/v1beta1/feegrant.proto=cosmossdk.io/x/feegrant
6 | - name: grpc-gateway
7 | out: ..
8 | opt: logtostderr=true,allow_colon_final_segments=true
9 |
10 |
--------------------------------------------------------------------------------
/contrib/prometheus/prometheus.yaml:
--------------------------------------------------------------------------------
1 | global:
2 | scrape_interval: 15s # By default, scrape targets every 15 seconds.
3 | evaluation_interval: 15s # By default, scrape targets every 15 seconds.
4 | rule_files:
5 |
6 | scrape_configs:
7 | - job_name: xiond
8 |
9 | scrape_interval: 5s
10 | static_configs:
11 | - targets: ['host.docker.internal:26660']
--------------------------------------------------------------------------------
/x/jwk/types/keys.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | const (
4 | // ModuleName defines the module name
5 | ModuleName = "jwk"
6 |
7 | // StoreKey defines the primary module store key
8 | StoreKey = ModuleName
9 |
10 | // RouterKey defines the module's message routing key
11 | RouterKey = ModuleName
12 | )
13 |
14 | func KeyPrefix(p string) []byte {
15 | return []byte(p)
16 | }
17 |
--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------
1 | # Scripts
2 |
3 | These scripts are copied from the [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk/tree/v0.42.1/scripts) repository
4 | with minor modifications. All credits and big thanks go to the original authors.
5 |
6 | Please note that a custom [fork](github.com/regen-network/protobuf) by the Regen network team is used.
7 | See [`go.mod`](../go.mod) for version.
8 |
--------------------------------------------------------------------------------
/x/jwk/keeper/msg_server.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "github.com/burnt-labs/xion/x/jwk/types"
5 | )
6 |
7 | type msgServer struct {
8 | Keeper
9 | }
10 |
11 | // NewMsgServerImpl returns an implementation of the MsgServer interface
12 | // for the provided Keeper.
13 | func NewMsgServerImpl(keeper Keeper) types.MsgServer {
14 | return &msgServer{Keeper: keeper}
15 | }
16 |
17 | var _ types.MsgServer = msgServer{}
18 |
--------------------------------------------------------------------------------
/.goreleaser/integration.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | project_name: tests
4 |
5 | # Docs: https://goreleaser.com/customization/build/
6 | builds:
7 | - id: tests
8 | goos:
9 | - linux
10 | - darwin
11 | goarch:
12 | - arm64
13 | - amd64
14 | command: test
15 | dir: e2e_tests
16 | binary: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}"
17 | no_unique_dist_dir: true
18 | no_main_check: true
19 |
--------------------------------------------------------------------------------
/x/globalfee/README.md:
--------------------------------------------------------------------------------
1 | # Global fee module
2 |
3 | The Global fee module is based on [Gaia's implementation](https://github.com/cosmos/gaia). Which is supplied by the great folks at [TGrade](https://github.com/confio/tgrade) 👋, with minor modifications. All credits and big thanks go to the original authors.
4 |
5 | More information about Cosmoshub fee system please check [here](https://github.com/cosmos/gaia/blob/v17.3.0/docs/docs/modules/globalfee.md).
6 |
--------------------------------------------------------------------------------
/cmd/xiond/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 |
6 | "cosmossdk.io/log"
7 |
8 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
9 |
10 | "github.com/burnt-labs/xion/app"
11 | )
12 |
13 | func main() {
14 | rootCmd, _ := NewRootCmd()
15 |
16 | if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
17 | log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
18 | os.Exit(1)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/e2e_tests/.gitignore:
--------------------------------------------------------------------------------
1 | # OS artifacts
2 | .DS_Store
3 | *.swp
4 | *.swo
5 |
6 | # Test binaries and executables
7 | *.test
8 | *.out
9 | e2e_tests
10 | e2e_tests.test
11 |
12 | # Coverage reports
13 | coverage.txt
14 | coverage*.out
15 | coverage*.html
16 | profile.out
17 |
18 | # Test data and artifacts
19 | *.log
20 | xion-data/
21 | .testnode/
22 |
23 | # Temporary files
24 | tmp/
25 | temp/
26 | *.tmp
27 |
28 | # Go workspace files (if any)
29 | go.work
30 | go.work.sum
31 |
32 | *TEST_COVERAGE.md
33 |
--------------------------------------------------------------------------------
/x/xion/types/keys.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | var (
4 | PlatformPercentageKey = []byte{0x00}
5 | PlatformMinimumKey = []byte{0x01}
6 | )
7 |
8 | const (
9 | // ModuleName is the module name constant used in many places
10 | ModuleName = "xion"
11 |
12 | // StoreKey is the store key string for oracle
13 | StoreKey = ModuleName
14 |
15 | // RouterKey is the message route for oracle
16 | RouterKey = ModuleName
17 |
18 | // QuerierRoute is the querier route for oracle
19 | QuerierRoute = ModuleName
20 | )
21 |
--------------------------------------------------------------------------------
/x/mint/types/keys.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | var (
4 | // MinterKey is the key to use for the keeper store.
5 | MinterKey = []byte{0x00}
6 | ParamsKey = []byte{0x01}
7 | )
8 |
9 | const (
10 | // module name
11 | ModuleName = "mint"
12 |
13 | // StoreKey is the default store key for mint
14 | StoreKey = ModuleName
15 |
16 | // Query endpoints supported by the minting querier
17 | QueryParameters = "parameters"
18 | QueryInflation = "inflation"
19 | QueryAnnualProvisions = "annual_provisions"
20 | )
21 |
--------------------------------------------------------------------------------
/x/globalfee/types/keys_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestModuleConstants(t *testing.T) {
10 | require.Equal(t, "globalfee", ModuleName)
11 | require.Equal(t, "globalfee", StoreKey)
12 | require.Equal(t, "globalfee", QuerierRoute)
13 | }
14 |
15 | func TestConstantsAreConsistent(t *testing.T) {
16 | // Ensure all constants are consistent with each other
17 | require.Equal(t, ModuleName, StoreKey)
18 | require.Equal(t, ModuleName, QuerierRoute)
19 | }
20 |
--------------------------------------------------------------------------------
/benchmarks/testdata/download_releases.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o errexit -o nounset -o pipefail
3 | command -v shellcheck > /dev/null && shellcheck "$0"
4 |
5 | if [ $# -ne 1 ]; then
6 | echo "Usage: ./download_releases.sh RELEASE_TAG"
7 | exit 1
8 | fi
9 |
10 | tag="$1"
11 |
12 | for contract in cw20_base cw1_whitelist; do
13 | url="https://github.com/CosmWasm/cw-plus/releases/download/$tag/${contract}.wasm"
14 | echo "Downloading $url ..."
15 | wget -O "${contract}.wasm" "$url"
16 | done
17 |
18 | rm -f version.txt
19 | echo "$tag" >version.txt
--------------------------------------------------------------------------------
/proto/xion/jwk/v1/params.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.jwk.v1;
3 |
4 | import "gogoproto/gogo.proto";
5 |
6 | option go_package = "github.com/burnt-labs/xion/x/jwk/types";
7 |
8 | // Params defines the parameters for the module.
9 | message Params {
10 | // Time offset in nanoseconds for JWT validation
11 | uint64 time_offset = 1 [ (gogoproto.moretags) = "yaml:\"time_offset\"" ];
12 | // Gas required to deploy a new project/audience
13 | uint64 deployment_gas = 2
14 | [ (gogoproto.moretags) = "yaml:\"deployment_gas\"" ];
15 | }
16 |
--------------------------------------------------------------------------------
/proto/xion/jwk/v1/genesis.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package xion.jwk.v1;
4 |
5 | import "gogoproto/gogo.proto";
6 | import "xion/jwk/v1/params.proto";
7 | import "xion/jwk/v1/audience.proto";
8 |
9 | option go_package = "github.com/burnt-labs/xion/x/jwk/types";
10 |
11 | // GenesisState defines the jwk module's genesis state.
12 | message GenesisState {
13 | // The module parameters
14 | Params params = 1 [ (gogoproto.nullable) = false ];
15 | // List of all audiences
16 | repeated Audience audience_list = 2 [ (gogoproto.nullable) = false ];
17 | }
18 |
--------------------------------------------------------------------------------
/app/params/encoding.go:
--------------------------------------------------------------------------------
1 | package params
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/client"
5 | "github.com/cosmos/cosmos-sdk/codec"
6 | "github.com/cosmos/cosmos-sdk/codec/types"
7 | )
8 |
9 | // EncodingConfig specifies the concrete encoding types to use for a given app.
10 | // This is provided for compatibility between protobuf and amino implementations.
11 | type EncodingConfig struct {
12 | InterfaceRegistry types.InterfaceRegistry
13 | Codec codec.Codec
14 | TxConfig client.TxConfig
15 | Amino *codec.LegacyAmino
16 | }
17 |
--------------------------------------------------------------------------------
/wasmbindings/wasm.go:
--------------------------------------------------------------------------------
1 | package wasmbinding
2 |
3 | import (
4 | wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
5 |
6 | "github.com/cosmos/cosmos-sdk/baseapp"
7 | "github.com/cosmos/cosmos-sdk/codec"
8 | )
9 |
10 | func RegisterStargateQueries(queryRouter baseapp.GRPCQueryRouter, codec codec.Codec) []wasmkeeper.Option {
11 | queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{
12 | Stargate: StargateQuerier(queryRouter, codec),
13 | Grpc: GrpcQuerier(queryRouter),
14 | })
15 |
16 | return []wasmkeeper.Option{
17 | queryPluginOpt,
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/proto/xion/jwk/v1/audience.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.jwk.v1;
3 |
4 | option go_package = "github.com/burnt-labs/xion/x/jwk/types";
5 |
6 | // Audience represents a JWT audience configuration
7 | message Audience {
8 | // The audience identifier
9 | string aud = 1;
10 | // The public key associated with this audience
11 | string key = 2;
12 | // The admin address for this audience
13 | string admin = 3;
14 | }
15 |
16 | // AudienceClaim represents a claim for an audience
17 | message AudienceClaim {
18 | // The signer of the audience claim
19 | string signer = 1;
20 | }
--------------------------------------------------------------------------------
/contrib/local/README.md:
--------------------------------------------------------------------------------
1 | # Dev scripts
2 | For manual testing. Works on my box(*) ...
3 |
4 |
5 | *) OSX
6 |
7 | ```
8 | make install
9 | cd contrib/local
10 | rm -rf /tmp/trash
11 | HOME=/tmp/trash bash setup_wasmd.sh
12 | HOME=/tmp/trash bash start_node.sh
13 | ```
14 |
15 | Next shell:
16 |
17 | ```
18 | cd contrib/local
19 | ./01-accounts.sh
20 | ./02-contracts.sh
21 | ```
22 |
23 | ## Shell script development
24 |
25 | [Use `shellcheck`](https://www.shellcheck.net/) to avoid common mistakes in shell scripts.
26 | [Use `shfmt`](https://github.com/mvdan/sh) to ensure a consistent code formatting.
27 |
--------------------------------------------------------------------------------
/x/feeabs/types/events.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | const (
4 | EventTypeTimeout = "timeout"
5 | EventTypePacket = "receive_feechain_verification_packet"
6 | EventTypeEpochEnd = "epoch_end" // TODO: need to clean up (not use)
7 | EventTypeEpochStart = "epoch_start"
8 | AttributeKeyAckSuccess = "success"
9 | AttributeKeyAck = "acknowledgement"
10 | AttributeKeyAckError = "ack_error"
11 | AttributeEpochNumber = "epoch_number"
12 | AttributeEpochStartTime = "start_time"
13 | AttributeKeyFailureType = "failure_type"
14 | AttributeKeyPacket = "packet"
15 | )
16 |
--------------------------------------------------------------------------------
/benchmarks/cw20_test.go:
--------------------------------------------------------------------------------
1 | package benchmarks
2 |
3 | type cw20InitMsg struct {
4 | Name string `json:"name"`
5 | Symbol string `json:"symbol"`
6 | Decimals uint8 `json:"decimals"`
7 | InitialBalances []balance `json:"initial_balances"`
8 | }
9 |
10 | type balance struct {
11 | Address string `json:"address"`
12 | Amount uint64 `json:"amount,string"`
13 | }
14 |
15 | type cw20ExecMsg struct {
16 | Transfer *transferMsg `json:"transfer,omitempty"`
17 | }
18 |
19 | type transferMsg struct {
20 | Recipient string `json:"recipient"`
21 | Amount uint64 `json:"amount,string"`
22 | }
23 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/README.md:
--------------------------------------------------------------------------------
1 | # Relayer tests
2 |
3 | These scripts helps to test go-relayer with two local wasmd chains. \
4 | Make sure you run below scripts under `wasmd/contrib/relayer-tests` directory.
5 |
6 | - `./init_two_chainz_relayer.sh` will spin two chains and runs
7 | - `./one_chain.sh` will spin a single chain. This script used by the one above
8 | - `./test_ibc_transfer.sh` will setup a path between chains and send tokens between chains.
9 |
10 | ## Thank you
11 | The setup scripts here are taken from [cosmos/relayer](https://github.com/cosmos/relayer)
12 | Thank your relayer team for these scripts.
13 |
14 |
15 |
--------------------------------------------------------------------------------
/x/jwk/keeper/query_params.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "context"
5 |
6 | "google.golang.org/grpc/codes"
7 | "google.golang.org/grpc/status"
8 |
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 |
11 | "github.com/burnt-labs/xion/x/jwk/types"
12 | )
13 |
14 | func (k Keeper) Params(goCtx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
15 | if req == nil {
16 | return nil, status.Error(codes.InvalidArgument, "invalid request")
17 | }
18 | ctx := sdk.UnwrapSDKContext(goCtx)
19 |
20 | params := k.GetParams(ctx)
21 |
22 | return &types.QueryParamsResponse{Params: params}, nil
23 | }
24 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/test_ibc_transfer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # Ensure relayer is installed
6 | if ! [ -x "$(which rly)" ]; then
7 | echo "Error: rly is not installed." >&2
8 | exit 1
9 | fi
10 |
11 | rly tx link demo -d
12 |
13 | rly tx transfer ibc-0 ibc-1 1000000test $(rly chains address ibc-1)
14 |
15 | sleep 2
16 |
17 | EXPECTED_BALANCE="100000000000test"
18 | CHAIN_1_BALANCE=$(rly q bal ibc-1)
19 |
20 | if [[ "$CHAIN_1_BALANCE" == *"$EXPECTED_BALANCE" ]]; then
21 | echo "Token not sent correctly"
22 | echo "$EXPECTED_BALANCE not found in $CHAIN_1_BALANCE"
23 | exit 1
24 | fi
25 |
26 | echo "IBC transfer executed successfully"
27 |
--------------------------------------------------------------------------------
/proto/buf.gen.openapi.yaml:
--------------------------------------------------------------------------------
1 | # buf.gen.docs.yaml - For documentation generation
2 | # This replaces the gen_swagger function from the shell script
3 | # Generates OpenAPI docs from query.proto and service.proto files
4 | version: v2
5 | plugins:
6 | - protoc_builtin: openapiv2
7 | out: .
8 | opt: logtostderr=true,fqn_for_openapi_name=true,simple_operation_ids=true
9 | # Include all query and service proto files
10 | strategy: all
11 | inputs:
12 | - directory: .
13 | exclude_paths:
14 | - "**/packet-forward-middleware/**"
15 | - "**/regen-network/protobuf/**"
16 | - "**/poa/genesis.proto"
17 | - "**/tokenfactory/v1beta1/**"
18 |
--------------------------------------------------------------------------------
/proto/xion/mint/v1/genesis.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.mint.v1;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "xion/mint/v1/mint.proto";
6 | import "amino/amino.proto";
7 |
8 | option go_package = "github.com/burnt-labs/xion/x/mint/types";
9 |
10 | // GenesisState defines the mint module's genesis state.
11 | message GenesisState {
12 | // minter is a space for holding current inflation information.
13 | Minter minter = 1
14 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
15 |
16 | // params defines all the parameters of the module.
17 | Params params = 2
18 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
19 | }
20 |
--------------------------------------------------------------------------------
/app/params/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Package params defines the simulation parameters in the gaia.
3 |
4 | It contains the default weights used for each transaction used on the module's
5 | simulation. These weights define the chance for a transaction to be simulated at
6 | any gived operation.
7 |
8 | You can replace the default values for the weights by providing a params.json
9 | file with the weights defined for each of the transaction operations:
10 |
11 | {
12 | "op_weight_msg_send": 60,
13 | "op_weight_msg_delegate": 100,
14 | }
15 |
16 | In the example above, the `MsgSend` has 60% chance to be simulated, while the
17 | `MsgDelegate` will always be simulated.
18 | */
19 | package params
20 |
--------------------------------------------------------------------------------
/x/jwk/keeper/migrations.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
6 |
7 | v1 "github.com/burnt-labs/xion/x/jwk/migrations/v1"
8 | )
9 |
10 | // Migrator is a struct for handling in-place store migrations.
11 | type Migrator struct {
12 | jwkSubspace paramtypes.Subspace
13 | }
14 |
15 | // NewMigrator returns a new Migrator.
16 | func NewMigrator(jwkSubspace paramtypes.Subspace) Migrator {
17 | return Migrator{jwkSubspace}
18 | }
19 |
20 | // Migrate1To2 migrates from version 1 to 2
21 | func (m Migrator) Migrate1To2(ctx sdk.Context) error {
22 | return v1.MigrateStore(ctx, m.jwkSubspace)
23 | }
24 |
--------------------------------------------------------------------------------
/contrib/local/01-accounts.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o errexit -o nounset -o pipefail
3 |
4 | BASE_ACCOUNT=$(wasmd keys show validator -a --keyring-backend=test)
5 | wasmd q account "$BASE_ACCOUNT" -o json | jq
6 |
7 | echo "## Add new account"
8 | wasmd keys add fred --keyring-backend=test
9 |
10 | echo "## Check balance"
11 | NEW_ACCOUNT=$(wasmd keys show fred -a --keyring-backend=test)
12 | wasmd q bank balances "$NEW_ACCOUNT" -o json || true
13 |
14 | echo "## Transfer tokens"
15 | wasmd tx bank send validator "$NEW_ACCOUNT" 1ustake --gas 1000000 -y --chain-id=testing --node=http://localhost:26657 -b sync -o json --keyring-backend=test | jq
16 |
17 | echo "## Check balance again"
18 | wasmd q bank balances "$NEW_ACCOUNT" -o json | jq
19 |
--------------------------------------------------------------------------------
/app/params/proto.go:
--------------------------------------------------------------------------------
1 | package params
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/codec"
5 | "github.com/cosmos/cosmos-sdk/codec/types"
6 | "github.com/cosmos/cosmos-sdk/x/auth/tx"
7 | )
8 |
9 | // MakeEncodingConfig creates an EncodingConfig for an amino based test configuration.
10 | func MakeEncodingConfig() EncodingConfig {
11 | amino := codec.NewLegacyAmino()
12 | interfaceRegistry := types.NewInterfaceRegistry()
13 | marshaler := codec.NewProtoCodec(interfaceRegistry)
14 | txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes)
15 |
16 | return EncodingConfig{
17 | InterfaceRegistry: interfaceRegistry,
18 | Codec: marshaler,
19 | TxConfig: txCfg,
20 | Amino: amino,
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/proto/buf.yaml:
--------------------------------------------------------------------------------
1 | # This module represents buf.build/cosmos/cosmos-sdk
2 | version: v1
3 | name: buf.build/burnt-labs/xion
4 |
5 | deps:
6 | - buf.build/cosmos/cosmos-sdk
7 | - buf.build/cosmos/cosmos-proto
8 | - buf.build/cosmos/gogo-proto
9 | - buf.build/googleapis/googleapis
10 | - buf.build/tendermint/tendermint
11 | - buf.build/protocolbuffers/wellknowntypes
12 | - buf.build/burnt-labs/abstractaccount
13 | - buf.build/burnt-labs/tokenfactory
14 | breaking:
15 | use:
16 | - FILE
17 | lint:
18 | use:
19 | - STANDARD
20 | - COMMENTS
21 | - FILE_LOWER_SNAKE_CASE
22 | except:
23 | #- UNARY_RPC
24 | # - COMMENT_FIELD
25 | - SERVICE_SUFFIX
26 | # - PACKAGE_VERSION_SUFFIX
27 | - RPC_REQUEST_STANDARD_NAME
28 |
--------------------------------------------------------------------------------
/x/globalfee/keeper/migrations.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
6 |
7 | v2 "github.com/burnt-labs/xion/x/globalfee/migrations/v2"
8 | )
9 |
10 | // Migrator is a struct for handling in-place store migrations.
11 | type Migrator struct {
12 | globalfeeSubspace paramtypes.Subspace
13 | }
14 |
15 | // NewMigrator returns a new Migrator.
16 | func NewMigrator(globalfeeSubspace paramtypes.Subspace) Migrator {
17 | return Migrator{globalfeeSubspace: globalfeeSubspace}
18 | }
19 |
20 | // Migrate1to2 migrates from version 1 to 2.
21 | func (m Migrator) Migrate1to2(ctx sdk.Context) error {
22 | return v2.MigrateStore(ctx, m.globalfeeSubspace)
23 | }
24 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/keys/jwtRS256.key.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCiWDtMXdpqL7BHgdMN7mhH5ZGESx1be747cgkeXQGIeSZHgwuyQcb0fOK9aheyWhQGcEysU3E4fTHlw0wjTuiLg95FsfJKKiBFb0Jc+Mlo2VOL6lP8iAoWzIk1ewvLOudqMuQNtBTqlGweY14vSEA5S/jyu1e/xVVZY3yiQl6EPar03ssegUA6YhQQ+D9VMdO3wr/87714xko3h4yOH/j6zFFfo1c9I9PztdGWsrgZnilR2nzorS04UuHA7hSPQmQw18jzZ5VnW0BsOWqN3yMWcBvx9abzC11pM1sv8ABeZsOGzDAk7KvDx8BFkiGtdJ0oFZrp7iTuwvBMjL447yxp5ueUBGyMay3tkLObDkoKbZy0RWXeFiEfDJe78Dms5uUytXcfQbtap4owIxVInXWyyuWyZ9WE0jC7VCW3kZiY9NMmIKAZQZHFmSAPI7KMU0eCVillqYIbIn2jKh+y6QQaioxDpbOMWL+GNVqnNeLsuL5DQ6MSikhRQMOB5SuCNsZjR6IcjqwDPmGhoPRCNz17ceTr7LtVwoJMIBqdk6UlXS8mQcH3wsEuH2oChVR6L9VosV7Yhx9WWsv/jdpeWweGv9JRBjmkc+VQxtCKET/nt2k9GHfWoNf/DrJ7x2KWeI/wmakoza4jCcnTHuF8njlBrSgseasaXNj3CL5EY/RhSQ== mv@invidia-2.local
2 |
--------------------------------------------------------------------------------
/proto/xion/feeabs/v1beta1/genesis.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.feeabs.v1beta1;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "xion/feeabs/v1beta1/params.proto";
6 | import "xion/feeabs/v1beta1/epoch.proto";
7 |
8 | option go_package = "github.com/burnt-labs/xion/x/feeabs/types";
9 |
10 | // GenesisState defines the feeabs module's genesis state.
11 | message GenesisState {
12 | // params defines the parameters for the feeabs module
13 | Params params = 1 [
14 | (gogoproto.moretags) = "yaml:\"params\"",
15 | (gogoproto.nullable) = false
16 | ];
17 | // epochs defines the list of epoch information
18 | repeated EpochInfo epochs = 2 [ (gogoproto.nullable) = false ];
19 | // port_id defines the IBC port identifier
20 | string port_id = 3;
21 | }
22 |
--------------------------------------------------------------------------------
/proto/xion/v1/genesis.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.v1;
3 |
4 | import "cosmos/base/v1beta1/coin.proto";
5 | import "gogoproto/gogo.proto";
6 |
7 | option go_package = "github.com/burnt-labs/xion/x/xion/types";
8 |
9 | // GenesisState defines the xion module's genesis state
10 | message GenesisState {
11 | // The percentage fee taken by the platform
12 | uint32 platform_percentage = 1;
13 | // Minimum amounts required for platform operations
14 | repeated cosmos.base.v1beta1.Coin platform_minimums = 2 [
15 | (gogoproto.nullable) = false,
16 | (gogoproto.jsontag) = "platform_minimums,omitempty",
17 | (gogoproto.moretags) = "yaml:\"platform_minimums\"",
18 | (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
19 | ];
20 | }
21 |
--------------------------------------------------------------------------------
/proto/xion/feeabs/v1beta1/params.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.feeabs.v1beta1;
3 |
4 | option go_package = "github.com/burnt-labs/xion/x/feeabs/types";
5 |
6 | // Params defines the parameters for the feeabs module.
7 | message Params {
8 | // native ibced in osmosis
9 | string native_ibced_in_osmosis = 1;
10 |
11 | // osmosis query TWAP path
12 | string osmosis_query_twap_path = 2;
13 |
14 | // chain name for ibc path unwinding
15 | string chain_name = 3;
16 |
17 | // transfer channel for cross chain swap with osmosis
18 | string ibc_transfer_channel = 4;
19 |
20 | // query twap price icq channel with osmosis
21 | string ibc_query_icq_channel = 5;
22 |
23 | // osmosis crosschain swap contract address
24 | string osmosis_crosschain_swap_address = 6;
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/trigger-assets.yaml:
--------------------------------------------------------------------------------
1 | name: Trigger Assets
2 |
3 | on:
4 | workflow_call: # is called from the create-release workflow
5 | workflow_dispatch: # manual trigger
6 |
7 | jobs:
8 | trigger-assets:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Trigger xion-assets workflow
12 | uses: peter-evans/repository-dispatch@v2
13 | with:
14 | token: ${{ secrets.REPO_DISPATCH_TOKEN }}
15 | repository: burnt-labs/xion-assets
16 | event-type: xion-assets-release-trigger # NOTICE: must match the trigger in xion-assets workflow
17 | client-payload: |
18 | {
19 | "tag_name": "${{ github.event.release.tag_name }}",
20 | "release_name": "${{ github.event.release.name }}"
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/x/globalfee/ante/expected_keepers.go:
--------------------------------------------------------------------------------
1 | package ante
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | "github.com/cosmos/cosmos-sdk/x/auth/types"
6 | )
7 |
8 | // AccountKeeper defines the contract needed for AccountKeeper related APIs.
9 | // Interface provides support to use non-sdk AccountKeeper for AnteHandler's decorators.
10 | type AccountKeeper interface {
11 | GetParams(ctx sdk.Context) (params types.Params)
12 | GetAccount(ctx sdk.Context, addr sdk.AccAddress) sdk.AccountI
13 | SetAccount(ctx sdk.Context, acc sdk.AccountI)
14 | GetModuleAddress(moduleName string) sdk.AccAddress
15 | }
16 |
17 | // FeegrantKeeper defines the expected feegrant keeper.
18 | type FeegrantKeeper interface {
19 | UseGrantedFees(ctx sdk.Context, granter, grantee sdk.AccAddress, fee sdk.Coins, msgs []sdk.Msg) error
20 | }
21 |
--------------------------------------------------------------------------------
/x/xion/types/errors.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import errorsmod "cosmossdk.io/errors"
4 |
5 | // Codes for general xion errors
6 | const (
7 | DefaultCodespace = ModuleName
8 | )
9 |
10 | var (
11 | ErrNoAllowedContracts = errorsmod.Register(DefaultCodespace, 2, "no contract addresses specified")
12 | ErrNoValidAllowances = errorsmod.Register(DefaultCodespace, 3, "none of the allowances accepted the msg")
13 | ErrInconsistentExpiry = errorsmod.Register(DefaultCodespace, 4, "multi allowances must all expire together")
14 | ErrMinimumNotMet = errorsmod.Register(DefaultCodespace, 5, "minimum send amount not met")
15 | ErrNoValidWebAuth = errorsmod.Register(DefaultCodespace, 6, "Web auth is not valid")
16 | ErrWebAuthDataTooLarge = errorsmod.Register(DefaultCodespace, 7, "WebAuth data exceeds maximum allowed size")
17 | )
18 |
--------------------------------------------------------------------------------
/.github/workflows/golangci-lint.yaml:
--------------------------------------------------------------------------------
1 | name: GoLangCI Lint
2 |
3 | # reusable workflow, do not add triggers
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: read
10 |
11 | jobs:
12 | golangci:
13 | name: main
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Check out code
17 | uses: actions/checkout@v5
18 |
19 | - name: Set Go Version
20 | id: go-version
21 | run: echo "version=$(sed -En 's/^go (.*)$/\1/p' go.mod)" >> $GITHUB_OUTPUT
22 |
23 | - uses: actions/setup-go@v5
24 | with:
25 | go-version: ${{ steps.go-version.outputs.version }}
26 |
27 | - name: golangci-lint-xiond
28 | uses: golangci/golangci-lint-action@v8
29 | with:
30 | version: v2.6.1
31 | args: --timeout=10m --tests=false
32 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yaml:
--------------------------------------------------------------------------------
1 | name: Unit Tests
2 |
3 | # reusable workflow, do not add triggers
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v5
13 |
14 | - uses: technote-space/get-diff-action@v6
15 | with:
16 | PATTERNS: |
17 | **/**.go
18 | go.mod
19 | go.sum
20 |
21 | - name: Prepare Environment
22 | run: |
23 | sed -En 's/^go (.*)$/GO_VERSION=\1/p' go.mod | tee -a $GITHUB_ENV
24 |
25 | - name: Set up Go
26 | uses: actions/setup-go@v5
27 | with:
28 | go-version: ${{ env.GO_VERSION }}
29 |
30 | - name: Build
31 | run: go build -v ./...
32 |
33 | - name: Test
34 | run: make test-cover
35 |
--------------------------------------------------------------------------------
/.github/workflows/trigger-chain-registry.yaml:
--------------------------------------------------------------------------------
1 | name: Trigger Chain Registry Update
2 |
3 | on:
4 | workflow_call: # is called from the publish-release workflow
5 | workflow_dispatch: # manual trigger
6 |
7 | jobs:
8 | trigger-chain-registry:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Trigger chain-registry workflow
12 | uses: peter-evans/repository-dispatch@v2
13 | with:
14 | token: ${{ secrets.REPO_DISPATCH_TOKEN }}
15 | repository: burnt-labs/chain-registry
16 | event-type: chain-registry-update-trigger # NOTICE: must match the trigger in chain-registry workflow
17 | client-payload: |
18 | {
19 | "tag_name": "${{ github.event.release.tag_name }}",
20 | "release_name": "${{ github.event.release.name }}"
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/x/jwk/migrations/v1/migration.go:
--------------------------------------------------------------------------------
1 | package v1
2 |
3 | import (
4 | "fmt"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
8 |
9 | "github.com/burnt-labs/xion/x/jwk/types"
10 | )
11 |
12 | // MigrateStore performs in-place params migrations of
13 | // TimeOffset and DeploymentGas
14 | //
15 | // this should correct a previous migration
16 | func MigrateStore(ctx sdk.Context, jwkSubspace paramtypes.Subspace) error {
17 | ctx.Logger().Info("Running Migration to v3")
18 | defaultParams := types.DefaultParams()
19 |
20 | if !jwkSubspace.HasKeyTable() {
21 | jwkSubspace = jwkSubspace.WithKeyTable(types.ParamKeyTable())
22 | }
23 | ctx.Logger().Info(fmt.Sprintf("setting default params to: %+v\n", defaultParams))
24 | jwkSubspace.SetParamSet(ctx, &defaultParams)
25 | return nil
26 | }
27 |
--------------------------------------------------------------------------------
/x/jwk/types/key_audience.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "encoding/binary"
4 |
5 | var _ binary.ByteOrder
6 |
7 | const (
8 | // AudienceKeyPrefix is the prefix to retrieve all Audience
9 | AudienceKeyPrefix = "Audience/value/"
10 |
11 | // AudienceClaimKeyPrefix is the prefix for audience claims
12 | AudienceClaimKeyPrefix = "AudienceClaim/value/"
13 | )
14 |
15 | // AudienceKey returns the store key to retrieve an Audience from the index fields
16 | func AudienceKey(
17 | aud string,
18 | ) []byte {
19 | var key []byte
20 |
21 | audBytes := []byte(aud)
22 | key = append(key, audBytes...)
23 | key = append(key, []byte("/")...)
24 |
25 | return key
26 | }
27 |
28 | func AudienceClaimKey(hash []byte) []byte {
29 | var key []byte
30 |
31 | key = append(key, hash...)
32 | key = append(key, []byte("/")...)
33 |
34 | return key
35 | }
36 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/unsigned_msgs/bank_send_unsigned.json:
--------------------------------------------------------------------------------
1 | {
2 | "body": {
3 | "messages": [
4 | {
5 | "@type": "/cosmos.bank.v1beta1.MsgSend",
6 | "from_address": "xion1e2fuwe3uhq8zd9nkkk876nawrwdulgv460vzg7",
7 | "to_address": "xion1qaf2xflx5j3agtlvqk5vhjpeuhl6g45hxshwqj",
8 | "amount": [
9 | {
10 | "denom": "uxion",
11 | "amount": "100000"
12 | }
13 | ]
14 | }
15 | ],
16 | "memo": "",
17 | "timeout_height": "0",
18 | "extension_options": [],
19 | "non_critical_extension_options": []
20 | },
21 | "auth_info": {
22 | "signer_infos": [],
23 | "fee": {
24 | "amount": [],
25 | "gas_limit": "200000",
26 | "payer": "",
27 | "granter": ""
28 | },
29 | "tip": null
30 | },
31 | "signatures": []
32 | }
33 |
--------------------------------------------------------------------------------
/x/jwk/keeper/params.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 |
6 | "github.com/burnt-labs/xion/x/jwk/types"
7 | )
8 |
9 | // GetParams get all parameters as types.Params
10 | func (k Keeper) GetParams(ctx sdk.Context) types.Params {
11 | return types.NewParams(k.GetTimeOffset(ctx), k.GetDeploymentGas(ctx))
12 | }
13 |
14 | // SetParams set the params
15 | func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
16 | k.paramspace.SetParamSet(ctx, ¶ms)
17 | }
18 |
19 | func (k Keeper) GetTimeOffset(ctx sdk.Context) uint64 {
20 | var to uint64
21 | k.paramspace.Get(ctx, types.ParamStoreKeyTimeOffset, &to)
22 | return to
23 | }
24 |
25 | func (k Keeper) GetDeploymentGas(ctx sdk.Context) uint64 {
26 | var dg uint64
27 | k.paramspace.Get(ctx, types.ParamStoreKeyDeploymentGas, &dg)
28 | return dg
29 | }
30 |
--------------------------------------------------------------------------------
/app/genesis.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "encoding/json"
5 |
6 | "github.com/cosmos/cosmos-sdk/codec"
7 | "github.com/cosmos/cosmos-sdk/types/module"
8 | )
9 |
10 | // GenesisState of the blockchain is represented here as a map of raw json
11 | // messages key'd by a identifier string.
12 | // The identifier is used to determine which module genesis information belongs
13 | // to so it may be appropriately routed during init chain.
14 | // Within this application default genesis information is retrieved from
15 | // the ModuleBasicManager which populates json from each BasicModule
16 | // object provided to it during init.
17 | type GenesisState map[string]json.RawMessage
18 |
19 | // NewDefaultGenesisState generates the default state for the application.
20 | func NewDefaultGenesisState(cdc codec.JSONCodec, manager module.BasicManager) GenesisState {
21 | return manager.DefaultGenesis(cdc)
22 | }
23 |
--------------------------------------------------------------------------------
/app/params/proto_test.go:
--------------------------------------------------------------------------------
1 | package params
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestMakeEncodingConfig(t *testing.T) {
10 | config := MakeEncodingConfig()
11 |
12 | require.NotNil(t, config)
13 | require.NotNil(t, config.InterfaceRegistry)
14 | require.NotNil(t, config.Codec)
15 | require.NotNil(t, config.TxConfig)
16 | require.NotNil(t, config.Amino)
17 |
18 | // Test that the interface registry is properly initialized
19 | require.IsType(t, config.InterfaceRegistry, config.InterfaceRegistry)
20 |
21 | // Test that the codec is properly initialized
22 | require.IsType(t, config.Codec, config.Codec)
23 |
24 | // Test that the tx config is properly initialized
25 | require.IsType(t, config.TxConfig, config.TxConfig)
26 |
27 | // Test that the amino codec is properly initialized
28 | require.IsType(t, config.Amino, config.Amino)
29 | }
30 |
--------------------------------------------------------------------------------
/client/docs/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | XION API
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/x/jwk/client/cli/query_params.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 |
6 | "github.com/cosmos/cosmos-sdk/client"
7 | "github.com/cosmos/cosmos-sdk/client/flags"
8 |
9 | "github.com/burnt-labs/xion/x/jwk/types"
10 | )
11 |
12 | func CmdQueryParams() *cobra.Command {
13 | cmd := &cobra.Command{
14 | Use: "params",
15 | Short: "shows the parameters of the module",
16 | Args: cobra.NoArgs,
17 | RunE: func(cmd *cobra.Command, _ []string) error {
18 | clientCtx, err := client.GetClientQueryContext(cmd)
19 | if err != nil {
20 | return err
21 | }
22 |
23 | queryClient := types.NewQueryClient(clientCtx)
24 |
25 | res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{})
26 | if err != nil {
27 | return err
28 | }
29 |
30 | return clientCtx.PrintProto(res)
31 | },
32 | }
33 |
34 | flags.AddQueryFlagsToCmd(cmd)
35 |
36 | return cmd
37 | }
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS
2 | .DS_Store
3 | *.swp
4 | *.swo
5 | *.swl
6 | *.swm
7 | *.swn
8 | .vscode
9 | .idea
10 |
11 | # Build
12 | vendor
13 | build
14 | tools/bin/*
15 | examples/build/*
16 | docs/_build
17 | docs/tutorial
18 | dist
19 | tools-stamp
20 | docs/node_modules
21 | client/docs/node_modules/
22 | client/docs/tmp-swagger-gen/
23 | devnet/.xiond
24 | devnet/.shared
25 |
26 | # Data - ideally these don't exist
27 | baseapp/data/*
28 | client/lcd/keys/*
29 | mytestnet
30 |
31 | # Testing
32 | coverage.txt
33 | coverage*out
34 | coverage*html
35 | profile.out
36 | xion-data
37 |
38 | # Vagrant
39 | .vagrant/
40 | *.box
41 | *.log
42 | vagrant
43 |
44 | # IDE
45 | .idea/
46 | *.iml
47 |
48 | # Graphviz
49 | dependency-graph.png
50 |
51 | # Latex
52 | *.aux
53 | *.out
54 | *.synctex.gz
55 | contract_tests/*
56 |
57 | # Go
58 | go.work
59 | go.work.sum
60 | /integration_tests/integration_tests.test
61 | release
62 | .testnode/
63 |
--------------------------------------------------------------------------------
/e2e_tests/configuredChains.yaml:
--------------------------------------------------------------------------------
1 | ## NOTICE: This file gets embedded into interchaintest binary.
2 | ## Set the environment variable: IBCTEST_CONFIGURED_CHAINS to a path
3 | ## to use custom versions of this file
4 |
5 | osmosis:
6 | name: osmosis
7 | type: cosmos
8 | bin: osmosisd
9 | bech32-prefix: osmo
10 | denom: uosmo
11 | gas-prices: 0.0025uosmo
12 | gas-adjustment: 1.3
13 | trusting-period: 336h
14 | images:
15 | - repository: ghcr.io/strangelove-ventures/heighliner/osmosis
16 | version: v28.0.0
17 | uid-gid: 1025:1025
18 | no-host-mount: false
19 |
20 | xion:
21 | name: xion
22 | type: cosmos
23 | bin: xiond
24 | bech32-prefix: xion
25 | denom: uxion
26 | gas-prices: 0.0uxion
27 | gas-adjustment: 1.3
28 | trusting-period: 336h
29 | images:
30 | - repository: ghcr.io/burnt-labs/xion/heighliner
31 | version: v20.0.0
32 | uid-gid: 1025:1025
33 | no-host-mount: false
34 |
--------------------------------------------------------------------------------
/proto/xion/globalfee/v1/query.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.globalfee.v1;
3 |
4 | import "xion/globalfee/v1/genesis.proto";
5 | import "gogoproto/gogo.proto";
6 | import "google/api/annotations.proto";
7 |
8 | option go_package = "github.com/burnt-labs/xion/x/globalfee/types";
9 |
10 | // Query defines the gRPC querier service.
11 | service Query {
12 | // Params queries the parameters of the module
13 | rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
14 | option (google.api.http).get = "/xion/globalfee/v1/params";
15 | }
16 | }
17 |
18 | // QueryMinimumGasPricesRequest is the request type for the
19 | // Query/MinimumGasPrices RPC method.
20 | message QueryParamsRequest {}
21 |
22 | // QueryMinimumGasPricesResponse is the response type for the
23 | // Query/MinimumGasPrices RPC method.
24 | message QueryParamsResponse {
25 | // The global fee parameters
26 | Params params = 1 [ (gogoproto.nullable) = false ];
27 | }
--------------------------------------------------------------------------------
/x/xion/client/cli/query.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/spf13/cobra"
7 |
8 | "github.com/cosmos/cosmos-sdk/client"
9 |
10 | "github.com/burnt-labs/xion/x/xion/types"
11 | )
12 |
13 | // GetQueryCmd returns the cli query commands for this module
14 | func GetQueryCmd() *cobra.Command {
15 | // Group jwk queries under a subcommand
16 | cmd := &cobra.Command{
17 | Use: types.ModuleName,
18 | Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
19 | DisableFlagParsing: true,
20 | SuggestionsMinimumDistance: 2,
21 | RunE: client.ValidateCmd,
22 | }
23 |
24 | cmd.AddCommand(CmdWebAuthNVerifyRegister())
25 | cmd.AddCommand(CmdWebAuthNVerifyAuthenticate())
26 | cmd.AddCommand(CmdPlatformPercentage())
27 | cmd.AddCommand(CmdPlatformMinimum())
28 |
29 | // this line is used by starport scaffolding # 1
30 |
31 | return cmd
32 | }
33 |
--------------------------------------------------------------------------------
/x/feeabs/types/errors.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | sdkerrors "cosmossdk.io/errors"
5 | )
6 |
7 | var (
8 | ErrInvalidExchangeRate = sdkerrors.Register(ModuleName, 1, "invalid exchange rate")
9 | ErrInvalidIBCFees = sdkerrors.Register(ModuleName, 2, "invalid ibc fees")
10 | ErrHostZoneConfigNotFound = sdkerrors.Register(ModuleName, 3, "host zone config not found")
11 | ErrDuplicateHostZoneConfig = sdkerrors.Register(ModuleName, 4, "duplicate host zone config")
12 | ErrNotEnoughFundInModuleAddress = sdkerrors.Register(ModuleName, 5, "not have funding yet")
13 | ErrUnsupportedDenom = sdkerrors.Register(ModuleName, 6, "unsupported denom")
14 | ErrHostZoneFrozen = sdkerrors.Register(ModuleName, 7, "host zone is frozen")
15 | ErrHostZoneOutdated = sdkerrors.Register(ModuleName, 8, "host zone is outdated")
16 |
17 | ErrInvalidSigner = sdkerrors.Register(ModuleName, 9, "invalid signer")
18 | )
19 |
--------------------------------------------------------------------------------
/x/mint/types/msgs.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | errorsmod "cosmossdk.io/errors"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | )
8 |
9 | var _ sdk.Msg = &MsgUpdateParams{}
10 |
11 | // GetSignBytes implements the LegacyMsg interface.
12 | func (m MsgUpdateParams) GetSignBytes() []byte {
13 | return sdk.MustSortJSON(amino.MustMarshalJSON(&m))
14 | }
15 |
16 | // GetSigners returns the expected signers for a MsgUpdateParams message.
17 | func (m *MsgUpdateParams) GetSigners() []sdk.AccAddress {
18 | addr, _ := sdk.AccAddressFromBech32(m.Authority)
19 | return []sdk.AccAddress{addr}
20 | }
21 |
22 | // ValidateBasic does a sanity check on the provided data.
23 | func (m *MsgUpdateParams) ValidateBasic() error {
24 | if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil {
25 | return errorsmod.Wrap(err, "invalid authority address")
26 | }
27 |
28 | if err := m.Params.Validate(); err != nil {
29 | return err
30 | }
31 |
32 | return nil
33 | }
34 |
--------------------------------------------------------------------------------
/x/jwk/genesis.go:
--------------------------------------------------------------------------------
1 | package jwk
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 |
6 | "github.com/burnt-labs/xion/x/jwk/keeper"
7 | "github.com/burnt-labs/xion/x/jwk/types"
8 | )
9 |
10 | // InitGenesis initializes the module's state from a provided genesis state.
11 | func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) {
12 | // Set all the audience
13 | for _, elem := range genState.AudienceList {
14 | k.SetAudience(ctx, elem)
15 | }
16 | // this line is used by starport scaffolding # genesis/module/init
17 | k.SetParams(ctx, genState.Params)
18 | }
19 |
20 | // ExportGenesis returns the module's exported genesis
21 | func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
22 | genesis := types.DefaultGenesis()
23 | genesis.Params = k.GetParams(ctx)
24 |
25 | genesis.AudienceList = k.GetAllAudience(ctx)
26 | // this line is used by starport scaffolding # genesis/module/export
27 |
28 | return genesis
29 | }
30 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/keys/zkproof.json:
--------------------------------------------------------------------------------
1 | {
2 | "pi_a": [
3 | "12507447113723412003224186427502020795233065601694475948353916367458023917378",
4 | "11647492317411203501005000400445357960526164678860073240934539412172539662393",
5 | "1"
6 | ],
7 | "pi_b": [
8 | [
9 | "7940549314384105696029058996970477222250722318473222306365757709950316328622",
10 | "3871803822315737814507990678305738946962434293488010314614673049872361357824"
11 | ],
12 | [
13 | "9321628147268837332826685691496619976214340529626890605901530205644891157623",
14 | "11055633623863522550839292215199250102681676923294542571845856636912478215249"
15 | ],
16 | [
17 | "1",
18 | "0"
19 | ]
20 | ],
21 | "pi_c": [
22 | "14657074421768515835858985917578621239565328965402854179356218448654860572889",
23 | "13279404639268614726451606952231465882641365149672841924541768399025661321311",
24 | "1"
25 | ],
26 | "protocol": "groth16",
27 | "curve": "bn128"
28 | }
--------------------------------------------------------------------------------
/contrib/local/03-grpc-queries.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o errexit -o nounset -o pipefail
3 |
4 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
5 |
6 | echo "-----------------------"
7 |
8 | echo "### List all codes"
9 | RESP=$(grpcurl -plaintext localhost:9090 cosmwasm.wasm.v1.Query/Codes)
10 | echo "$RESP" | jq
11 |
12 | CODE_ID=$(echo "$RESP" | jq -r '.codeInfos[-1].codeId')
13 | echo "### List contracts by code"
14 | RESP=$(grpcurl -plaintext -d "{\"codeId\": $CODE_ID}" localhost:9090 cosmwasm.wasm.v1.Query/ContractsByCode)
15 | echo "$RESP" | jq
16 |
17 | echo "### Show history for contract"
18 | CONTRACT=$(echo "$RESP" | jq -r ".contracts[-1]")
19 | grpcurl -plaintext -d "{\"address\": \"$CONTRACT\"}" localhost:9090 cosmwasm.wasm.v1.Query/ContractHistory | jq
20 |
21 | echo "### Show contract state"
22 | grpcurl -plaintext -d "{\"address\": \"$CONTRACT\"}" localhost:9090 cosmwasm.wasm.v1.Query/AllContractState | jq
23 |
24 | echo "Empty state due to 'burner' contract cleanup"
25 |
--------------------------------------------------------------------------------
/indexer/config.go:
--------------------------------------------------------------------------------
1 | package indexer
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/spf13/cast"
7 |
8 | servertypes "github.com/cosmos/cosmos-sdk/server/types"
9 | )
10 |
11 | // Config defines the indexer configuration.
12 | type Config struct {
13 | Enabled bool `mapstructure:"enabled" json:"enabled"`
14 | }
15 |
16 | func DefaultConfig() Config {
17 | return Config{
18 | Enabled: false,
19 | }
20 | }
21 |
22 | // DefaultConfigTemplate returns the default TOML snippet for the indexer configuration.
23 | func DefaultConfigTemplate() string {
24 | return ConfigTemplate(DefaultConfig())
25 | }
26 |
27 | // ConfigTemplate returns the TOML snippet for the indexer configuration.
28 | func ConfigTemplate(c Config) string {
29 | return fmt.Sprintf(`
30 | [indexer]
31 | enabled = %t
32 | `, c.Enabled)
33 | }
34 |
35 | func NewConfigFromOptions(opts servertypes.AppOptions) Config {
36 | enabled := cast.ToBool(opts.Get("indexer.enabled"))
37 | return Config{
38 | Enabled: enabled,
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/unsigned_msgs/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "grant_config": [
3 | {
4 | "msg_type_url": "/cosmos.bank.v1.MsgSend",
5 | "grant_config": {
6 | "description": "Bank grant",
7 | "authorization": {
8 | "type_url": "/cosmos.authz.v1.GenericAuthorization",
9 | "value": "CgRQYXk="
10 | },
11 | "optional": true
12 | }
13 | },
14 | {
15 | "msg_type_url": "/cosmos.staking.v1.MsgDelegate",
16 | "grant_config": {
17 | "description": "Staking grant",
18 | "authorization": {
19 | "type_url": "/cosmos.authz.v1.GenericAuthorization",
20 | "value": "CgREZWxlZ2F0ZQ=="
21 | },
22 | "optional": false
23 | }
24 | }
25 | ],
26 | "fee_config": {
27 | "description": "Fee allowance for user1",
28 | "allowance": {
29 | "type_url": "/cosmos.feegrant.v1.BasicAllowance",
30 | "value": "CgQICAI="
31 | },
32 | "expiration": 1715151235
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/x/xion/types/codec_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "github.com/cosmos/cosmos-sdk/codec"
9 | "github.com/cosmos/cosmos-sdk/codec/types"
10 |
11 | xionTypes "github.com/burnt-labs/xion/x/xion/types"
12 | )
13 |
14 | func TestRegisterLegacyAminoCodec(t *testing.T) {
15 | cdc := codec.NewLegacyAmino()
16 |
17 | // Should not panic
18 | require.NotPanics(t, func() {
19 | xionTypes.RegisterLegacyAminoCodec(cdc)
20 | })
21 | }
22 |
23 | func TestRegisterInterfaces(t *testing.T) {
24 | registry := types.NewInterfaceRegistry()
25 |
26 | // Should not panic
27 | require.NotPanics(t, func() {
28 | xionTypes.RegisterInterfaces(registry)
29 | })
30 |
31 | // Test that some interfaces are registered
32 | require.NotNil(t, registry)
33 | }
34 |
35 | func TestCodecInit(t *testing.T) {
36 | // Test that init function runs without panic
37 | // This is implicitly tested by importing the package
38 | require.True(t, true)
39 | }
40 |
--------------------------------------------------------------------------------
/x/jwk/keeper/keeper.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "fmt"
5 |
6 | "cosmossdk.io/log"
7 | storetypes "cosmossdk.io/store/types"
8 |
9 | "github.com/cosmos/cosmos-sdk/codec"
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
12 |
13 | "github.com/burnt-labs/xion/x/jwk/types"
14 | )
15 |
16 | type (
17 | Keeper struct {
18 | cdc codec.BinaryCodec
19 | storeKey storetypes.StoreKey
20 | paramspace paramtypes.Subspace
21 | }
22 | )
23 |
24 | func NewKeeper(
25 | cdc codec.BinaryCodec,
26 | storeKey storetypes.StoreKey,
27 | ps paramtypes.Subspace,
28 | ) Keeper {
29 | // set KeyTable if it has not already been set
30 | if !ps.HasKeyTable() {
31 | ps = ps.WithKeyTable(types.ParamKeyTable())
32 | }
33 |
34 | return Keeper{
35 | cdc: cdc,
36 | storeKey: storeKey,
37 | paramspace: ps,
38 | }
39 | }
40 |
41 | func (k Keeper) Logger(ctx sdk.Context) log.Logger {
42 | return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
43 | }
44 |
--------------------------------------------------------------------------------
/x/jwk/client/cli/query.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/spf13/cobra"
7 |
8 | "github.com/cosmos/cosmos-sdk/client"
9 |
10 | "github.com/burnt-labs/xion/x/jwk/types"
11 | )
12 |
13 | // GetQueryCmd returns the cli query commands for this module
14 | func GetQueryCmd() *cobra.Command {
15 | // Group jwk queries under a subcommand
16 | cmd := &cobra.Command{
17 | Use: types.ModuleName,
18 | Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
19 | DisableFlagParsing: true,
20 | SuggestionsMinimumDistance: 2,
21 | RunE: client.ValidateCmd,
22 | }
23 |
24 | cmd.AddCommand(CmdQueryParams())
25 | cmd.AddCommand(CmdListAudience())
26 | cmd.AddCommand(CmdShowAudience())
27 | cmd.AddCommand(CmdShowAudienceClaim())
28 | cmd.AddCommand(CmdValidateJWT())
29 |
30 | // utils, not sure where best to put this
31 | cmd.AddCommand(CmdConvertPemToJSON())
32 |
33 | // this line is used by starport scaffolding # 1
34 |
35 | return cmd
36 | }
37 |
--------------------------------------------------------------------------------
/x/jwk/types/codec.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/codec"
5 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | "github.com/cosmos/cosmos-sdk/types/msgservice"
8 | )
9 |
10 | func RegisterCodec(cdc *codec.LegacyAmino) {
11 | cdc.RegisterConcrete(&MsgCreateAudience{}, "jwk/CreateAudience", nil)
12 | cdc.RegisterConcrete(&MsgUpdateAudience{}, "jwk/UpdateAudience", nil)
13 | cdc.RegisterConcrete(&MsgDeleteAudience{}, "jwk/DeleteAudience", nil)
14 | // this line is used by starport scaffolding # 2
15 | }
16 |
17 | func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
18 | registry.RegisterImplementations((*sdk.Msg)(nil),
19 | &MsgCreateAudience{},
20 | &MsgUpdateAudience{},
21 | &MsgDeleteAudience{},
22 | )
23 | // this line is used by starport scaffolding # 3
24 |
25 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
26 | }
27 |
28 | var (
29 | Amino = codec.NewLegacyAmino()
30 | ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry())
31 | )
32 |
--------------------------------------------------------------------------------
/x/feeabs/types/genesis.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "fmt"
4 |
5 | // DefaultGenesis returns the incentive module's default genesis state.
6 | func DefaultGenesis() *GenesisState {
7 | return &GenesisState{
8 | Params: Params{
9 | OsmosisQueryTwapPath: DefaultOsmosisQueryTwapPath,
10 | NativeIbcedInOsmosis: "ibc/C053D637CCA2A2BA030E2C5EE1B28A16F71CCB0E45E8BE52766DC1B241B77878",
11 | ChainName: DefaultChainName,
12 | },
13 | Epochs: []EpochInfo{NewGenesisEpochInfo(DefaultQueryEpochIdentifier, DefaultQueryPeriod), NewGenesisEpochInfo(DefaultSwapEpochIdentifier, DefaultSwapPeriod)},
14 | PortId: IBCPortID,
15 | }
16 | }
17 |
18 | // Validate performs basic genesis state validation, returning an error upon any failure.
19 | func (gs GenesisState) Validate() error {
20 | err := gs.Params.Validate()
21 | if err != nil {
22 | return fmt.Errorf("invalid params %s", err)
23 | }
24 |
25 | // Validate epochs genesis
26 | for _, epoch := range gs.Epochs {
27 | err := epoch.Validate()
28 | if err != nil {
29 | return err
30 | }
31 | }
32 | return nil
33 | }
34 |
--------------------------------------------------------------------------------
/x/jwk/client/cli/tx.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "time"
6 |
7 | "github.com/spf13/cobra"
8 |
9 | "github.com/cosmos/cosmos-sdk/client"
10 |
11 | // "github.com/cosmos/cosmos-sdk/client/flags"
12 | "github.com/burnt-labs/xion/x/jwk/types"
13 | )
14 |
15 | var DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds())
16 |
17 | // GetTxCmd returns the transaction commands for this module
18 | func GetTxCmd() *cobra.Command {
19 | cmd := &cobra.Command{
20 | Use: types.ModuleName,
21 | Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName),
22 | DisableFlagParsing: true,
23 | SuggestionsMinimumDistance: 2,
24 | RunE: client.ValidateCmd,
25 | }
26 |
27 | cmd.AddCommand(CmdCreateAudienceClaim())
28 | cmd.AddCommand(CmdCreateAudience())
29 | cmd.AddCommand(CmdUpdateAudience())
30 | cmd.AddCommand(CmdDeleteAudience())
31 | cmd.AddCommand(CmdDeleteAudienceClaim())
32 | // this line is used by starport scaffolding # 1
33 |
34 | return cmd
35 | }
36 |
--------------------------------------------------------------------------------
/app/xionapp.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gorilla/mux"
7 |
8 | "github.com/cosmos/cosmos-sdk/client"
9 |
10 | "github.com/burnt-labs/xion/client/docs"
11 | )
12 |
13 | // RegisterSwaggerAPI registers swagger route with API Server
14 | func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router, swaggerEnabled bool) error {
15 | if swaggerEnabled {
16 | docsServer := http.FileServer(http.FS(docs.Docs))
17 | rtr.Handle("/static", docsServer)
18 | rtr.Handle("/static/", docsServer)
19 | rtr.Handle("/static/swagger.json", docsServer)
20 | rtr.Handle("/static/openapi.json", docsServer)
21 |
22 | rtr.PathPrefix("/static").Handler(http.StripPrefix("/static/", docsServer))
23 | rtr.PathPrefix("/static/").Handler(http.StripPrefix("/static/", docsServer))
24 |
25 | rtr.Handle("/", http.RedirectHandler("/static/", http.StatusMovedPermanently))
26 | rtr.Handle("/swagger", http.RedirectHandler("/static/", http.StatusMovedPermanently))
27 | rtr.Handle("/swagger/", http.RedirectHandler("/static/", http.StatusMovedPermanently))
28 | }
29 | return nil
30 | }
31 |
--------------------------------------------------------------------------------
/x/xion/keeper/genesis.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "encoding/binary"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 |
8 | "github.com/burnt-labs/xion/x/xion/types"
9 | )
10 |
11 | // InitGenesis initializes the bank module's state from a given genesis state.
12 | func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) {
13 | k.OverwritePlatformPercentage(ctx, genState.PlatformPercentage)
14 | err := k.OverwritePlatformMinimum(ctx, genState.PlatformMinimums)
15 | if err != nil {
16 | panic(err)
17 | }
18 | }
19 |
20 | // ExportGenesis returns the bank module's genesis state.
21 | func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
22 | bz := ctx.KVStore(k.storeKey).Get(types.PlatformPercentageKey)
23 | // Read as uint64 (8 bytes) since that's how it's stored, then convert to uint32
24 | platformPercentage := uint32(binary.BigEndian.Uint64(bz))
25 |
26 | platformMinimums, err := k.GetPlatformMinimums(ctx)
27 | if err != nil {
28 | panic(err)
29 | }
30 | rv := types.NewGenesisState(platformPercentage, platformMinimums)
31 | return rv
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/build-test.yaml:
--------------------------------------------------------------------------------
1 | name: Build and Test
2 |
3 | on:
4 | workflow_call:
5 | workflow_dispatch:
6 | pull_request:
7 | branches:
8 | - main
9 | - release/*
10 |
11 | concurrency:
12 | group: ${{ github.workflow }}-${{ github.ref }}
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | lint:
17 | name: Golang CI Lint
18 | uses: burnt-labs/xion/.github/workflows/golangci-lint.yaml@workflows/main
19 | secrets: inherit
20 |
21 | update-swagger:
22 | name: Update Swagger
23 | uses: burnt-labs/xion/.github/workflows/update-swagger.yaml@workflows/main
24 | secrets: inherit
25 |
26 | unit-tests:
27 | name: Go Unit Tests
28 | uses: burnt-labs/xion/.github/workflows/tests.yaml@workflows/main
29 | secrets: inherit
30 |
31 | build-docker:
32 | name: Build Docker Images
33 | uses: burnt-labs/xion/.github/workflows/docker-build.yaml@workflows/main
34 | secrets: inherit
35 |
36 | e2e-tests:
37 | name: E2E tests
38 | needs:
39 | - build-docker
40 | uses: burnt-labs/xion/.github/workflows/e2e-tests.yaml@workflows/main
41 | secrets: inherit
42 |
--------------------------------------------------------------------------------
/x/xion/types/errors_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "github.com/burnt-labs/xion/x/xion/types"
9 | )
10 |
11 | func TestErrors(t *testing.T) {
12 | // Test that error constants are properly defined
13 | require.NotNil(t, types.ErrNoAllowedContracts)
14 | require.NotNil(t, types.ErrNoValidAllowances)
15 | require.NotNil(t, types.ErrInconsistentExpiry)
16 | require.NotNil(t, types.ErrMinimumNotMet)
17 | require.NotNil(t, types.ErrNoValidWebAuth)
18 |
19 | // Test error messages
20 | require.Contains(t, types.ErrNoAllowedContracts.Error(), "no contract addresses specified")
21 | require.Contains(t, types.ErrNoValidAllowances.Error(), "none of the allowances accepted the msg")
22 | require.Contains(t, types.ErrInconsistentExpiry.Error(), "multi allowances must all expire together")
23 | require.Contains(t, types.ErrMinimumNotMet.Error(), "minimum send amount not met")
24 | require.Contains(t, types.ErrNoValidWebAuth.Error(), "Web auth is not valid")
25 |
26 | // Test codespace
27 | require.Equal(t, types.ModuleName, types.DefaultCodespace)
28 | }
29 |
--------------------------------------------------------------------------------
/.github/workflows/update-swagger.yaml:
--------------------------------------------------------------------------------
1 | name: Update Swagger
2 |
3 | # runs on push to any branch
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | main:
10 | runs-on: ubuntu-latest
11 | permissions:
12 | contents: write
13 |
14 | steps:
15 | - name: Check out code
16 | uses: actions/checkout@v5
17 |
18 | - name: Generate Swagger
19 | env:
20 | DOCKER_IMAGE: ghcr.io/cosmos/proto-builder:0.15.0
21 | run: |
22 | # runs as runner:docker (1001:121)
23 | chmod -R o+wX client
24 | make proto-gen-swagger
25 | chmod -R o-w client/*
26 |
27 | # Need to sort out using signed commits to use
28 | # - name: Commit if Changed
29 | # uses: stefanzweifel/git-auto-commit-action@v5
30 | # with:
31 | # commit_message: Update swagger
32 |
33 | - name: Fail on changed
34 | run: |
35 | if [[ -n "$(git status --porcelain)" ]]; then
36 | git status --porcelain 1>&2
37 | echo 'Please run `make proto-gen-swagger`' 1>&2
38 | exit 1
39 | fi
40 |
--------------------------------------------------------------------------------
/.coveragerc:
--------------------------------------------------------------------------------
1 | # Coverage configuration for Xion project
2 | # Format: INI-style configuration file
3 |
4 | [run]
5 | # Coverage threshold percentage (can be overridden via COVERAGE_THRESHOLD env var)
6 | threshold = 70
7 |
8 | [exclude]
9 | # Patterns to ignore in low coverage reporting
10 | # Format: file_path:pattern (grep -v compatible)
11 |
12 | # CLI commands with complex manual testing
13 | github.com/burnt-labs/xion/x/xion/client/cli/tx.go:.*NewSignCmd
14 |
15 | # WebAuthn verification (requires hardware/browser)
16 | github.com/burnt-labs/xion/x/xion/keeper/grpc_query.go:.*WebAuthNVerifyRegister
17 |
18 | # Staking inflation mint function
19 | github.com/burnt-labs/xion/x/xion/keeper/mint.go:.*StakedInflationMintFn
20 |
21 | # Indexer CLI reindex command (requires full chain context)
22 | github.com/burnt-labs/xion/indexer/client/cli/indexer.go:.*ReIndex
23 |
24 | # Wasm keeper metadata retrieval (requires full keeper setup for success path)
25 | # Error path is tested; success path needs integration test with real keeper
26 | github.com/burnt-labs/xion/app/keepers/wasm_keeper.go:.*GetXionContractMetadata
27 |
28 | github.com/burnt-labs/xion/app/v25_upgrade
29 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # # Specify a default Code Owner for all files with a wildcard:
2 | # * @default-owner
3 |
4 | # # Specify multiple Code Owners to a specific file:
5 | # README.md @doc-team @tech-lead
6 |
7 | # # Specify a Code Owner to all files with a specific extension:
8 | # *.rb @ruby-owner
9 |
10 | # # Specify Code Owners with usernames or email addresses:
11 | # LICENSE @legal janedoe@gitlab.com
12 |
13 | # # Use group names to match groups and nested groups:
14 | # README @group @group/with-nested/subgroup
15 |
16 | # # Specify a Code Owner to a directory and all its contents:
17 | # /docs/ @all-docs
18 | # /docs/* @root-docs
19 | # /docs/**/*.md @markdown-docs # Match specific file types in any subdirectory
20 | # /db/**/index.md @index-docs # Match a specific file name in any subdirectory
21 |
22 | # # Use a section to group related rules:
23 | # [Documentation]
24 | # ee/docs @docs
25 | # docs @docs
26 |
27 | # # Assign a role as a Code Owner:
28 | # /config/ @@maintainer
29 |
30 | * @burnt-labs/Burnt_Engineering/Burnt_Protocol
31 |
32 | .github/ @burnt-labs/Burnt_DevOps
33 | .goreleaser @burnt-labs/Burnt_DevOps
34 | Dockerfile @burnt-labs/Burnt_DevOps
--------------------------------------------------------------------------------
/wasmbindings/test_utils.go:
--------------------------------------------------------------------------------
1 | package wasmbinding
2 |
3 | import (
4 | "crypto/rsa"
5 | "os"
6 |
7 | "github.com/lestrrat-go/jwx/v2/jwk"
8 | )
9 |
10 | func SetupKeys() (*rsa.PrivateKey, error) {
11 | // CreateAudience
12 | privateKeyBz, err := os.ReadFile("./keys/jwtRS256.key")
13 | if err != nil {
14 | return nil, err
15 | }
16 | jwKey, err := jwk.ParseKey(privateKeyBz, jwk.WithPEM(true))
17 | if err != nil {
18 | return nil, err
19 | }
20 | var privateKey rsa.PrivateKey
21 | err = jwKey.Raw(&privateKey)
22 | if err != nil {
23 | return nil, err
24 | }
25 | return &privateKey, nil
26 | }
27 |
28 | func SetupPublicKeys(rsaFile ...string) (*rsa.PrivateKey, jwk.Key, error) {
29 | // CreateAudience
30 | if rsaFile[0] == "" {
31 | rsaFile[0] = "./keys/jwtRS256.key"
32 | }
33 | privateKeyBz, err := os.ReadFile(rsaFile[0])
34 | if err != nil {
35 | return nil, nil, err
36 | }
37 | jwKey, err := jwk.ParseKey(privateKeyBz, jwk.WithPEM(true))
38 | if err != nil {
39 | return nil, nil, err
40 | }
41 |
42 | var privateKey rsa.PrivateKey
43 | err = jwKey.Raw(&privateKey)
44 | if err != nil {
45 | return nil, nil, err
46 | }
47 |
48 | return &privateKey, jwKey, nil
49 | }
50 |
--------------------------------------------------------------------------------
/app/encoding.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "testing"
5 |
6 | wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
7 |
8 | dbm "github.com/cosmos/cosmos-db"
9 |
10 | "cosmossdk.io/log"
11 |
12 | simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
13 |
14 | "github.com/burnt-labs/xion/app/params"
15 | )
16 |
17 | // MakeEncodingConfig creates a new EncodingConfig with all modules registered
18 | func MakeEncodingConfig(t testing.TB) params.EncodingConfig {
19 | // we "pre"-instantiate the application for getting the injected/configured encoding configuration
20 | // note, this is not necessary when using app wiring, as depinject can be directly used (see root_v2.go)
21 | tempApp := NewWasmApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), []wasmkeeper.Option{})
22 | return makeEncodingConfig(tempApp)
23 | }
24 |
25 | func makeEncodingConfig(tempApp *WasmApp) params.EncodingConfig {
26 | encodingConfig := params.EncodingConfig{
27 | InterfaceRegistry: tempApp.InterfaceRegistry(),
28 | Codec: tempApp.AppCodec(),
29 | TxConfig: tempApp.TxConfig(),
30 | Amino: tempApp.LegacyAmino(),
31 | }
32 | return encodingConfig
33 | }
34 |
--------------------------------------------------------------------------------
/x/globalfee/types/genesis.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/json"
5 |
6 | errorsmod "cosmossdk.io/errors"
7 |
8 | "github.com/cosmos/cosmos-sdk/codec"
9 | )
10 |
11 | // NewGenesisState - Create a new genesis state
12 | func NewGenesisState(params Params) *GenesisState {
13 | return &GenesisState{
14 | Params: params,
15 | }
16 | }
17 |
18 | // DefaultGenesisState - Return a default genesis state
19 | func DefaultGenesisState() *GenesisState {
20 | return NewGenesisState(DefaultParams())
21 | }
22 |
23 | // GetGenesisStateFromAppState returns x/auth GenesisState given raw application
24 | // genesis state.
25 | func GetGenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMessage) *GenesisState {
26 | var genesisState GenesisState
27 |
28 | if appState[ModuleName] != nil {
29 | cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState)
30 | } else {
31 | // Return default genesis state when module state is not present
32 | return DefaultGenesisState()
33 | }
34 |
35 | return &genesisState
36 | }
37 |
38 | func ValidateGenesis(data GenesisState) error {
39 | if err := data.Params.ValidateBasic(); err != nil {
40 | return errorsmod.Wrap(err, "globalfee params")
41 | }
42 |
43 | return nil
44 | }
45 |
--------------------------------------------------------------------------------
/x/jwk/client/cli/util.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "encoding/json"
5 | "os"
6 |
7 | "github.com/lestrrat-go/jwx/v2/jwk"
8 | "github.com/spf13/cobra"
9 |
10 | "github.com/cosmos/cosmos-sdk/client"
11 | "github.com/cosmos/cosmos-sdk/client/flags"
12 | )
13 |
14 | func CmdConvertPemToJSON() *cobra.Command {
15 | cmd := &cobra.Command{
16 | Use: "convert-pem [file] [alg | optional]",
17 | Short: "Convert PEM to JSON",
18 | Args: cobra.RangeArgs(1, 2),
19 | RunE: func(cmd *cobra.Command, args []string) (err error) {
20 | publicKeyBz, err := os.ReadFile(args[0])
21 | if err != nil {
22 | return err
23 | }
24 | publicKey, err := jwk.ParseKey(publicKeyBz, jwk.WithPEM(true))
25 | if err != nil {
26 | return err
27 | }
28 |
29 | if len(args) == 2 {
30 | err = publicKey.Set("alg", args[1])
31 | if err != nil {
32 | return err
33 | }
34 | }
35 |
36 | publicKeyJSON, err := json.Marshal(publicKey)
37 | if err != nil {
38 | return err
39 | }
40 |
41 | clientCtx, err := client.GetClientQueryContext(cmd)
42 | if err != nil {
43 | return err
44 | }
45 |
46 | return clientCtx.PrintBytes(publicKeyJSON)
47 | },
48 | }
49 |
50 | flags.AddQueryFlagsToCmd(cmd)
51 |
52 | return cmd
53 | }
54 |
--------------------------------------------------------------------------------
/x/jwk/client/cli/query_validate_jwt.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 |
7 | "github.com/spf13/cobra"
8 |
9 | "github.com/cosmos/cosmos-sdk/client"
10 | "github.com/cosmos/cosmos-sdk/client/flags"
11 |
12 | "github.com/burnt-labs/xion/x/jwk/types"
13 | )
14 |
15 | var _ = strconv.Itoa(0)
16 |
17 | func CmdValidateJWT() *cobra.Command {
18 | cmd := &cobra.Command{
19 | Use: "validate-jwt [aud] [sub] [sig-bytes]",
20 | Short: "Query ValidateJWT",
21 | Args: cobra.ExactArgs(3),
22 | RunE: func(cmd *cobra.Command, args []string) (err error) {
23 | reqAud := args[0]
24 | reqSub := args[1]
25 | reqSigBytes := args[2]
26 |
27 | clientCtx, err := client.GetClientQueryContext(cmd)
28 | if err != nil {
29 | return err
30 | }
31 |
32 | queryClient := types.NewQueryClient(clientCtx)
33 |
34 | params := &types.QueryValidateJWTRequest{
35 | Aud: reqAud,
36 | Sub: reqSub,
37 | SigBytes: reqSigBytes,
38 | }
39 |
40 | fmt.Printf("request: %s", params)
41 |
42 | res, err := queryClient.ValidateJWT(cmd.Context(), params)
43 | if err != nil {
44 | return err
45 | }
46 |
47 | return clientCtx.PrintProto(res)
48 | },
49 | }
50 |
51 | flags.AddQueryFlagsToCmd(cmd)
52 |
53 | return cmd
54 | }
55 |
--------------------------------------------------------------------------------
/.codecov.yml:
--------------------------------------------------------------------------------
1 | #
2 | # This codecov.yml is the default configuration for
3 | # all repositories on Codecov. You may adjust the settings
4 | # below in your own codecov.yml in your repository.
5 | #
6 | coverage:
7 | precision: 2
8 | round: down
9 | range: 70...100
10 |
11 | status:
12 | # Learn more at https://docs.codecov.io/docs/commit-status
13 | project:
14 | default:
15 | threshold: 1% # allow this much decrease on project
16 | app:
17 | target: 70%
18 | flags:
19 | - app
20 | modules:
21 | target: 70%
22 | flags:
23 | - modules
24 | client:
25 | flags:
26 | - client
27 | changes: false
28 |
29 | comment:
30 | layout: "reach, diff, files"
31 | behavior: default # update if exists else create new
32 | require_changes: true
33 |
34 | flags:
35 | app:
36 | paths:
37 | - "app/"
38 | modules:
39 | paths:
40 | - "x/"
41 | - "!x/**/client/" # ignore client package
42 | client:
43 | paths:
44 | - "x/**/client/"
45 |
46 | ignore:
47 | - "cmd/"
48 | - "contrib/"
49 | - "docs/"
50 | - "docker/"
51 | - "scripts/"
52 | - "*.md"
53 | - "*.rst"
54 | - "x/**/*.pb.go"
55 | - "x/**/*.pb.gw.go"
56 | - "x/**/test_common.go"
57 | - "x/**/testdata/"
58 |
--------------------------------------------------------------------------------
/x/jwk/types/keys_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestModuleConstants(t *testing.T) {
10 | require.Equal(t, "jwk", ModuleName)
11 | require.Equal(t, "jwk", StoreKey)
12 | require.Equal(t, "jwk", RouterKey)
13 | }
14 |
15 | func TestConstantsAreConsistent(t *testing.T) {
16 | // Ensure all constants are consistent with each other
17 | require.Equal(t, ModuleName, StoreKey)
18 | require.Equal(t, ModuleName, RouterKey)
19 | }
20 |
21 | func TestKeyPrefix(t *testing.T) {
22 | tests := []struct {
23 | name string
24 | prefix string
25 | expected []byte
26 | }{
27 | {
28 | name: "empty string",
29 | prefix: "",
30 | expected: []byte(""),
31 | },
32 | {
33 | name: "simple prefix",
34 | prefix: "test",
35 | expected: []byte("test"),
36 | },
37 | {
38 | name: "prefix with slash",
39 | prefix: "audience/",
40 | expected: []byte("audience/"),
41 | },
42 | {
43 | name: "complex prefix",
44 | prefix: "audience/claim/",
45 | expected: []byte("audience/claim/"),
46 | },
47 | }
48 |
49 | for _, tt := range tests {
50 | t.Run(tt.name, func(t *testing.T) {
51 | result := KeyPrefix(tt.prefix)
52 | require.Equal(t, tt.expected, result)
53 | })
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/wasmbindings/grpc_plugin.go:
--------------------------------------------------------------------------------
1 | package wasmbinding
2 |
3 | import (
4 | "fmt"
5 |
6 | wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types"
7 |
8 | abci "github.com/cometbft/cometbft/abci/types"
9 |
10 | "github.com/cosmos/gogoproto/proto"
11 |
12 | "github.com/cosmos/cosmos-sdk/baseapp"
13 | sdk "github.com/cosmos/cosmos-sdk/types"
14 | )
15 |
16 | func GrpcQuerier(queryRouter baseapp.GRPCQueryRouter) func(ctx sdk.Context, request *wasmvmtypes.GrpcQuery) (proto.Message, error) {
17 | return func(ctx sdk.Context, request *wasmvmtypes.GrpcQuery) (proto.Message, error) {
18 | protoResponse, err := GetWhitelistedQuery(request.Path)
19 | if err != nil {
20 | return nil, err
21 | }
22 |
23 | route := queryRouter.Route(request.Path)
24 | if route == nil {
25 | return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("No route to query '%s'", request.Path)}
26 | }
27 |
28 | res, err := route(ctx, &abci.RequestQuery{
29 | Data: request.Data,
30 | Path: request.Path,
31 | })
32 | if err != nil {
33 | return nil, err
34 | }
35 |
36 | if res.Value == nil {
37 | return nil, fmt.Errorf("res returned from abci query route is nil")
38 | }
39 | err = proto.Unmarshal(res.Value, protoResponse)
40 | if err != nil {
41 | return nil, err
42 | }
43 |
44 | return protoResponse, nil
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/x/globalfee/ante/ante_test.go:
--------------------------------------------------------------------------------
1 | package ante
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "cosmossdk.io/math"
9 |
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | )
12 |
13 | // Test utility functions
14 | func TestUtilityFunctions(t *testing.T) {
15 | // Test MaxCoins function
16 | coins1 := sdk.DecCoins{sdk.NewDecCoinFromDec("uxion", math.LegacyNewDecWithPrec(1, 3))}
17 | coins2 := sdk.DecCoins{sdk.NewDecCoinFromDec("uxion", math.LegacyNewDecWithPrec(2, 3))}
18 | result := MaxCoins(coins1, coins2)
19 | expected := sdk.DecCoins{sdk.NewDecCoinFromDec("uxion", math.LegacyNewDecWithPrec(2, 3))}
20 | require.Equal(t, expected, result)
21 |
22 | // Test IsAllGT function
23 | require.True(t, IsAllGT(coins2, coins1))
24 | require.False(t, IsAllGT(coins1, coins2))
25 | require.False(t, IsAllGT(coins1, coins1))
26 |
27 | // Test DenomsSubsetOf function
28 | require.True(t, DenomsSubsetOf(coins1, coins1))
29 | subset := sdk.DecCoins{sdk.NewDecCoinFromDec("uxion", math.LegacyNewDecWithPrec(1, 3))}
30 | superset := sdk.DecCoins{
31 | sdk.NewDecCoinFromDec("uxion", math.LegacyNewDecWithPrec(1, 3)),
32 | sdk.NewDecCoinFromDec("stake", math.LegacyNewDecWithPrec(1, 3)),
33 | }.Sort() // Ensure coins are sorted
34 | require.True(t, DenomsSubsetOf(subset, superset))
35 | require.False(t, DenomsSubsetOf(superset, subset))
36 | }
37 |
--------------------------------------------------------------------------------
/.github/workflows/binaries-darwin.yaml:
--------------------------------------------------------------------------------
1 | name: Build Darwin Binaries
2 |
3 | # reusable workflow, do not add triggers
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build-binaries:
10 | name: Build xiond-${{ matrix.os }}-${{ matrix.arch }}
11 | runs-on: 'ubuntu-latest'
12 |
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | os:
17 | - darwin
18 | arch:
19 | - amd64
20 | - arm64
21 |
22 | steps:
23 | - name: Check Out Code
24 | uses: actions/checkout@v5
25 | with:
26 | fetch-depth: 0
27 |
28 | - name: Set Go Version
29 | run: sed -En 's/^go (.*)$/GO_VERSION=\1/p' go.mod >> $GITHUB_ENV
30 |
31 | - name: Set up Go
32 | uses: actions/setup-go@v5
33 | with:
34 | go-version: ${{ env.GO_VERSION }}
35 |
36 | - name: Build darwin Binary
37 | env:
38 | GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
39 | run: |
40 | make build-${{ matrix.os }}-${{ matrix.arch }}
41 |
42 | - name: Upload Binary
43 | uses: actions/upload-artifact@v4
44 | with:
45 | name: xiond-${{ matrix.os }}-${{ matrix.arch }}
46 | path: dist/**/xiond-${{ matrix.os }}-${{ matrix.arch }}
47 | retention-days: 3
48 | if-no-files-found: error
49 |
--------------------------------------------------------------------------------
/x/jwk/types/genesis.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "fmt"
5 |
6 | errorsmod "cosmossdk.io/errors"
7 |
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
10 | )
11 |
12 | // DefaultIndex is the default global index
13 | const DefaultIndex uint64 = 1
14 |
15 | // DefaultGenesis returns the default genesis state
16 | func DefaultGenesis() *GenesisState {
17 | return &GenesisState{
18 | AudienceList: []Audience{},
19 | // this line is used by starport scaffolding # genesis/types/default
20 | Params: DefaultParams(),
21 | }
22 | }
23 |
24 | // Validate performs basic genesis state validation returning an error upon any
25 | // failure.
26 | func (gs GenesisState) Validate() error {
27 | // Check for duplicated index in audience
28 | audienceIndexMap := make(map[string]struct{})
29 |
30 | for _, elem := range gs.AudienceList {
31 | _, err := sdk.AccAddressFromBech32(elem.Admin)
32 | if err != nil {
33 | return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid admin address (%s)", err)
34 | }
35 |
36 | index := string(AudienceKey(elem.Aud))
37 | if _, ok := audienceIndexMap[index]; ok {
38 | return fmt.Errorf("duplicated index for audience")
39 | }
40 | audienceIndexMap[index] = struct{}{}
41 | }
42 | // this line is used by starport scaffolding # genesis/types/validate
43 |
44 | return gs.Params.Validate()
45 | }
46 |
--------------------------------------------------------------------------------
/x/xion/types/genesis.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 |
7 | "github.com/cosmos/cosmos-sdk/codec"
8 | "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | // Validate performs basic validation of supply genesis data returning an
12 | // error for any failed validation criteria.
13 | func (gs GenesisState) Validate() error {
14 | if gs.PlatformPercentage > 10000 {
15 | return errors.New("unable to set platform percentage to greater than 100%")
16 | }
17 |
18 | return nil
19 | }
20 |
21 | // NewGenesisState creates a new genesis state.
22 | func NewGenesisState(platformPercentage uint32, platformMinimums types.Coins) *GenesisState {
23 | rv := &GenesisState{
24 | PlatformPercentage: platformPercentage,
25 | PlatformMinimums: platformMinimums,
26 | }
27 | return rv
28 | }
29 |
30 | // DefaultGenesisState returns a default bank module genesis state.
31 | func DefaultGenesisState() *GenesisState {
32 | return NewGenesisState(0, types.Coins{})
33 | }
34 |
35 | // GetGenesisStateFromAppState returns x/bank GenesisState given raw application
36 | // genesis state.
37 | func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *GenesisState {
38 | var genesisState GenesisState
39 |
40 | if appState[ModuleName] != nil {
41 | cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState)
42 | }
43 |
44 | return &genesisState
45 | }
46 |
--------------------------------------------------------------------------------
/x/mint/types/codec.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/codec"
5 | "github.com/cosmos/cosmos-sdk/codec/legacy"
6 | "github.com/cosmos/cosmos-sdk/codec/types"
7 | cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | "github.com/cosmos/cosmos-sdk/types/msgservice"
10 | )
11 |
12 | var amino = codec.NewLegacyAmino()
13 |
14 | func init() {
15 | RegisterLegacyAminoCodec(amino)
16 | cryptocodec.RegisterCrypto(amino)
17 | sdk.RegisterLegacyAminoCodec(amino)
18 |
19 | // Register all Amino interfaces and concrete types on the authz and gov Amino codec
20 | // so that this can later be used to properly serialize MsgGrant and MsgExec
21 | // instances.
22 |
23 | // RegisterLegacyAminoCodec(groupcodec.Amino)
24 | }
25 |
26 | // RegisterLegacyAminoCodec registers concrete types on the LegacyAmino codec
27 | func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
28 | cdc.RegisterConcrete(Params{}, "xion/x/mint/Params", nil)
29 | legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "xion/x/mint/MsgUpdateParams")
30 | }
31 |
32 | // RegisterInterfaces registers the interfaces types with the interface registry.
33 | func RegisterInterfaces(registry types.InterfaceRegistry) {
34 | registry.RegisterImplementations(
35 | (*sdk.Msg)(nil),
36 | &MsgUpdateParams{},
37 | )
38 |
39 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
40 | }
41 |
--------------------------------------------------------------------------------
/.github/workflows/binaries-linux.yaml:
--------------------------------------------------------------------------------
1 | name: Build Linux Binaries
2 |
3 | # reusable workflow, do not add triggers
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build-binaries:
10 | name: Build xiond-${{ matrix.os }}-${{ matrix.arch }}
11 | runs-on: ${{ matrix.arch == 'arm64' && format('github-{0}', matrix.arch) || 'ubuntu-latest' }}
12 |
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | os:
17 | - linux
18 | arch:
19 | - amd64
20 | - arm64
21 |
22 | steps:
23 | - name: Check Out Code
24 | uses: actions/checkout@v5
25 | with:
26 | fetch-depth: 0
27 |
28 | - name: Set Go Version
29 | run: sed -En 's/^go (.*)$/GO_VERSION=\1/p' go.mod >> $GITHUB_ENV
30 |
31 | - name: Set up Go
32 | uses: actions/setup-go@v5
33 | with:
34 | go-version: ${{ env.GO_VERSION }}
35 |
36 | - name: Build Linux Binary
37 | env:
38 | GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
39 | run: |
40 | make build-${{ matrix.os }}-${{ matrix.arch }}
41 |
42 | - name: Upload Binary
43 | uses: actions/upload-artifact@v4
44 | with:
45 | name: xiond-${{ matrix.os }}-${{ matrix.arch }}
46 | path: dist/**/xiond-${{ matrix.os }}-${{ matrix.arch }}
47 | retention-days: 3
48 | if-no-files-found: error
49 |
--------------------------------------------------------------------------------
/x/xion/types/keys_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "github.com/burnt-labs/xion/x/xion/types"
9 | )
10 |
11 | func TestKeys(t *testing.T) {
12 | // Test PlatformPercentageKey
13 | require.NotNil(t, types.PlatformPercentageKey)
14 | require.Equal(t, []byte{0x00}, types.PlatformPercentageKey)
15 |
16 | // Test PlatformMinimumKey
17 | require.NotNil(t, types.PlatformMinimumKey)
18 | require.Equal(t, []byte{0x01}, types.PlatformMinimumKey)
19 | }
20 |
21 | func TestConstants(t *testing.T) {
22 | // Test ModuleName
23 | require.Equal(t, "xion", types.ModuleName)
24 |
25 | // Test StoreKey
26 | require.Equal(t, types.ModuleName, types.StoreKey)
27 | require.Equal(t, "xion", types.StoreKey)
28 |
29 | // Test RouterKey
30 | require.Equal(t, types.ModuleName, types.RouterKey)
31 | require.Equal(t, "xion", types.RouterKey)
32 |
33 | // Test QuerierRoute
34 | require.Equal(t, types.ModuleName, types.QuerierRoute)
35 | require.Equal(t, "xion", types.QuerierRoute)
36 |
37 | // Test all constants are consistent
38 | require.Equal(t, types.ModuleName, types.StoreKey)
39 | require.Equal(t, types.ModuleName, types.RouterKey)
40 | require.Equal(t, types.ModuleName, types.QuerierRoute)
41 | }
42 |
43 | func TestKeyUniqueness(t *testing.T) {
44 | // Ensure keys are unique
45 | require.NotEqual(t, types.PlatformPercentageKey, types.PlatformMinimumKey)
46 | }
47 |
--------------------------------------------------------------------------------
/make/lint.mk:
--------------------------------------------------------------------------------
1 | # Linting and formatting targets
2 |
3 | # Install formatting tools
4 | format-tools:
5 | go install mvdan.cc/gofumpt@v0.4.0
6 | go install github.com/client9/misspell/cmd/misspell@v0.3.4
7 | go install golang.org/x/tools/cmd/goimports@latest
8 |
9 | # Lint Go code
10 | lint: format-tools
11 | golangci-lint run --tests=false
12 | find . -name '*.go' -type f -not -path "./api/*" -not -path "*.git*" -not -path "*_test.go" -not -path "*.pb.go" -not -path "*.pb.gw.go" | xargs gofumpt -d
13 |
14 | # Format Go code
15 | format: format-tools
16 | golangci-lint run --fix
17 | find . -name '*.go' -type f -not -path "./api/*" -not -path "*.git*" -not -path "*.pb.go" -not -path "*.pb.gw.go" | xargs gofumpt -w
18 | find . -name '*.go' -type f -not -path "./api/*" -not -path "*.git*" -not -path "*.pb.go" -not -path "*.pb.gw.go" | xargs misspell -w
19 | find . -name '*.go' -type f -not -path "./api/*" -not -path "*.git*" -not -path "*.pb.go" -not -path "*.pb.gw.go" | xargs goimports -w -local github.com/burnt-labs/xiond
20 |
21 | # Help targets for lint module
22 | help-lint-brief:
23 | @echo " lint Lint and format code"
24 |
25 | help-lint:
26 | @echo "Linting targets:"
27 | @echo " lint Lint Go code"
28 | @echo " format Format Go code"
29 | @echo " format-tools Install formatting tools"
30 | @echo ""
31 |
32 | .PHONY: format-tools lint format help-lint help-lint-brief
33 |
--------------------------------------------------------------------------------
/x/mint/types/expected_keepers.go:
--------------------------------------------------------------------------------
1 | package types // noalias
2 |
3 | import (
4 | "context"
5 |
6 | "cosmossdk.io/math"
7 |
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | // StakingKeeper defines the expected staking keeper
12 | type StakingKeeper interface {
13 | StakingTokenSupply(ctx context.Context) (math.Int, error)
14 | TotalBondedTokens(ctx context.Context) (math.Int, error)
15 | BondedRatio(ctx context.Context) (math.LegacyDec, error)
16 | }
17 |
18 | // AccountKeeper defines the contract required for account APIs.
19 | type AccountKeeper interface {
20 | GetModuleAddress(name string) sdk.AccAddress
21 |
22 | // TODO remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862
23 | SetModuleAccount(context.Context, sdk.ModuleAccountI)
24 | GetModuleAccount(ctx context.Context, moduleName string) sdk.ModuleAccountI
25 | }
26 |
27 | // BankKeeper defines the contract needed to be fulfilled for banking and supply
28 | // dependencies.
29 | type BankKeeper interface {
30 | SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
31 | SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error
32 | MintCoins(ctx context.Context, name string, amt sdk.Coins) error
33 | GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
34 | BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins) error
35 | }
36 |
--------------------------------------------------------------------------------
/x/globalfee/client/cli/query.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 |
6 | "github.com/cosmos/cosmos-sdk/client"
7 | "github.com/cosmos/cosmos-sdk/client/flags"
8 |
9 | "github.com/burnt-labs/xion/x/globalfee/types"
10 | )
11 |
12 | func GetQueryCmd() *cobra.Command {
13 | queryCmd := &cobra.Command{
14 | Use: types.ModuleName,
15 | Short: "Querying commands for the global fee module",
16 | DisableFlagParsing: true,
17 | SuggestionsMinimumDistance: 2,
18 | RunE: client.ValidateCmd,
19 | }
20 | queryCmd.AddCommand(
21 | GetCmdShowGlobalFeeParams(),
22 | )
23 | return queryCmd
24 | }
25 |
26 | func GetCmdShowGlobalFeeParams() *cobra.Command {
27 | cmd := &cobra.Command{
28 | Use: "params",
29 | Short: "Show globalfee params",
30 | Long: "Show globalfee requirement: minimum_gas_prices, bypass_min_fee_msg_types, max_total_bypass_minFee_msg_gas_usage",
31 | Args: cobra.ExactArgs(0),
32 | RunE: func(cmd *cobra.Command, _ []string) error {
33 | clientCtx, err := client.GetClientQueryContext(cmd)
34 | if err != nil {
35 | return err
36 | }
37 |
38 | queryClient := types.NewQueryClient(clientCtx)
39 | res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{})
40 | if err != nil {
41 | return err
42 | }
43 | return clientCtx.PrintProto(&res.Params)
44 | },
45 | }
46 | flags.AddQueryFlagsToCmd(cmd)
47 | return cmd
48 | }
49 |
--------------------------------------------------------------------------------
/.github/workflows/trigger-homebrew.yaml:
--------------------------------------------------------------------------------
1 | name: Trigger Homebrew
2 |
3 | on:
4 | workflow_call: # is called from the create-release workflow
5 | workflow_dispatch: # manual trigger
6 |
7 | jobs:
8 | trigger-homebrew:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Trigger homebrew-xion workflow
12 | uses: peter-evans/repository-dispatch@v2
13 | with:
14 | token: ${{ secrets.REPO_DISPATCH_TOKEN }}
15 | repository: burnt-labs/homebrew-xion
16 | event-type: homebrew-release-trigger # NOTICE: must match the trigger in homebrew-xion workflow
17 | # -client-payload logic description-
18 | # Checks if it's a pre-release: github.event.release.prerelease == true - if the release is marked as a pre-release, it sets release_type to 'prerelease'
19 | # If not a pre-release, checks for latest release: github.event.release.prerelease == false && github.event.release.draft == false && github.event.release.make_latest == 'true' - ensures it's not a pre-release, not a draft, and is marked as the latest release
20 | # Sets latest tag: If all the above conditions are true, it sets release_type to 'latest'
21 | # Fallback to published: If none of the above conditions are met, it sets release_type to 'published'
22 | client-payload: |
23 | {
24 | "tag_name": "${{ github.event.release.tag_name }}",
25 | "release_name": "${{ github.event.release.name }}"
26 | }
27 |
--------------------------------------------------------------------------------
/contrib/local/setup_wasmd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o errexit -o nounset -o pipefail
3 |
4 | PASSWORD=${PASSWORD:-1234567890}
5 | STAKE=${STAKE_TOKEN:-ustake}
6 | FEE=${FEE_TOKEN:-ucosm}
7 | CHAIN_ID=${CHAIN_ID:-testing}
8 | MONIKER=${MONIKER:-node001}
9 |
10 | wasmd init --chain-id "$CHAIN_ID" "$MONIKER"
11 | # staking/governance token is hardcoded in config, change this
12 | ## OSX requires: -i.
13 | sed -i. "s/\"stake\"/\"$STAKE\"/" "$HOME"/.wasmd/config/genesis.json
14 | if ! wasmd keys show validator --keyring-backend=test; then
15 | (
16 | echo "$PASSWORD"
17 | echo "$PASSWORD"
18 | ) | wasmd keys add validator --keyring-backend=test
19 | fi
20 | # hardcode the validator account for this instance
21 | echo "$PASSWORD" | wasmd genesis add-genesis-account validator "1000000000$STAKE,1000000000$FEE" --keyring-backend=test
22 | # (optionally) add a few more genesis accounts
23 | for addr in "$@"; do
24 | echo "$addr"
25 | wasmd genesis add-genesis-account "$addr" "1000000000$STAKE,1000000000$FEE" --keyring-backend=test
26 | done
27 | # submit a genesis validator tx
28 | ## Workraround for https://github.com/cosmos/cosmos-sdk/issues/8251
29 | (
30 | echo "$PASSWORD"
31 | echo "$PASSWORD"
32 | echo "$PASSWORD"
33 | ) | wasmd genesis gentx validator "250000000$STAKE" --chain-id="$CHAIN_ID" --amount="250000000$STAKE" --keyring-backend=test
34 | ## should be:
35 | # (echo "$PASSWORD"; echo "$PASSWORD"; echo "$PASSWORD") | xiond gentx validator "250000000$STAKE" --chain-id="$CHAIN_ID"
36 | wasmd genesis collect-gentxs
37 |
--------------------------------------------------------------------------------
/contrib/prometheus/README.md:
--------------------------------------------------------------------------------
1 | # Setup
2 | Enable prometheus metrics in wasmd:
3 |
4 | * Edit `$HOME/config/app.toml`
5 | ```toml
6 | [telemetry]
7 |
8 | # Enabled enables the application telemetry functionality. When enabled,
9 | # an in-memory sink is also enabled by default. Operators may also enabled
10 | # other sinks such as Prometheus.
11 | enabled =true
12 | # ...
13 |
14 | # PrometheusRetentionTime, when positive, enables a Prometheus metrics sink.
15 | prometheus-retention-time = 15
16 | ```
17 |
18 | `retention-time` must be >0 (see prometheus scrape config)
19 |
20 |
21 | * Edit `$HOME/config/config.toml`
22 | ```toml
23 | [instrumentation]
24 |
25 | # When true, Prometheus metrics are served under /metrics on
26 | # PrometheusListenAddr.
27 | # Check out the documentation for the list of available metrics.
28 | prometheus = true
29 | ```
30 |
31 | Test manually at:
32 | `http://localhost:1317/metrics?format=prometheus`
33 |
34 | Note the `format` parameter in the request for the endpoint:
35 |
36 |
37 | # Local testing
38 | ## Run Prometheus
39 | ```sh
40 | # port 9090 is used by xiond already
41 | docker run -it -v $(pwd)/contrib/prometheus:/prometheus -p9091:9090 prom/prometheus --config.file=/prometheus/prometheus.yaml
42 | ```
43 | * Open [console](http://localhost:9091) and find `wasm_`service metrics
44 |
45 | ## Run Grafana
46 |
47 | ```shell
48 | docker run -it -p 3000:3000 grafana/grafana
49 | ```
50 | * Add Prometheus data source
51 | `http://host.docker.internal:9091`
52 | ### Labels
53 | * `wasm_contract_create` = nanosec
--------------------------------------------------------------------------------
/proto/xion/mint/v1/event.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.mint.v1;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "cosmos_proto/cosmos.proto";
6 |
7 | option go_package = "github.com/burnt-labs/xion/x/mint/types";
8 |
9 | // MintIncentiveTokens defines an event emitted on each block from the mint
10 | // module EndBlocker
11 | message MintIncentiveTokens {
12 | // The ratio of bonded tokens to total supply
13 | string bonded_ratio = 1 [
14 | (cosmos_proto.scalar) = "cosmos.Dec",
15 | (gogoproto.moretags) = "yaml:\"bonded_ratio\"",
16 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
17 | (gogoproto.nullable) = false
18 | ];
19 | // The current inflation rate
20 | string inflation = 2 [
21 | (cosmos_proto.scalar) = "cosmos.Dec",
22 | (gogoproto.moretags) = "yaml:\"inflation\"",
23 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
24 | (gogoproto.nullable) = false
25 | ];
26 | // The total annual provisions for minting
27 | string annual_provisions = 3 [
28 | (gogoproto.moretags) = "yaml:\"annual_provisions\"",
29 | (cosmos_proto.scalar) = "cosmos.Dec",
30 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
31 | (gogoproto.nullable) = false
32 | ];
33 | // The amount of tokens needed for incentives
34 | uint64 needed_amount = 4;
35 | // The amount of tokens collected for incentives
36 | uint64 collected_amount = 5;
37 | // The amount of tokens minted
38 | uint64 minted_amount = 6;
39 | // The amount of tokens burned
40 | uint64 burned_amount = 7;
41 | }
--------------------------------------------------------------------------------
/x/globalfee/migrations/v2/migration.go:
--------------------------------------------------------------------------------
1 | package v2
2 |
3 | import (
4 | sdk "github.com/cosmos/cosmos-sdk/types"
5 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
6 |
7 | "github.com/burnt-labs/xion/x/globalfee/types"
8 | )
9 |
10 | // MigrateStore performs in-place params migrations of
11 | // BypassMinFeeMsgTypes and MaxTotalBypassMinFeeMsgGasUsage
12 | // from app.toml to globalfee params.
13 | // The migration includes:
14 | // Add bypass-min-fee-msg-types params that are set
15 | // ["/ibc.core.channel.v1.MsgRecvPacket",
16 | // "/ibc.core.channel.v1.MsgAcknowledgement",
17 | // "/ibc.core.client.v1.MsgUpdateClient",
18 | // "/ibc.core.channel.v1.MsgTimeout",
19 | // "/ibc.core.channel.v1.MsgTimeoutOnClose"] as default and
20 | // add MaxTotalBypassMinFeeMsgGasUsage that is set 1_000_000 as default.
21 | func MigrateStore(ctx sdk.Context, globalfeeSubspace paramtypes.Subspace) error {
22 | if !globalfeeSubspace.HasKeyTable() {
23 | globalfeeSubspace = globalfeeSubspace.WithKeyTable(types.ParamKeyTable())
24 | }
25 |
26 | var oldGlobalMinGasPrices sdk.DecCoins
27 | globalfeeSubspace.Get(ctx, types.ParamStoreKeyMinGasPrices, &oldGlobalMinGasPrices)
28 | defaultParams := types.DefaultParams()
29 | params := types.Params{
30 | MinimumGasPrices: oldGlobalMinGasPrices,
31 | BypassMinFeeMsgTypes: defaultParams.BypassMinFeeMsgTypes,
32 | MaxTotalBypassMinFeeMsgGasUsage: defaultParams.MaxTotalBypassMinFeeMsgGasUsage,
33 | }
34 |
35 | globalfeeSubspace.SetParamSet(ctx, ¶ms)
36 |
37 | return nil
38 | }
39 |
--------------------------------------------------------------------------------
/app/config.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
5 |
6 | serverconfig "github.com/cosmos/cosmos-sdk/server/config"
7 |
8 | "github.com/burnt-labs/xion/indexer"
9 | )
10 |
11 | // CustomConfig defines a custom app.toml configuration file
12 | // that contains default wasm configuration and
13 | // indexer configuration
14 | type CustomConfig struct {
15 | serverconfig.Config
16 | Wasm wasmtypes.NodeConfig `mapstructure:"wasm" json:"wasm"`
17 | Indexer indexer.Config `mapstructure:"config" json:"config"`
18 | }
19 |
20 | func CustomconfigTemplate(config wasmtypes.NodeConfig) string {
21 | return serverconfig.DefaultConfigTemplate + wasmtypes.ConfigTemplate(config) + indexer.DefaultConfigTemplate()
22 | }
23 |
24 | func DefaultConfig() (string, any) {
25 | // Default SDK config params
26 | serverConfig := serverconfig.DefaultConfig()
27 | serverConfig.MinGasPrices = "0uxion"
28 |
29 | // Default x/wasm configuration
30 | wasmConfig := wasmtypes.DefaultNodeConfig()
31 | simulationLimit := uint64(50_000_00)
32 | wasmConfig.SimulationGasLimit = &simulationLimit // 50M Gas
33 | wasmConfig.SmartQueryGasLimit = 50_000_00 // 50M Gas
34 | wasmConfig.MemoryCacheSize = 1024 // 1GB memory caache
35 |
36 | // Default Indexer Params
37 | indexerConfig := indexer.DefaultConfig()
38 | customConfig := CustomConfig{
39 | Config: *serverConfig,
40 | Wasm: wasmConfig,
41 | Indexer: indexerConfig,
42 | }
43 |
44 | return CustomconfigTemplate(wasmConfig), customConfig
45 | }
46 |
--------------------------------------------------------------------------------
/x/mint/types/codec_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "github.com/cosmos/cosmos-sdk/codec"
9 | "github.com/cosmos/cosmos-sdk/codec/types"
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | )
12 |
13 | func TestRegisterLegacyAminoCodec(t *testing.T) {
14 | cdc := codec.NewLegacyAmino()
15 |
16 | // Test that RegisterLegacyAminoCodec doesn't panic
17 | require.NotPanics(t, func() {
18 | RegisterLegacyAminoCodec(cdc)
19 | })
20 |
21 | // Test that Params can be marshaled/unmarshaled
22 | params := DefaultParams()
23 |
24 | // Test marshaling
25 | bz, err := cdc.MarshalJSON(params)
26 | require.NoError(t, err)
27 | require.NotEmpty(t, bz)
28 |
29 | // Test unmarshaling
30 | var unmarshaled Params
31 | err = cdc.UnmarshalJSON(bz, &unmarshaled)
32 | require.NoError(t, err)
33 | require.Equal(t, params, unmarshaled)
34 | }
35 |
36 | func TestRegisterInterfaces(t *testing.T) {
37 | registry := types.NewInterfaceRegistry()
38 |
39 | // Test that RegisterInterfaces doesn't panic
40 | require.NotPanics(t, func() {
41 | RegisterInterfaces(registry)
42 | })
43 |
44 | // Test that MsgUpdateParams is registered as sdk.Msg
45 | msg := &MsgUpdateParams{}
46 | require.Implements(t, (*sdk.Msg)(nil), msg)
47 |
48 | // Test that we can pack/unpack the message
49 | any, err := types.NewAnyWithValue(msg)
50 | require.NoError(t, err)
51 |
52 | var unpacked sdk.Msg
53 | err = registry.UnpackAny(any, &unpacked)
54 | require.NoError(t, err)
55 | require.Equal(t, msg, unpacked)
56 | }
57 |
--------------------------------------------------------------------------------
/x/xion/client/cli/suite_test.go:
--------------------------------------------------------------------------------
1 | package cli_test
2 |
3 | import (
4 | "io"
5 | "testing"
6 |
7 | "github.com/CosmWasm/wasmd/x/wasm"
8 | "github.com/stretchr/testify/suite"
9 |
10 | rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
11 |
12 | feegrant "cosmossdk.io/x/feegrant/module"
13 |
14 | "github.com/cosmos/cosmos-sdk/client"
15 | "github.com/cosmos/cosmos-sdk/crypto/keyring"
16 | clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
17 | testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
18 | authz "github.com/cosmos/cosmos-sdk/x/authz/module"
19 | "github.com/cosmos/cosmos-sdk/x/bank"
20 | "github.com/cosmos/cosmos-sdk/x/gov"
21 | "github.com/cosmos/cosmos-sdk/x/staking"
22 | )
23 |
24 | type CLITestSuite struct {
25 | suite.Suite
26 |
27 | kr keyring.Keyring
28 | encCfg testutilmod.TestEncodingConfig
29 | baseCtx client.Context
30 | }
31 |
32 | func TestMigrateTestSuite(t *testing.T) {
33 | suite.Run(t, new(CLITestSuite))
34 | }
35 |
36 | func (s *CLITestSuite) SetupSuite() {
37 | s.encCfg = testutilmod.MakeTestEncodingConfig(bank.AppModuleBasic{}, feegrant.AppModuleBasic{}, authz.AppModuleBasic{}, staking.AppModuleBasic{}, gov.AppModuleBasic{}, wasm.AppModuleBasic{})
38 | s.kr = keyring.NewInMemory(s.encCfg.Codec)
39 | s.baseCtx = client.Context{}.
40 | WithKeyring(s.kr).
41 | WithTxConfig(s.encCfg.TxConfig).
42 | WithCodec(s.encCfg.Codec).
43 | WithClient(clitestutil.MockCometRPC{Client: rpcclientmock.Client{}}).
44 | WithAccountRetriever(client.MockAccountRetriever{}).
45 | WithOutput(io.Discard)
46 | }
47 |
--------------------------------------------------------------------------------
/indexer/authz_decode_test.go:
--------------------------------------------------------------------------------
1 | package indexer
2 |
3 | import (
4 | "testing"
5 |
6 | "cosmossdk.io/collections"
7 |
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | func TestAuthzDecode(t *testing.T) {
12 | // This test creates a proper collections-encoded key and verifies it can be decoded
13 | granter := sdk.AccAddress([]byte("granter_address_____"))
14 | grantee := sdk.AccAddress([]byte("grantee_address_____"))
15 | msgType := "/cosmos.bank.v1beta1.MsgSend"
16 |
17 | // Encode using collections codec
18 | codec := collections.TripleKeyCodec(sdk.AccAddressKey, sdk.AccAddressKey, collections.StringKey)
19 | triple := collections.Join3(granter, grantee, msgType)
20 | size := codec.Size(triple)
21 | buf := make([]byte, size)
22 | _, err := codec.Encode(buf, triple)
23 | if err != nil {
24 | t.Fatal(err)
25 | }
26 |
27 | // Add prefix
28 | key := append([]byte{0x01}, buf...)
29 |
30 | // Decode using our function
31 | decodedGranter, decodedGrantee, decodedMsgType := parseGrantStoreKey(key)
32 |
33 | if decodedGranter.String() != granter.String() {
34 | t.Errorf("granter mismatch: got %s, want %s", decodedGranter.String(), granter.String())
35 | }
36 | if decodedGrantee.String() != grantee.String() {
37 | t.Errorf("grantee mismatch: got %s, want %s", decodedGrantee.String(), grantee.String())
38 | }
39 | if decodedMsgType != msgType {
40 | t.Errorf("msgType mismatch: got %q (len=%d), want %q (len=%d)", decodedMsgType, len(decodedMsgType), msgType, len(msgType))
41 | t.Logf("Key hex: %x", key)
42 | t.Logf("Buf hex: %x", buf)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/proto/xion/mint/v1/tx.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.mint.v1;
3 |
4 | option go_package = "github.com/burnt-labs/xion/x/mint/types";
5 |
6 | import "cosmos/msg/v1/msg.proto";
7 | import "amino/amino.proto";
8 | import "xion/mint/v1/mint.proto";
9 | import "gogoproto/gogo.proto";
10 | import "cosmos_proto/cosmos.proto";
11 |
12 | // Msg defines the x/mint Msg service.
13 | service Msg {
14 | option (cosmos.msg.v1.service) = true;
15 |
16 | // UpdateParams defines a governance operation for updating the x/mint module
17 | // parameters. The authority is defaults to the x/gov module account.
18 | //
19 | // Since: cosmos-sdk 0.47
20 | rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);
21 | }
22 |
23 | // MsgUpdateParams is the Msg/UpdateParams request type.
24 | //
25 | // Since: cosmos-sdk 0.47
26 | message MsgUpdateParams {
27 | option (cosmos.msg.v1.signer) = "authority";
28 | option (amino.name) = "xion/x/mint/MsgUpdateParams";
29 |
30 | // authority is the address that controls the module (defaults to x/gov unless
31 | // overwritten).
32 | string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
33 |
34 | // params defines the x/mint parameters to update.
35 | //
36 | // NOTE: All parameters must be supplied.
37 | Params params = 2
38 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
39 | }
40 |
41 | // MsgUpdateParamsResponse defines the response structure for executing a
42 | // MsgUpdateParams message.
43 | //
44 | // Since: cosmos-sdk 0.47
45 | message MsgUpdateParamsResponse {}
46 |
--------------------------------------------------------------------------------
/.github/workflows/docker-scout.yaml:
--------------------------------------------------------------------------------
1 | name: Docker Scout
2 |
3 | # reusable workflow, do not add triggers
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | docker-scout:
10 | name: main
11 | runs-on: ubuntu-latest
12 | permissions:
13 | contents: read
14 | pull-requests: write
15 |
16 | strategy:
17 | fail-fast: false
18 | matrix:
19 | os:
20 | - linux
21 | arch:
22 | - amd64
23 | - arm64
24 |
25 | steps:
26 | - name: Login to Docker Hub
27 | uses: docker/login-action@v3
28 | with:
29 | username: ${{ secrets.DOCKER_HUB_USERNAME }}
30 | password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
31 |
32 | - name: Prepare environment
33 | run: |
34 | echo "DOCKER_FN=docker/${{ matrix.os }}/${{ matrix.arch }}.tar" | tr '/' '-' | tee -a $GITHUB_ENV
35 |
36 | - name: Download images
37 | uses: actions/download-artifact@v4
38 | with:
39 | path: ${{ runner.temp }}
40 | pattern: ${{ env.DOCKER_FN }}
41 | merge-multiple: true
42 |
43 | - name: Load images
44 | working-directory: ${{ runner.temp }}
45 | run: |
46 | ls -la
47 | docker load < ${{ env.DOCKER_FN }}
48 |
49 | - name: Run Docker Scout
50 | uses: docker/scout-action@v1
51 | with:
52 | command: cves
53 | only-fixed: true
54 | platform: ${{ matrix.os }}/${{ matrix.arch }}
55 | image: xion:${{ matrix.os }}-${{ matrix.arch }}
56 |
--------------------------------------------------------------------------------
/x/feeabs/types/epoch.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "errors"
5 | "time"
6 | )
7 |
8 | const (
9 | DefaultSwapPeriod = time.Minute * 2
10 | DefaultQueryPeriod = time.Minute * 1
11 | DefaultSwapEpochIdentifier = "swap"
12 | DefaultQueryEpochIdentifier = "query"
13 | // assume that query period is after 1 minute, thus a maximum of 32 minutes is enough
14 | // todo: should be a parameter
15 | // 1, 2, 4, 8, 16, 32
16 | ExponentialMaxJump = 32
17 | // after 4 jump, a connection is considered outdated
18 | ExponentialOutdatedJump = 4
19 | )
20 |
21 | func KeyPrefix(p string) []byte {
22 | return []byte(p)
23 | }
24 |
25 | // Validate also validates epoch info.
26 | func (epoch EpochInfo) Validate() error {
27 | if epoch.Identifier == "" {
28 | return errors.New("epoch identifier should NOT be empty")
29 | }
30 | if epoch.Duration == 0 {
31 | return errors.New("epoch duration should NOT be 0")
32 | }
33 | if epoch.CurrentEpoch < 0 {
34 | return errors.New("epoch CurrentEpoch must be non-negative")
35 | }
36 | if epoch.CurrentEpochStartHeight < 0 {
37 | return errors.New("epoch CurrentEpoch must be non-negative")
38 | }
39 | return nil
40 | }
41 |
42 | func NewGenesisEpochInfo(identifier string, duration time.Duration) EpochInfo {
43 | return EpochInfo{
44 | Identifier: identifier,
45 | StartTime: time.Time{},
46 | Duration: duration,
47 | CurrentEpoch: 0,
48 | CurrentEpochStartHeight: 0,
49 | CurrentEpochStartTime: time.Time{},
50 | EpochCountingStarted: false,
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/.github/workflows/publish-release.yaml:
--------------------------------------------------------------------------------
1 | name: Publish Release
2 |
3 | on:
4 | workflow_call: # is called from the create-release workflow
5 | workflow_dispatch: # manual trigger
6 | release: # triggered by release event
7 | types: [released]
8 | # Notice:
9 | # ref: https://docs.github.com/en/webhooks/webhook-events-and-payloads#release
10 | # - "published" type is happening when the release is marked as "latest"
11 | # - "released" type is happening when a release was published, or a pre-release was changed to a release.
12 | # - "prereleased" type is happening when a release was created and identified as a pre-release. A pre-release is a release that is not ready for production and may be unstable.
13 |
14 | concurrency: # With concurrency control: Only the latest workflow run executes, previous runs get cancelled
15 | group: ${{ github.workflow }}-${{ github.ref }}
16 | cancel-in-progress: true
17 |
18 | jobs:
19 | trigger-types:
20 | name: Trigger Types
21 | uses: burnt-labs/xion/.github/workflows/trigger-types.yaml@workflows/main
22 | secrets: inherit
23 | trigger-assets:
24 | name: Trigger Assets
25 | uses: burnt-labs/xion/.github/workflows/trigger-assets.yaml@workflows/main
26 | secrets: inherit
27 | trigger-homebrew:
28 | name: Trigger Homebrew
29 | uses: burnt-labs/xion/.github/workflows/trigger-homebrew.yaml@workflows/main
30 | secrets: inherit
31 | trigger-chain-registry:
32 | name: Trigger Chain Registry
33 | uses: burnt-labs/xion/.github/workflows/trigger-chain-registry.yaml@workflows/main
34 | secrets: inherit
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | run:
3 | tests: true
4 | linters:
5 | default: none
6 | enable:
7 | - bodyclose
8 | - copyloopvar
9 | - dogsled
10 | - errcheck
11 | - gocritic
12 | - gosec
13 | - govet
14 | - ineffassign
15 | - misspell
16 | - nakedret
17 | - revive
18 | - staticcheck
19 | - unconvert
20 | - unparam
21 | - unused
22 | settings:
23 | gocritic:
24 | disabled-checks:
25 | - appendAssign
26 | gosec:
27 | excludes:
28 | - G404
29 | - G115
30 | revive:
31 | rules:
32 | - name: "var-naming"
33 | disabled: true
34 | severity: "warning"
35 | arguments: []
36 | exclusions:
37 | generated: lax
38 | presets:
39 | - comments
40 | - common-false-positives
41 | - legacy
42 | - std-error-handling
43 | paths:
44 | - third_party$
45 | - builtin$
46 | - examples$
47 | issues:
48 | max-issues-per-linter: 0
49 | max-same-issues: 0
50 | formatters:
51 | enable:
52 | - gci
53 | - gofumpt
54 | settings:
55 | gci:
56 | sections:
57 | - standard
58 | - default
59 | - blank
60 | - dot
61 | - prefix(github.com/cometbft/cometbft)
62 | - prefix(github.com/cosmos)
63 | - prefix(cosmossdk.io)
64 | - prefix(github.com/cosmos/cosmos-sdk)
65 | - prefix(github.com/burnt-labs/xion)
66 | custom-order: true
67 | exclusions:
68 | generated: lax
69 | paths:
70 | - third_party$
71 | - builtin$
72 | - examples$
73 |
--------------------------------------------------------------------------------
/proto/buf.gen.pulsar.yaml:
--------------------------------------------------------------------------------
1 | version: v2
2 |
3 | managed:
4 | enabled: true
5 | override:
6 | - file_option: go_package_prefix
7 | value: github.com/burnt-labs/xion/api
8 | - file_option: go_package_prefix
9 | module: buf.build/cosmos/gogo-proto
10 | value: github.com/cosmos/gogoproto
11 | - file_option: go_package_prefix
12 | module: buf.build/cosmos/cosmos-proto
13 | value: github.com/cosmos/cosmos-proto
14 | - file_option: go_package
15 | module: buf.build/cosmos/cosmos-proto
16 | path: cosmos_proto/cosmos.proto
17 | value: github.com/cosmos/cosmos-proto
18 | - file_option: go_package_prefix
19 | module: buf.build/cosmos/cosmos-sdk
20 | value: cosmossdk.io/api
21 | - file_option: go_package
22 | module: buf.build/googleapis/googleapis
23 | path: google/api/annotations.proto
24 | value: google.golang.org/genproto/googleapis/api/annotations
25 | - file_option: go_package
26 | module: buf.build/googleapis/googleapis
27 | path: google/api/http.proto
28 | value: google.golang.org/genproto/googleapis/api/annotations
29 | - file_option: go_package
30 | module: buf.build/tendermint/tendermint
31 | path: tendermint/abci/types.proto
32 | value: github.com/cometbft/cometbft/abci/types
33 |
34 |
35 | plugins:
36 | - local: protoc-gen-go-pulsar
37 | out: ../api
38 | opt: paths=source_relative
39 | - local: protoc-gen-go-grpc
40 | out: ../api
41 | opt: paths=source_relative
42 | - local: protoc-gen-go-cosmos-orm
43 | out: ../api
44 | opt: paths=source_relative
45 |
--------------------------------------------------------------------------------
/x/mint/types/params_legacy.go:
--------------------------------------------------------------------------------
1 | /*
2 | NOTE: Usage of x/params to manage parameters is deprecated in favor of x/gov
3 | controlled execution of MsgUpdateParams messages. These types remains solely
4 | for migration purposes and will be removed in a future release.
5 | */
6 | package types
7 |
8 | import (
9 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
10 | )
11 |
12 | // Parameter store keys
13 | var (
14 | KeyMintDenom = []byte("MintDenom")
15 | KeyInflationRateChange = []byte("InflationRateChange")
16 | KeyInflationMax = []byte("InflationMax")
17 | KeyInflationMin = []byte("InflationMin")
18 | KeyGoalBonded = []byte("GoalBonded")
19 | KeyBlocksPerYear = []byte("BlocksPerYear")
20 | )
21 |
22 | // Deprecated: ParamTable for minting module.
23 | func ParamKeyTable() paramtypes.KeyTable {
24 | return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
25 | }
26 |
27 | // Implements params.ParamSet
28 | //
29 | // Deprecated.
30 | func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
31 | return paramtypes.ParamSetPairs{
32 | paramtypes.NewParamSetPair(KeyMintDenom, &p.MintDenom, validateMintDenom),
33 | paramtypes.NewParamSetPair(KeyInflationRateChange, &p.InflationRateChange, validateInflationRateChange),
34 | paramtypes.NewParamSetPair(KeyInflationMax, &p.InflationMax, validateInflationMax),
35 | paramtypes.NewParamSetPair(KeyInflationMin, &p.InflationMin, validateInflationMin),
36 | paramtypes.NewParamSetPair(KeyGoalBonded, &p.GoalBonded, validateGoalBonded),
37 | paramtypes.NewParamSetPair(KeyBlocksPerYear, &p.BlocksPerYear, validateBlocksPerYear),
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/x/xion/client/cli/query_platform_fee.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 |
6 | "github.com/cosmos/cosmos-sdk/client"
7 | "github.com/cosmos/cosmos-sdk/client/flags"
8 |
9 | "github.com/burnt-labs/xion/x/xion/types"
10 | )
11 |
12 | func CmdPlatformPercentage() *cobra.Command {
13 | cmd := &cobra.Command{
14 | Use: "platform-percentage",
15 | Short: "Get Platform Percentage",
16 | RunE: func(cmd *cobra.Command, _ []string) error {
17 | clientCtx, err := client.GetClientQueryContext(cmd)
18 | if err != nil {
19 | return err
20 | }
21 |
22 | queryClient := types.NewQueryClient(clientCtx)
23 |
24 | params := &types.QueryPlatformPercentageRequest{}
25 |
26 | res, err := queryClient.PlatformPercentage(cmd.Context(), params)
27 | if err != nil {
28 | return err
29 | }
30 |
31 | return clientCtx.PrintProto(res)
32 | },
33 | }
34 |
35 | flags.AddQueryFlagsToCmd(cmd)
36 |
37 | return cmd
38 | }
39 |
40 | func CmdPlatformMinimum() *cobra.Command {
41 | cmd := &cobra.Command{
42 | Use: "platform-minimum",
43 | Short: "Get Platform Minimum",
44 | RunE: func(cmd *cobra.Command, _ []string) error {
45 | clientCtx, err := client.GetClientQueryContext(cmd)
46 | if err != nil {
47 | return err
48 | }
49 |
50 | queryClient := types.NewQueryClient(clientCtx)
51 |
52 | params := &types.QueryPlatformMinimumRequest{}
53 |
54 | res, err := queryClient.PlatformMinimum(cmd.Context(), params)
55 | if err != nil {
56 | return err
57 | }
58 |
59 | return clientCtx.PrintProto(res)
60 | },
61 | }
62 |
63 | flags.AddQueryFlagsToCmd(cmd)
64 |
65 | return cmd
66 | }
67 |
--------------------------------------------------------------------------------
/x/mint/types/genesis.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "cosmossdk.io/math"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | )
8 |
9 | // InflationCalculationFn defines the function required to calculate inflation rate during
10 | // BeginBlock. It receives the minter and params stored in the keeper, along with the current
11 | // bondedRatio and returns the newly calculated inflation rate.
12 | // It can be used to specify a custom inflation calculation logic, instead of relying on the
13 | // default logic provided by the sdk.
14 | type InflationCalculationFn func(ctx sdk.Context, minter Minter, params Params, bondedRatio math.LegacyDec) math.LegacyDec
15 |
16 | // DefaultInflationCalculationFn is the default function used to calculate inflation.
17 | func DefaultInflationCalculationFn(_ sdk.Context, minter Minter, params Params, bondedRatio math.LegacyDec) math.LegacyDec {
18 | return minter.NextInflationRate(params, bondedRatio)
19 | }
20 |
21 | // NewGenesisState creates a new GenesisState object
22 | func NewGenesisState(minter Minter, params Params) *GenesisState {
23 | return &GenesisState{
24 | Minter: minter,
25 | Params: params,
26 | }
27 | }
28 |
29 | // DefaultGenesisState creates a default GenesisState object
30 | func DefaultGenesisState() *GenesisState {
31 | return &GenesisState{
32 | Minter: DefaultInitialMinter(),
33 | Params: DefaultParams(),
34 | }
35 | }
36 |
37 | // ValidateGenesis validates the provided genesis state to ensure the
38 | // expected invariants holds.
39 | func ValidateGenesis(data GenesisState) error {
40 | if err := data.Params.Validate(); err != nil {
41 | return err
42 | }
43 |
44 | return ValidateMinter(data.Minter)
45 | }
46 |
--------------------------------------------------------------------------------
/indexer/noop_service.go:
--------------------------------------------------------------------------------
1 | package indexer
2 |
3 | import (
4 | "context"
5 |
6 | abci "github.com/cometbft/cometbft/abci/types"
7 |
8 | "cosmossdk.io/log"
9 | storetypes "cosmossdk.io/store/types"
10 |
11 | "github.com/cosmos/cosmos-sdk/types/module"
12 | )
13 |
14 | // NoOpStreamService is a no-operation implementation of the StreamService
15 | // Used when the indexer cannot be initialized but we want the node to continue
16 | type NoOpStreamService struct {
17 | log log.Logger
18 | }
19 |
20 | // NewNoOpStreamService creates a new no-op stream service
21 | func NewNoOpStreamService(logger log.Logger) *NoOpStreamService {
22 | return &NoOpStreamService{
23 | log: logger.With("module", "indexer", "mode", "noop"),
24 | }
25 | }
26 |
27 | // ListenFinalizeBlock implements ABCIListener - no-op
28 | func (n *NoOpStreamService) ListenFinalizeBlock(ctx context.Context, req abci.RequestFinalizeBlock, res abci.ResponseFinalizeBlock) error {
29 | // No-op: just return nil to allow consensus to continue
30 | return nil
31 | }
32 |
33 | // ListenCommit implements ABCIListener - no-op
34 | func (n *NoOpStreamService) ListenCommit(ctx context.Context, res abci.ResponseCommit, changeSet []*storetypes.StoreKVPair) error {
35 | // No-op: just return nil to allow consensus to continue
36 | return nil
37 | }
38 |
39 | // Close implements io.Closer - no-op
40 | func (n *NoOpStreamService) Close() error {
41 | n.log.Info("Closing no-op indexer service")
42 | return nil
43 | }
44 |
45 | // RegisterServices implements the required interface - no-op
46 | func (n *NoOpStreamService) RegisterServices(configurator module.Configurator) error {
47 | n.log.Info("No-op indexer: skipping service registration")
48 | return nil
49 | }
50 |
--------------------------------------------------------------------------------
/.github/workflows/trigger-types.yaml:
--------------------------------------------------------------------------------
1 | name: Trigger Types
2 |
3 | on:
4 | workflow_call: # is called from the create-release workflow
5 | workflow_dispatch: # manual trigger
6 |
7 | jobs:
8 | trigger-types:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Trigger xion-types workflow
12 | uses: peter-evans/repository-dispatch@v2
13 | with:
14 | token: ${{ secrets.REPO_DISPATCH_TOKEN }}
15 | repository: burnt-labs/xion-types
16 | event-type: xion-types-release-trigger # NOTICE: must match the trigger in xion-types workflow
17 | # -client-payload logic description-
18 | # Checks if it's a pre-release: github.event.release.prerelease == true - if the release is marked as a pre-release, it sets release_type to 'prerelease'
19 | # If not a pre-release, checks for latest release: github.event.release.prerelease == false && github.event.release.draft == false && github.event.release.make_latest == 'true' - ensures it's not a pre-release, not a draft, and is marked as the latest release
20 | # Sets latest tag: If all the above conditions are true, it sets release_type to 'latest'
21 | # Fallback to published: If none of the above conditions are met, it sets release_type to 'published'
22 | client-payload: |
23 | {
24 | "release_type": "${{ github.event.release.prerelease == true && 'prerelease' || (github.event.release.prerelease == false && github.event.release.draft == false && github.event.release.make_latest == 'true' && 'latest' || 'published') }}",
25 | "tag_name": "${{ github.event.release.tag_name }}",
26 | "release_name": "${{ github.event.release.name }}"
27 | }
28 |
--------------------------------------------------------------------------------
/proto/xion/globalfee/v1/genesis.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.globalfee.v1;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "cosmos/base/v1beta1/coin.proto";
6 |
7 | option go_package = "github.com/burnt-labs/xion/x/globalfee/types";
8 |
9 | // GenesisState - initial state of module
10 | message GenesisState {
11 | // Params of this module
12 | Params params = 1 [
13 | (gogoproto.nullable) = false,
14 | (gogoproto.jsontag) = "params,omitempty"
15 | ];
16 | }
17 |
18 | // Params defines the set of module parameters.
19 | message Params {
20 | // minimum_gas_prices stores the minimum gas price(s) for all TX on the chain.
21 | // When multiple coins are defined then they are accepted alternatively.
22 | // The list must be sorted by denoms asc. No duplicate denoms or zero amount
23 | // values allowed. For more information see
24 | // https://docs.cosmos.network/main/modules/auth#concepts
25 | repeated cosmos.base.v1beta1.DecCoin minimum_gas_prices = 1 [
26 | (gogoproto.nullable) = false,
27 | (gogoproto.jsontag) = "minimum_gas_prices,omitempty",
28 | (gogoproto.moretags) = "yaml:\"minimum_gas_prices\"",
29 | (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"
30 | ];
31 |
32 | // bypass_min_fee_msg_types defines a list of message type urls
33 | // that are free of fee charge.
34 | repeated string bypass_min_fee_msg_types = 2 [
35 | (gogoproto.jsontag) = "bypass_min_fee_msg_types,omitempty",
36 | (gogoproto.moretags) = "yaml:\"bypass_min_fee_msg_types\""
37 | ];
38 |
39 | // max_total_bypass_min_fee_msg_gas_usage defines the total maximum gas usage
40 | // allowed for a transaction containing only messages of types in
41 | // bypass_min_fee_msg_types to bypass fee charge.
42 | uint64 max_total_bypass_min_fee_msg_gas_usage = 3;
43 | }
44 |
--------------------------------------------------------------------------------
/x/globalfee/querier.go:
--------------------------------------------------------------------------------
1 | package globalfee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 |
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 |
9 | "github.com/burnt-labs/xion/x/globalfee/types"
10 | )
11 |
12 | var _ types.QueryServer = &GrpcQuerier{}
13 |
14 | // ParamSource is a read only subset of paramtypes.Subspace
15 | type ParamSource interface {
16 | Get(ctx sdk.Context, key []byte, ptr interface{})
17 | Has(ctx sdk.Context, key []byte) bool
18 | }
19 |
20 | type GrpcQuerier struct {
21 | paramSource ParamSource
22 | }
23 |
24 | func NewGrpcQuerier(paramSource ParamSource) GrpcQuerier {
25 | return GrpcQuerier{paramSource: paramSource}
26 | }
27 |
28 | // MinimumGasPrices return minimum gas prices
29 | func (g GrpcQuerier) Params(stdCtx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
30 | if req == nil {
31 | return nil, fmt.Errorf("invalid request")
32 | }
33 |
34 | var minGasPrices sdk.DecCoins
35 | var bypassMinFeeMsgTypes []string
36 | var maxTotalBypassMinFeeMsgGasUsage uint64
37 | ctx := sdk.UnwrapSDKContext(stdCtx)
38 |
39 | if g.paramSource.Has(ctx, types.ParamStoreKeyMinGasPrices) {
40 | g.paramSource.Get(ctx, types.ParamStoreKeyMinGasPrices, &minGasPrices)
41 | }
42 | if g.paramSource.Has(ctx, types.ParamStoreKeyBypassMinFeeMsgTypes) {
43 | g.paramSource.Get(ctx, types.ParamStoreKeyBypassMinFeeMsgTypes, &bypassMinFeeMsgTypes)
44 | }
45 | if g.paramSource.Has(ctx, types.ParamStoreKeyMaxTotalBypassMinFeeMsgGasUsage) {
46 | g.paramSource.Get(ctx, types.ParamStoreKeyMaxTotalBypassMinFeeMsgGasUsage, &maxTotalBypassMinFeeMsgGasUsage)
47 | }
48 |
49 | return &types.QueryParamsResponse{
50 | Params: types.Params{
51 | MinimumGasPrices: minGasPrices,
52 | BypassMinFeeMsgTypes: bypassMinFeeMsgTypes,
53 | MaxTotalBypassMinFeeMsgGasUsage: maxTotalBypassMinFeeMsgGasUsage,
54 | },
55 | }, nil
56 | }
57 |
--------------------------------------------------------------------------------
/x/feeabs/types/keys.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | const (
4 | // Module name store the name of the module
5 | ModuleName = "feeabs"
6 |
7 | // StoreKey is the string store representation
8 | StoreKey = ModuleName
9 |
10 | // RouterKey is the msg router key for the feeabs module
11 | RouterKey = ModuleName
12 |
13 | // QuerierRoute defines the module's query routing key
14 | QuerierRoute = ModuleName
15 |
16 | // MemStoreKey defines the in-memory store key
17 | MemStoreKey = "mem_feeabs"
18 |
19 | // Contract: Coin denoms cannot contain this character
20 | KeySeparator = "|"
21 | )
22 |
23 | type (
24 | ByPassMsgKey struct{}
25 | ByPassExceedMaxGasUsageKey struct{}
26 | GlobalFeeKey struct{}
27 | )
28 |
29 | var (
30 | StoreExponentialBackoff = []byte{0x10} // sub store that records the next block to send an ibc query or cross - chain swap
31 |
32 | OsmosisTwapExchangeRate = []byte{0x01} // Key for the exchange rate of osmosis (to native token)
33 | KeyChannelID = []byte{0x02} // Key for IBC channel to osmosis
34 | KeyHostChainConfigByFeeAbs = []byte{0x03} // Key for IBC channel to osmosis
35 | KeyHostChainConfigByOsmosis = []byte{0x04} // Key for IBC channel to osmosis
36 | KeyPrefixEpoch = []byte{0x05} // KeyPrefixEpoch defines prefix key for storing epochs.
37 | KeyTokenDenomPair = []byte{0x06} // Key store token denom pair on feeabs and osmosis
38 | )
39 |
40 | func GetKeyHostZoneConfigByFeeabsIBCDenom(feeabsIbcDenom string) []byte {
41 | return append(KeyHostChainConfigByFeeAbs, []byte(feeabsIbcDenom)...)
42 | }
43 |
44 | func GetKeyHostZoneConfigByOsmosisIBCDenom(osmosisIbcDenom string) []byte {
45 | return append(KeyHostChainConfigByOsmosis, []byte(osmosisIbcDenom)...)
46 | }
47 |
48 | func GetKeyTwapExchangeRate(ibcDenom string) []byte {
49 | return append(OsmosisTwapExchangeRate, []byte(ibcDenom)...)
50 | }
51 |
--------------------------------------------------------------------------------
/e2e_tests/app/upgrade_test.go:
--------------------------------------------------------------------------------
1 | package e2e_app
2 |
3 | import (
4 | "strings"
5 | "testing"
6 |
7 | "github.com/burnt-labs/xion/e2e_tests/testlib"
8 | "github.com/cosmos/interchaintest/v10/ibc"
9 | "github.com/stretchr/testify/require"
10 | )
11 |
12 | func TestAppUpgradeNetwork(t *testing.T) {
13 | t.Parallel()
14 |
15 | // Get the "from" image (current version in repo)
16 | xionFromImage, err := testlib.GetGHCRPackageNameCurrentRepo()
17 | require.NoError(t, err)
18 |
19 | // Get the "to" from (local image) which is where we want to upgrade from
20 | xionFromImageParts := strings.SplitN(xionFromImage, ":", 2)
21 | require.GreaterOrEqual(t, len(xionFromImageParts), 2, "xionFromImage should have repository:tag format")
22 |
23 | // Get the "to" image (local image) which is where we want to upgrade to
24 | xionToImageParts, err := testlib.GetXionImageTagComponents()
25 | require.NoError(t, err)
26 | require.GreaterOrEqual(t, len(xionToImageParts), 2, "xionToImage should have repository:tag format")
27 |
28 | xionToRepo := xionToImageParts[0]
29 | xionToVersion := xionToImageParts[1]
30 |
31 | // Use "recent" as upgrade name for local builds, otherwise use version-based name
32 | upgradeName := "recent"
33 | if xionToVersion != "local" {
34 | // For non-local builds, use version as upgrade name (e.g., "v20")
35 | upgradeName = xionToVersion
36 | }
37 |
38 | chainSpec := testlib.XionChainSpec(3, 1)
39 | chainSpec.Version = xionFromImageParts[1]
40 | chainSpec.ChainConfig.Images = []ibc.DockerImage{
41 | {
42 | Repository: xionFromImageParts[0],
43 | Version: xionFromImageParts[1],
44 | UIDGID: "1025:1025",
45 | },
46 | }
47 |
48 | // Build chain starting with the "from" image
49 | xion := testlib.BuildXionChainWithSpec(t, chainSpec)
50 |
51 | // Upgrade from current version in repo to local image
52 | testlib.CosmosChainUpgradeTest(t, xion, xionToRepo, xionToVersion, upgradeName)
53 | }
54 |
--------------------------------------------------------------------------------
/indexer/multi_raw.go:
--------------------------------------------------------------------------------
1 | package indexer
2 |
3 | import (
4 | "context"
5 | "reflect"
6 | "unsafe"
7 |
8 | "cosmossdk.io/collections"
9 | "cosmossdk.io/collections/indexes"
10 | )
11 |
12 | // MultiIterateRaw provides IterateRaw functionality for Multi indexes.
13 | //
14 | // Background:
15 | // The Multi index type is missing the IterateRaw() method that other index types
16 | // (Unique, ReversePair) provide. The underlying refKeys field (a KeySet) already has
17 | // IterateRaw(), but it's not exposed through the Multi type's public API.
18 | //
19 | // This helper uses reflection to access the private refKeys field and call its
20 | // IterateRaw() method. This is safe because:
21 | // 1. We're only calling a public method (IterateRaw) on the accessed field
22 | // 2. We're not modifying any state or violating type safety
23 | // 3. The performance impact is negligible (reflection only happens once per iteration)
24 | func MultiIterateRaw[ReferenceKey, PrimaryKey, Value any](
25 | ctx context.Context,
26 | multi *indexes.Multi[ReferenceKey, PrimaryKey, Value],
27 | start, end []byte,
28 | order collections.Order,
29 | ) (collections.Iterator[collections.Pair[ReferenceKey, PrimaryKey], collections.NoValue], error) {
30 | // Access the private refKeys field via reflection
31 | // The Multi struct has: refKeys collections.KeySet[collections.Pair[ReferenceKey, PrimaryKey]]
32 | v := reflect.ValueOf(multi).Elem()
33 | refKeysField := v.FieldByName("refKeys")
34 |
35 | // Make the unexported field accessible and extract the KeySet
36 | // This is equivalent to: return multi.refKeys.IterateRaw(ctx, start, end, order)
37 | refKeys := reflect.NewAt(
38 | refKeysField.Type(),
39 | unsafe.Pointer(refKeysField.UnsafeAddr()),
40 | ).Elem().Interface().(collections.KeySet[collections.Pair[ReferenceKey, PrimaryKey]])
41 |
42 | // Call the public IterateRaw method on the KeySet
43 | return refKeys.IterateRaw(ctx, start, end, order)
44 | }
45 |
--------------------------------------------------------------------------------
/x/feeabs/types/events_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestEventConstants(t *testing.T) {
10 | // Test all event type constants
11 | require.Equal(t, "timeout", EventTypeTimeout)
12 | require.Equal(t, "receive_feechain_verification_packet", EventTypePacket)
13 | require.Equal(t, "epoch_end", EventTypeEpochEnd)
14 | require.Equal(t, "epoch_start", EventTypeEpochStart)
15 |
16 | // Test all attribute key constants
17 | require.Equal(t, "success", AttributeKeyAckSuccess)
18 | require.Equal(t, "acknowledgement", AttributeKeyAck)
19 | require.Equal(t, "ack_error", AttributeKeyAckError)
20 | require.Equal(t, "epoch_number", AttributeEpochNumber)
21 | require.Equal(t, "start_time", AttributeEpochStartTime)
22 | require.Equal(t, "failure_type", AttributeKeyFailureType)
23 | require.Equal(t, "packet", AttributeKeyPacket)
24 | }
25 |
26 | func TestEventConstantsUniqueness(t *testing.T) {
27 | // Collect all event constants to ensure they're unique
28 | eventTypes := []string{
29 | EventTypeTimeout,
30 | EventTypePacket,
31 | EventTypeEpochEnd,
32 | EventTypeEpochStart,
33 | }
34 |
35 | attributeKeys := []string{
36 | AttributeKeyAckSuccess,
37 | AttributeKeyAck,
38 | AttributeKeyAckError,
39 | AttributeEpochNumber,
40 | AttributeEpochStartTime,
41 | AttributeKeyFailureType,
42 | AttributeKeyPacket,
43 | }
44 |
45 | // Check that event types are unique
46 | for i := 0; i < len(eventTypes); i++ {
47 | for j := i + 1; j < len(eventTypes); j++ {
48 | require.NotEqual(t, eventTypes[i], eventTypes[j],
49 | "Event types should be unique")
50 | }
51 | }
52 |
53 | // Check that attribute keys are unique
54 | for i := 0; i < len(attributeKeys); i++ {
55 | for j := i + 1; j < len(attributeKeys); j++ {
56 | require.NotEqual(t, attributeKeys[i], attributeKeys[j],
57 | "Attribute keys should be unique")
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.github/workflows/heighliner-alt.yaml:
--------------------------------------------------------------------------------
1 | name: Heighliner Action Build
2 |
3 | # reusable workflow, do not add triggers
4 | on:
5 | workflow_dispatch:
6 |
7 | env:
8 | GHCR: ghcr.io/${{ github.repository }}
9 | PLATFORMS: linux/amd64
10 |
11 | jobs:
12 | build-heighliner:
13 | name: main
14 | runs-on: ubuntu-latest
15 | permissions:
16 | id-token: write
17 | contents: read
18 | packages: write
19 | pull-requests: write
20 |
21 | steps:
22 | - name: Login to GitHub Container Registry
23 | uses: docker/login-action@v3
24 | with:
25 | registry: ghcr.io
26 | username: ${{ github.repository_owner }}
27 | password: ${{ secrets.GITHUB_TOKEN }}
28 |
29 | - name: Set up docker buildx
30 | uses: docker/setup-buildx-action@v3
31 |
32 | - name: Metadata for heighliner
33 | id: meta-heighliner
34 | uses: docker/metadata-action@v5
35 | with:
36 | images: |
37 | ${{ env.GHCR }}/heighliner
38 | tags: |
39 | type=sha
40 | type=semver,pattern={{version}},enable=${{ github.event_name == 'push' }}
41 | type=raw,value=latest,enable={{is_default_branch}}
42 |
43 | - name: Build Heighliner image
44 | id: heighliner
45 | uses: burnt-labs/heighliner-action@v1.0.0-alpha10
46 | with:
47 | local: true
48 | tag: ${{ steps.meta-heighliner.outputs.tags }}
49 | chain: xion
50 | dockerfile: import
51 | platform: ${{ env.PLATFORMS }}
52 | binaries: '["/usr/bin/xiond"]'
53 | build-env: "[\"BUILD_TAGS=muslc\", \"BASE_IMAGE=${{ env.GHCR }}/xion\", \"VERSION=${{ fromJSON(steps.meta-heighliner.outputs.json).labels['org.opencontainers.image.version'] }}\"]"
54 |
55 | - name: Push Heighliner image
56 | run: |
57 | docker push ghcr.io/burnt-labs/xion/${{ steps.heighliner.outputs.tag }}
58 |
--------------------------------------------------------------------------------
/x/globalfee/keeper/migrations_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "cosmossdk.io/math"
9 | storetypes "cosmossdk.io/store/types"
10 |
11 | "github.com/cosmos/cosmos-sdk/codec"
12 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
13 | "github.com/cosmos/cosmos-sdk/testutil"
14 | sdk "github.com/cosmos/cosmos-sdk/types"
15 | paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
16 |
17 | "github.com/burnt-labs/xion/x/globalfee/keeper"
18 | "github.com/burnt-labs/xion/x/globalfee/types"
19 | )
20 |
21 | func TestNewMigrator(t *testing.T) {
22 | // Create a test subspace
23 | storeKey := storetypes.NewKVStoreKey(paramstypes.StoreKey)
24 | tkey := storetypes.NewTransientStoreKey(paramstypes.TStoreKey)
25 |
26 | subspace := paramstypes.NewSubspace(
27 | codec.NewProtoCodec(codectypes.NewInterfaceRegistry()),
28 | codec.NewLegacyAmino(),
29 | storeKey,
30 | tkey,
31 | types.ModuleName,
32 | ).WithKeyTable(types.ParamKeyTable())
33 |
34 | migrator := keeper.NewMigrator(subspace)
35 | require.NotNil(t, migrator)
36 | }
37 |
38 | func TestMigrate1to2(t *testing.T) {
39 | // Create a test subspace
40 | storeKey := storetypes.NewKVStoreKey(paramstypes.StoreKey)
41 | tkey := storetypes.NewTransientStoreKey(paramstypes.TStoreKey)
42 | ctx := testutil.DefaultContextWithDB(t, storeKey, tkey)
43 |
44 | subspace := paramstypes.NewSubspace(
45 | codec.NewProtoCodec(codectypes.NewInterfaceRegistry()),
46 | codec.NewLegacyAmino(),
47 | storeKey,
48 | tkey,
49 | types.ModuleName,
50 | ).WithKeyTable(types.ParamKeyTable())
51 |
52 | // Set up initial params for migration
53 | initialParams := sdk.DecCoins{sdk.NewDecCoin("stake", math.NewInt(1000))}
54 | subspace.Set(ctx.Ctx, types.ParamStoreKeyMinGasPrices, &initialParams)
55 |
56 | migrator := keeper.NewMigrator(subspace)
57 |
58 | // Test that the migration function can be called
59 | err := migrator.Migrate1to2(ctx.Ctx)
60 | require.NoError(t, err)
61 | }
62 |
--------------------------------------------------------------------------------
/proto/xion/mint/v1/mint.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.mint.v1;
3 |
4 | option go_package = "github.com/burnt-labs/xion/x/mint/types";
5 |
6 | import "gogoproto/gogo.proto";
7 | import "cosmos_proto/cosmos.proto";
8 | import "amino/amino.proto";
9 |
10 | // Minter represents the minting state.
11 | message Minter {
12 | // current annual inflation rate
13 | string inflation = 1 [
14 | (cosmos_proto.scalar) = "cosmos.Dec",
15 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
16 | (gogoproto.nullable) = false
17 | ];
18 | // current annual expected provisions
19 | string annual_provisions = 2 [
20 | (cosmos_proto.scalar) = "cosmos.Dec",
21 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
22 | (gogoproto.nullable) = false
23 | ];
24 | }
25 |
26 | // Params defines the parameters for the x/mint module.
27 | message Params {
28 | option (gogoproto.goproto_stringer) = false;
29 | option (amino.name) = "xion/x/mint/Params";
30 |
31 | // type of coin to mint
32 | string mint_denom = 1;
33 | // maximum annual change in inflation rate
34 | string inflation_rate_change = 2 [
35 | (cosmos_proto.scalar) = "cosmos.Dec",
36 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
37 | (gogoproto.nullable) = false
38 | ];
39 | // maximum inflation rate
40 | string inflation_max = 3 [
41 | (cosmos_proto.scalar) = "cosmos.Dec",
42 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
43 | (gogoproto.nullable) = false
44 | ];
45 | // minimum inflation rate
46 | string inflation_min = 4 [
47 | (cosmos_proto.scalar) = "cosmos.Dec",
48 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
49 | (gogoproto.nullable) = false
50 | ];
51 | // goal of percent bonded atoms
52 | string goal_bonded = 5 [
53 | (cosmos_proto.scalar) = "cosmos.Dec",
54 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
55 | (gogoproto.nullable) = false
56 | ];
57 | // expected blocks per year
58 | uint64 blocks_per_year = 6;
59 | }
60 |
--------------------------------------------------------------------------------
/.github/workflows/build-release-info.yaml:
--------------------------------------------------------------------------------
1 | name: Build Release Info
2 | # Run for new release tags only
3 |
4 | on:
5 | workflow_call:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build-release-info:
10 | runs-on: ubuntu-latest
11 | env:
12 | GH_TOKEN: ${{ github.token }}
13 |
14 | steps:
15 | - name: checkout
16 | uses: actions/checkout@v5
17 |
18 | - name: Prepare environment
19 | run: mkdir -p release
20 |
21 | - name: Download artifacts
22 | uses: actions/download-artifact@v4
23 | with:
24 | path: release
25 | pattern: xiond-*
26 | merge-multiple: true
27 |
28 | - name: Create version.json
29 | working-directory: release
30 | run: |
31 | set -Eeuo pipefail
32 | upgrade_name=$(echo $GITHUB_REF_NAME | cut -d. -f1)
33 | jq -s '.[0] * (.[1] // {})' <(go mod edit -json | jq --arg name $upgrade_name '{
34 | name: $name,
35 | tag: "${{ github.ref_name }}",
36 | height: 0,
37 | proposal: 0,
38 | go_version: .Go,
39 | cosmos_sdk_version: (.Require[] | select(.Path == "github.com/cosmos/cosmos-sdk") | .Version),
40 | cosmwasm_enabled: (.Require[] | select(.Path == "github.com/CosmWasm/wasmd") != null),
41 | cosmwasm_version: (.Require[] | select(.Path == "github.com/CosmWasm/wasmd") | .Version),
42 | ibc_go_version: (.Require[] | select(.Path == "github.com/cosmos/ibc-go/v10") | .Version),
43 | consensus: {
44 | type: "cometbft",
45 | version: (.Require[] | select(.Path == "github.com/cometbft/cometbft") | .Version)
46 | }
47 | }') binaries.json | tee version.json
48 |
49 | - name: Upload version.json files
50 | uses: actions/upload-artifact@v4
51 | with:
52 | name: version.json
53 | path: release/version.json
54 | retention-days: 3
55 | if-no-files-found: error
56 |
--------------------------------------------------------------------------------
/app/params/weights.go:
--------------------------------------------------------------------------------
1 | package params
2 |
3 | // Default simulation operation weights for messages and gov proposals
4 | const (
5 | DefaultWeightMsgSend int = 100
6 | DefaultWeightMsgMultiSend int = 10
7 | DefaultWeightMsgSetWithdrawAddress int = 50
8 | DefaultWeightMsgWithdrawDelegationReward int = 50
9 | DefaultWeightMsgWithdrawValidatorCommission int = 50
10 | DefaultWeightMsgFundCommunityPool int = 50
11 | DefaultWeightMsgDeposit int = 100
12 | DefaultWeightMsgVote int = 67
13 | DefaultWeightMsgUnjail int = 100
14 | DefaultWeightMsgCreateValidator int = 100
15 | DefaultWeightMsgEditValidator int = 5
16 | DefaultWeightMsgDelegate int = 100
17 | DefaultWeightMsgUndelegate int = 100
18 | DefaultWeightMsgBeginRedelegate int = 100
19 |
20 | DefaultWeightCommunitySpendProposal int = 5
21 | DefaultWeightTextProposal int = 5
22 | DefaultWeightParamChangeProposal int = 5
23 |
24 | DefaultWeightMsgStoreCode int = 50
25 | DefaultWeightMsgInstantiateContract int = 100
26 | DefaultWeightMsgExecuteContract int = 100
27 | DefaultWeightMsgUpdateAdmin int = 25
28 | DefaultWeightMsgClearAdmin int = 10
29 | DefaultWeightMsgMigrateContract int = 50
30 |
31 | DefaultWeightStoreCodeProposal int = 5
32 | DefaultWeightInstantiateContractProposal int = 5
33 | DefaultWeightUpdateAdminProposal int = 5
34 | DefaultWeightExecuteContractProposal int = 5
35 | DefaultWeightClearAdminProposal int = 5
36 | DefaultWeightMigrateContractProposal int = 5
37 | DefaultWeightSudoContractProposal int = 5
38 | DefaultWeightPinCodesProposal int = 5
39 | DefaultWeightUnpinCodesProposal int = 5
40 | DefaultWeightUpdateInstantiateConfigProposal int = 5
41 | DefaultWeightStoreAndInstantiateContractProposal int = 5
42 | )
43 |
--------------------------------------------------------------------------------
/x/jwk/types/genesis_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
9 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
10 |
11 | "github.com/burnt-labs/xion/x/jwk/types"
12 | )
13 |
14 | func TestGenesisState_Validate(t *testing.T) {
15 | tests := []struct {
16 | desc string
17 | genState *types.GenesisState
18 | valid bool
19 | }{
20 | {
21 | desc: "default is valid",
22 | genState: types.DefaultGenesis(),
23 | valid: true,
24 | },
25 | {
26 | desc: "valid genesis state",
27 | genState: &types.GenesisState{
28 | Params: types.DefaultParams(),
29 | AudienceList: []types.Audience{
30 | {
31 | Aud: "0",
32 | Admin: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
33 | },
34 | {
35 | Aud: "1",
36 | Admin: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
37 | },
38 | },
39 | // this line is used by starport scaffolding # types/genesis/validField
40 | },
41 | valid: true,
42 | },
43 | {
44 | desc: "duplicated audience",
45 | genState: &types.GenesisState{
46 | AudienceList: []types.Audience{
47 | {
48 | Aud: "0",
49 | Admin: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
50 | },
51 | {
52 | Aud: "0",
53 | Admin: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
54 | },
55 | },
56 | },
57 | valid: false,
58 | },
59 | {
60 | desc: "invalid admin address",
61 | genState: &types.GenesisState{
62 | AudienceList: []types.Audience{
63 | {
64 | Aud: "test-audience",
65 | Admin: "invalid-address",
66 | },
67 | },
68 | },
69 | valid: false,
70 | },
71 | // this line is used by starport scaffolding # types/genesis/testcase
72 | }
73 | for _, tc := range tests {
74 | t.Run(tc.desc, func(t *testing.T) {
75 | err := tc.genState.Validate()
76 | if tc.valid {
77 | require.NoError(t, err)
78 | } else {
79 | require.Error(t, err)
80 | }
81 | })
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/x/feeabs/types/codec_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | "github.com/cosmos/cosmos-sdk/codec"
9 | "github.com/cosmos/cosmos-sdk/codec/types"
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | )
12 |
13 | func TestRegisterCodec(t *testing.T) {
14 | cdc := codec.NewLegacyAmino()
15 |
16 | // This should not panic
17 | require.NotPanics(t, func() {
18 | RegisterCodec(cdc)
19 | })
20 | }
21 |
22 | func TestRegisterInterfaces(t *testing.T) {
23 | registry := types.NewInterfaceRegistry()
24 |
25 | // This should not panic
26 | require.NotPanics(t, func() {
27 | RegisterInterfaces(registry)
28 | })
29 |
30 | // Just verify that the function runs without panic
31 | // The actual interface registration testing is complex and would require
32 | // a full setup with proper protobuf message registration
33 | }
34 |
35 | func TestAminoCodec(t *testing.T) {
36 | // Test that the amino codec is properly initialized
37 | require.NotNil(t, amino)
38 |
39 | // Test encoding/decoding a message
40 | // nolint: goconst
41 | validAddr := "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
42 | senderAddr, err := sdk.AccAddressFromBech32(validAddr)
43 | require.NoError(t, err)
44 |
45 | msg := NewMsgSendQueryIbcDenomTWAP(senderAddr)
46 |
47 | // Should be able to marshal and unmarshal
48 | bz, err := amino.MarshalJSON(msg)
49 | require.NoError(t, err)
50 | require.NotEmpty(t, bz)
51 |
52 | var decoded MsgSendQueryIbcDenomTWAP
53 | err = amino.UnmarshalJSON(bz, &decoded)
54 | require.NoError(t, err)
55 | require.Equal(t, msg.Sender, decoded.Sender)
56 | }
57 |
58 | func TestInit(t *testing.T) {
59 | // The init function should have been called during package initialization
60 | // We can test that amino codec is properly set up
61 | require.NotNil(t, amino)
62 |
63 | // Test that we can encode a basic SDK message
64 | // nolint: goconst
65 | validAddr := "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
66 | senderAddr, err := sdk.AccAddressFromBech32(validAddr)
67 | require.NoError(t, err)
68 |
69 | msg := NewMsgSendQueryIbcDenomTWAP(senderAddr)
70 | bz := msg.GetSignBytes()
71 | require.NotEmpty(t, bz)
72 | }
73 |
--------------------------------------------------------------------------------
/scripts/release-info.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -Eeuo pipefail
3 |
4 | if [ -n "${DEBUG:-}" ]; then
5 | set -x
6 | fi
7 |
8 | # Get the directory of this script, used to source other scripts
9 | : ${scripts_dir:="$(realpath $(dirname $0))"}
10 | : ${base_dir:="$(dirname $scripts_dir)"}
11 | : ${release_dir:="$base_dir/release"}
12 |
13 | # set binaries file
14 | binaries_json=${release_dir}/binaries.json
15 |
16 | # set ref name if not set
17 | : ${GITHUB_REF_NAME:=$(git describe --tags)}
18 |
19 | upgrade_name=$(echo $GITHUB_REF_NAME | cut -d. -f1)
20 |
21 | binaries=$(
22 | find "$release_dir" -name 'xiond_*.tar.gz' ! -name 'xiond_*darwin_all.tar.gz' | sort
23 | )
24 |
25 | binaries_list=$(
26 | for file in ${binaries[@]}; do
27 | platform=$(basename "$file" ".tar.gz" | cut -d_ -f3- | sed -E 's/^rc[0-9]*-//g; s/_/\//g')
28 | checksum=$(sha256sum "$file" | awk '{ print $1 }')
29 | echo "\"$platform\": \"https://github.com/burnt-labs/xion/releases/download/${GITHUB_REF_NAME}/$(basename "$file")?checksum=sha256:$checksum"\"
30 | done
31 | )
32 |
33 | echo "{\"binaries\": {$(paste -s -d "," <(echo "${binaries_list[@]}"))}}" | jq . > ${binaries_json}
34 |
35 | go mod edit -json |
36 | jq --rawfile binaries "$binaries_json" --arg name "$upgrade_name" --arg tag "$GITHUB_REF_NAME" '{
37 | name: $name,
38 | tag: $tag,
39 | recommended_version: $tag,
40 | language: {
41 | type: "go",
42 | version: ("v" + (.Go | split(".") | first + "." + (.[1] // "")))
43 | },
44 | binaries: ($binaries | fromjson).binaries,
45 | sdk: {
46 | type: "cosmos",
47 | version: (.Require[] | select(.Path == "github.com/cosmos/cosmos-sdk") | .Version)
48 | },
49 | consensus: {
50 | type: "cometbft",
51 | version: (.Require[] | select(.Path == "github.com/cometbft/cometbft") | .Version)
52 | },
53 | cosmwasm: {
54 | version: (.Require[] | select(.Path == "github.com/CosmWasm/wasmd") | .Version),
55 | enabled: (.Require[] | select(.Path == "github.com/CosmWasm/wasmd") != null)
56 | },
57 | ibc: {
58 | type: "go",
59 | version: (.Require[] | select(.Path == "github.com/cosmos/ibc-go/v8") | .Version)
60 | }
61 | }' | tee "$release_dir/version.json"
62 |
--------------------------------------------------------------------------------
/proto/xion/v1/feegrant.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.v1;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "google/protobuf/any.proto";
6 | import "cosmos_proto/cosmos.proto";
7 | import "amino/amino.proto";
8 |
9 | option go_package = "github.com/burnt-labs/xion/x/xion/types";
10 |
11 | // AuthzAllowance creates allowance only authz message for a specific grantee
12 | message AuthzAllowance {
13 | option (gogoproto.goproto_getters) = false;
14 | option (cosmos_proto.implements_interface) =
15 | "cosmos.feegrant.v1beta1.FeeAllowanceI";
16 | option (amino.name) = "xion/AuthzAllowance";
17 |
18 | // allowance can be any of basic and periodic fee allowance.
19 | google.protobuf.Any allowance = 1
20 | [ (cosmos_proto.accepts_interface) =
21 | "cosmos.feegrant.v1beta1.FeeAllowanceI" ];
22 |
23 | // The address that can use this authorization-based allowance
24 | string authz_grantee = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
25 | }
26 |
27 | // ContractsAllowance creates allowance only for specific contracts
28 | message ContractsAllowance {
29 | option (gogoproto.goproto_getters) = false;
30 | option (cosmos_proto.implements_interface) =
31 | "cosmos.feegrant.v1beta1.FeeAllowanceI";
32 | option (amino.name) = "xion/ContractsAllowance";
33 |
34 | // allowance can be any allowance interface type.
35 | google.protobuf.Any allowance = 1
36 | [ (cosmos_proto.accepts_interface) =
37 | "cosmos.feegrant.v1beta1.FeeAllowanceI" ];
38 |
39 | // List of contract addresses that this allowance applies to
40 | repeated string contract_addresses = 2
41 | [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
42 | }
43 |
44 | // MultiAnyAllowance creates an allowance that pays if any of the internal
45 | // allowances are met
46 | message MultiAnyAllowance {
47 | option (gogoproto.goproto_getters) = false;
48 | option (cosmos_proto.implements_interface) =
49 | "cosmos.feegrant.v1beta1.FeeAllowanceI";
50 | option (amino.name) = "xion/MultiAnyAllowance";
51 |
52 | // allowance can be any allowance interface type.
53 | repeated google.protobuf.Any allowances = 1
54 | [ (cosmos_proto.accepts_interface) =
55 | "cosmos.feegrant.v1beta1.FeeAllowanceI" ];
56 | }
57 |
--------------------------------------------------------------------------------
/wasmbindings/query_plugin.go:
--------------------------------------------------------------------------------
1 | package wasmbinding
2 |
3 | import (
4 | "fmt"
5 |
6 | wasmvmtypes "github.com/CosmWasm/wasmvm/v3/types"
7 |
8 | abci "github.com/cometbft/cometbft/abci/types"
9 |
10 | "github.com/cosmos/gogoproto/proto"
11 |
12 | "github.com/cosmos/cosmos-sdk/baseapp"
13 | "github.com/cosmos/cosmos-sdk/codec"
14 | sdk "github.com/cosmos/cosmos-sdk/types"
15 | )
16 |
17 | // StargateQuerier dispatches whitelisted stargate queries
18 | func StargateQuerier(queryRouter baseapp.GRPCQueryRouter, cdc codec.Codec) func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) {
19 | return func(ctx sdk.Context, request *wasmvmtypes.StargateQuery) ([]byte, error) {
20 | protoResponseType, err := GetWhitelistedQuery(request.Path)
21 | if err != nil {
22 | return nil, err
23 | }
24 |
25 | route := queryRouter.Route(request.Path)
26 | if route == nil {
27 | return nil, wasmvmtypes.UnsupportedRequest{Kind: fmt.Sprintf("No route to query '%s'", request.Path)}
28 | }
29 |
30 | res, err := route(ctx, &abci.RequestQuery{
31 | Data: request.Data,
32 | Path: request.Path,
33 | })
34 | if err != nil {
35 | return nil, err
36 | }
37 |
38 | if res.Value == nil {
39 | return nil, fmt.Errorf("res returned from abci query route is nil")
40 | }
41 |
42 | bz, err := ConvertProtoToJSONMarshal(protoResponseType, res.Value, cdc)
43 | if err != nil {
44 | return nil, err
45 | }
46 |
47 | return bz, nil
48 | }
49 | }
50 |
51 | // ConvertProtoToJsonMarshal unmarshals the given bytes into a proto message and then marshals it to json.
52 | // This is done so that clients calling stargate queries do not need to define their own proto unmarshalers,
53 | // being able to use response directly by json marshalling, which is supported in cosmwasm.
54 | func ConvertProtoToJSONMarshal(protoResponseType proto.Message, bz []byte, cdc codec.Codec) ([]byte, error) {
55 | // unmarshal binary into stargate response data structure
56 | err := cdc.Unmarshal(bz, protoResponseType)
57 | if err != nil {
58 | return nil, wasmvmtypes.Unknown{}
59 | }
60 |
61 | bz, err = cdc.MarshalJSON(protoResponseType)
62 | if err != nil {
63 | return nil, wasmvmtypes.Unknown{}
64 | }
65 |
66 | protoResponseType.Reset()
67 |
68 | return bz, nil
69 | }
70 |
--------------------------------------------------------------------------------
/contrib/relayer-tests/init_two_chainz_relayer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # init_two_chainz_relayer creates two xiond chains and configures the relayer
3 |
4 | SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
5 | WASMD_DATA="$(pwd)/data"
6 | RELAYER_CONF="$(pwd)/.relayer"
7 |
8 | # Ensure relayer is installed
9 | if ! [ -x "$(which rly)" ]; then
10 | echo "Error: wasmd is not installed. Try running 'make build-wasmd'" >&2
11 | exit 1
12 | fi
13 |
14 | # Ensure xiond is installed
15 | if ! [ -x "$(which xiond)" ]; then
16 | echo "Error: wasmd is not installed. Try running 'make build-wasmd'" >&2
17 | exit 1
18 | fi
19 |
20 | # Display software version for testers
21 | echo "WASMD VERSION INFO:"
22 | xiond version --long
23 |
24 | # Ensure jq is installed
25 | if [[ ! -x "$(which jq)" ]]; then
26 | echo "jq (a tool for parsing json in the command line) is required..."
27 | echo "https://stedolan.github.io/jq/download/"
28 | exit 1
29 | fi
30 |
31 | # Delete data from old runs
32 | rm -rf $WASMD_DATA &> /dev/null
33 | rm -rf $RELAYER_CONF &> /dev/null
34 |
35 | # Stop existing xiond processes
36 | killall xiond &> /dev/null
37 |
38 | set -e
39 |
40 | chainid0=ibc-0
41 | chainid1=ibc-1
42 |
43 | echo "Generating wasmd configurations..."
44 | mkdir -p $WASMD_DATA && cd $WASMD_DATA && cd ../
45 | ./one_chain.sh xiond $chainid0 ./data 26657 26656 6060 9090
46 | ./one_chain.sh xiond $chainid1 ./data 26557 26556 6061 9091
47 |
48 | [ -f $WASMD_DATA/$chainid0.log ] && echo "$chainid0 initialized. Watch file $WASMD_DATA/$chainid0.log to see its execution."
49 | [ -f $WASMD_DATA/$chainid1.log ] && echo "$chainid1 initialized. Watch file $WASMD_DATA/$chainid1.log to see its execution."
50 |
51 |
52 | echo "Generating rly configurations..."
53 | rly config init
54 | rly config add-chains configs/xiond/chains
55 | rly config add-paths configs/xiond/paths
56 |
57 | SEED0=$(jq -r '.mnemonic' $WASMD_DATA/ibc-0/key_seed.json)
58 | SEED1=$(jq -r '.mnemonic' $WASMD_DATA/ibc-1/key_seed.json)
59 | echo "Key $(rly keys restore ibc-0 testkey "$SEED0") imported from ibc-0 to relayer..."
60 | echo "Key $(rly keys restore ibc-1 testkey "$SEED1") imported from ibc-1 to relayer..."
61 | echo "Creating light clients..."
62 | sleep 3
63 | rly light init ibc-0 -f
64 | rly light init ibc-1 -f
65 |
--------------------------------------------------------------------------------
/proto/xion/feeabs/v1beta1/proposal.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.feeabs.v1beta1;
3 |
4 | import "gogoproto/gogo.proto";
5 |
6 | option go_package = "github.com/burnt-labs/xion/x/feeabs/types";
7 |
8 | // HostChainFeeAbsStatus represents the status of a host chain fee abstraction
9 | // configuration
10 | enum HostChainFeeAbsStatus {
11 | // HOST_CHAIN_FEE_ABS_STATUS_UNSPECIFIED indicates an unspecified status
12 | HOST_CHAIN_FEE_ABS_STATUS_UNSPECIFIED = 0;
13 | // HOST_CHAIN_FEE_ABS_STATUS_UPDATED indicates the configuration is up to date
14 | HOST_CHAIN_FEE_ABS_STATUS_UPDATED = 1;
15 | // HOST_CHAIN_FEE_ABS_STATUS_OUTDATED indicates the configuration is outdated
16 | HOST_CHAIN_FEE_ABS_STATUS_OUTDATED = 2;
17 | // HOST_CHAIN_FEE_ABS_STATUS_FROZEN indicates the configuration is frozen
18 | HOST_CHAIN_FEE_ABS_STATUS_FROZEN = 3;
19 | }
20 |
21 | // HostChainFeeAbsConfig
22 | message HostChainFeeAbsConfig {
23 | // ibc token is allowed to be used as fee token
24 | string ibc_denom = 1 [ (gogoproto.moretags) = "yaml:\"allowed_token\"" ];
25 | // token_in in cross_chain swap contract.
26 | string osmosis_pool_token_denom_in = 2;
27 | // pool id
28 | uint64 pool_id = 3;
29 | // Host chain fee abstraction connection status
30 | HostChainFeeAbsStatus status = 4;
31 | }
32 |
33 | // AddHostZoneProposal
34 | message AddHostZoneProposal {
35 | option (gogoproto.goproto_getters) = false;
36 | // the title of the proposal
37 | string title = 1;
38 | // the description of the proposal
39 | string description = 2;
40 | // the host chain config
41 | HostChainFeeAbsConfig host_chain_config = 3;
42 | }
43 |
44 | // DeleteHostZoneProposal
45 | message DeleteHostZoneProposal {
46 | option (gogoproto.goproto_getters) = false;
47 | // the title of the proposal
48 | string title = 1;
49 | // the description of the proposal
50 | string description = 2;
51 | // the ibc denom of this token
52 | string ibc_denom = 3;
53 | }
54 |
55 | // SetHostZoneProposal
56 | message SetHostZoneProposal {
57 | option (gogoproto.goproto_getters) = false;
58 | // the title of the proposal
59 | string title = 1;
60 | // the description of the proposal
61 | string description = 2;
62 | // the host chain config
63 | HostChainFeeAbsConfig host_chain_config = 3;
64 | }
65 |
--------------------------------------------------------------------------------
/wasmbindings/whitelist_all_test.go:
--------------------------------------------------------------------------------
1 | package wasmbinding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | // TestAllWhitelistedPathsEnsured iterates every path we add in init() and ensures
8 | // GetWhitelistedQuery returns a non-nil proto.Message without error.
9 | func TestAllWhitelistedPathsEnsured(t *testing.T) {
10 | paths := []string{
11 | "/cosmos.auth.v1beta1.Query/Account",
12 | "/cosmos.auth.v1beta1.Query/Params",
13 | "/cosmos.auth.v1beta1.Query/ModuleAccounts",
14 | "/cosmos.authz.v1beta1.Query/Grants",
15 | "/cosmos.bank.v1beta1.Query/Balance",
16 | "/cosmos.bank.v1beta1.Query/DenomMetadata",
17 | "/cosmos.bank.v1beta1.Query/DenomsMetadata",
18 | "/cosmos.bank.v1beta1.Query/Params",
19 | "/cosmos.bank.v1beta1.Query/SupplyOf",
20 | "/cosmos.distribution.v1beta1.Query/Params",
21 | "/cosmos.distribution.v1beta1.Query/DelegatorWithdrawAddress",
22 | "/cosmos.distribution.v1beta1.Query/ValidatorCommission",
23 | "/cosmos.feegrant.v1beta1.Query/Allowance",
24 | "/cosmos.feegrant.v1beta1.Query/AllowancesByGranter",
25 | "/cosmos.gov.v1beta1.Query/Deposit",
26 | "/cosmos.gov.v1beta1.Query/Params",
27 | "/cosmos.gov.v1beta1.Query/Vote",
28 | "/cosmos.slashing.v1beta1.Query/Params",
29 | "/cosmos.slashing.v1beta1.Query/SigningInfo",
30 | "/cosmos.staking.v1beta1.Query/Delegation",
31 | "/cosmos.staking.v1beta1.Query/Params",
32 | "/cosmos.staking.v1beta1.Query/Validator",
33 | "/xion.v1.Query/WebAuthNVerifyRegister",
34 | "/xion.v1.Query/WebAuthNVerifyAuthenticate",
35 | "/xion.jwk.v1.Query/AudienceAll",
36 | "/xion.jwk.v1.Query/Audience",
37 | "/xion.jwk.v1.Query/Params",
38 | "/xion.jwk.v1.Query/ValidateJWT",
39 | }
40 |
41 | seen := make(map[string]struct{}, len(paths))
42 | for _, p := range paths {
43 | if _, dup := seen[p]; dup {
44 | // guard against accidental duplicates in test slice
45 | continue
46 | }
47 | seen[p] = struct{}{}
48 | msg, err := GetWhitelistedQuery(p)
49 | if err != nil {
50 | // fail fast with specific path context
51 | t.Fatalf("expected path %s to be whitelisted, got err: %v", p, err)
52 | }
53 | if msg == nil {
54 | t.Fatalf("expected non-nil proto message for path %s", p)
55 | }
56 | }
57 |
58 | if len(seen) != len(paths) {
59 | t.Fatalf("deduplicated path count mismatch: expected %d got %d", len(paths), len(seen))
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/proto/buf.lock:
--------------------------------------------------------------------------------
1 | # Generated by buf. DO NOT EDIT.
2 | version: v1
3 | deps:
4 | - remote: buf.build
5 | owner: burnt-labs
6 | repository: abstractaccount
7 | commit: 9db2c5638029409d90d27cafad584745
8 | digest: shake256:9cb480d93cbd8c4665f2964e95415f2792935d557680180cfc8536eb8f8f944618411b1f06d633610afa36b47985afaaf9a805e4102d33a6c1a9370384505a48
9 | - remote: buf.build
10 | owner: burnt-labs
11 | repository: tokenfactory
12 | commit: 5e4d38acf183470b9e6490c6f0bc8847
13 | digest: shake256:19708e05dc669c995751b17cfb291aa6d3c58f4d1b5cec511eca8f4d52c4fc40d092ec9dc5565da33344c1094fd866e58aead5932534753264fc6b2a34f3227e
14 | - remote: buf.build
15 | owner: cosmos
16 | repository: cosmos-proto
17 | commit: 04467658e59e44bbb22fe568206e1f70
18 | digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466
19 | - remote: buf.build
20 | owner: cosmos
21 | repository: cosmos-sdk
22 | commit: 650cd9ad7f7a468e8e19975269958658
23 | digest: shake256:c2c1e67ed8efa7f5c6af7a2fc02a6c257dc78fe86911cbf4d3dd379710bf475565ffe2ae4f65221888373d515caa31be68b720897cccec6e0c6a1a91ff0b5227
24 | - remote: buf.build
25 | owner: cosmos
26 | repository: gogo-proto
27 | commit: 88ef6483f90f478fb938c37dde52ece3
28 | digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba
29 | - remote: buf.build
30 | owner: googleapis
31 | repository: googleapis
32 | commit: 61b203b9a9164be9a834f58c37be6f62
33 | digest: shake256:e619113001d6e284ee8a92b1561e5d4ea89a47b28bf0410815cb2fa23914df8be9f1a6a98dcf069f5bc2d829a2cfb1ac614863be45cd4f8a5ad8606c5f200224
34 | - remote: buf.build
35 | owner: protocolbuffers
36 | repository: wellknowntypes
37 | commit: a4aee59cf3714106961b09d99b349cd1
38 | digest: shake256:7e2aa4fb37e2be8dc8a4bcbebaec00635abbcc7333df40ba6412a666335f66c5c0705ce4cc5c207e728412ac3d81850545f90e8535da66712a17ab42923be6bd
39 | - remote: buf.build
40 | owner: tendermint
41 | repository: tendermint
42 | commit: 33ed361a90514289beabf3189e1d7665
43 | digest: shake256:038267e06294714fd883610626554b04a127b576b4e253befb4206cb72d5d3c1eeccacd4b9ec8e3fb891f7c14e1cb0f770c077d2989638995b0a61c85afedb1d
44 |
--------------------------------------------------------------------------------
/x/jwk/types/params.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | errorsmod "cosmossdk.io/errors"
5 |
6 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
7 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
8 | )
9 |
10 | var _ paramtypes.ParamSet = (*Params)(nil)
11 |
12 | var (
13 | ParamStoreKeyTimeOffset = []byte("TimeOffset")
14 | ParamStoreKeyDeploymentGas = []byte("DeploymentGas")
15 | )
16 |
17 | // ParamKeyTable the param key table for launch module
18 | func ParamKeyTable() paramtypes.KeyTable {
19 | return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
20 | }
21 |
22 | // NewParams creates a new Params instance
23 | func NewParams(timeOffset, deploymentGas uint64) Params {
24 | return Params{
25 | TimeOffset: timeOffset,
26 | DeploymentGas: deploymentGas,
27 | }
28 | }
29 |
30 | // DefaultParams returns a default set of parameters
31 | func DefaultParams() Params {
32 | deploymentGas := uint64(10_000)
33 | timeOffset := uint64(30 * 1000) // default to 30 seconds
34 |
35 | return NewParams(timeOffset, deploymentGas)
36 | }
37 |
38 | // ParamSetPairs get the params.ParamSet
39 | func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
40 | return paramtypes.ParamSetPairs{
41 | paramtypes.NewParamSetPair(ParamStoreKeyDeploymentGas, &p.DeploymentGas, validateDeploymentGas),
42 | paramtypes.NewParamSetPair(ParamStoreKeyTimeOffset, &p.TimeOffset, validateTimeOffset),
43 | }
44 | }
45 |
46 | func validateDeploymentGas(i interface{}) error {
47 | v, ok := i.(uint64)
48 | if !ok {
49 | return errorsmod.Wrapf(sdkerrors.ErrInvalidType, "type: %T, expected uint64", i)
50 | }
51 |
52 | if v == 0 {
53 | return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "deployment gas must be positive")
54 | }
55 |
56 | return nil
57 | }
58 |
59 | func validateTimeOffset(i interface{}) error {
60 | v, ok := i.(uint64)
61 | if !ok {
62 | return errorsmod.Wrapf(sdkerrors.ErrInvalidType, "type: %T, expected uint64", i)
63 | }
64 |
65 | if v == 0 {
66 | return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "time offset must be positive")
67 | }
68 |
69 | return nil
70 | }
71 |
72 | // Validate validates the set of params
73 | func (p Params) Validate() error {
74 | if err := validateDeploymentGas(p.DeploymentGas); err != nil {
75 | return err
76 | }
77 |
78 | return validateTimeOffset(p.TimeOffset)
79 | }
80 |
--------------------------------------------------------------------------------
/x/xion/types/expected_keepers.go:
--------------------------------------------------------------------------------
1 | package types // noalias
2 |
3 | import (
4 | "context"
5 |
6 | aatypes "github.com/burnt-labs/abstract-account/x/abstractaccount/types"
7 |
8 | "cosmossdk.io/math"
9 |
10 | sdktypes "github.com/cosmos/cosmos-sdk/types"
11 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
12 | )
13 |
14 | // BankKeeper defines the contract needed to be fulfilled for banking and supply
15 | // dependencies.
16 | type BankKeeper interface {
17 | SendCoinsFromModuleToAccount(
18 | ctx context.Context,
19 | senderModule string,
20 | recipientAddr sdktypes.AccAddress,
21 | amt sdktypes.Coins,
22 | ) error
23 | SendCoinsFromModuleToModule(
24 | ctx context.Context,
25 | senderModule,
26 | recipientModule string,
27 | amt sdktypes.Coins,
28 | ) error
29 | SendCoinsFromAccountToModule(
30 | ctx context.Context,
31 | senderAddr sdktypes.AccAddress,
32 | recipientModule string,
33 | amt sdktypes.Coins,
34 | ) error
35 | IsSendEnabledCoins(ctx context.Context, coins ...sdktypes.Coin) error
36 | BlockedAddr(addr sdktypes.AccAddress) bool
37 | SendCoins(ctx context.Context, fromAddr sdktypes.AccAddress, toAddr sdktypes.AccAddress, amt sdktypes.Coins) error
38 | InputOutputCoins(ctx context.Context, input banktypes.Input, outputs []banktypes.Output) error
39 | GetBalance(ctx context.Context, addr sdktypes.AccAddress, denom string) sdktypes.Coin
40 | BurnCoins(ctx context.Context, moduleName string, amt sdktypes.Coins) error
41 | }
42 |
43 | type AccountKeeper interface {
44 | GetModuleAccount(ctx context.Context, moduleName string) sdktypes.ModuleAccountI
45 | }
46 |
47 | type WasmKeeper interface {
48 | Migrate(ctx sdktypes.Context, contractAddress, caller sdktypes.AccAddress, newCodeID uint64, msg []byte) ([]byte, error)
49 | IterateContractsByCode(ctx sdktypes.Context, codeID uint64, cb func(address sdktypes.AccAddress) bool)
50 | PinCode(ctx sdktypes.Context, codeID uint64) error
51 | UnpinCode(ctx sdktypes.Context, codeID uint64) error
52 | }
53 |
54 | type AbstractAccountKeeper interface {
55 | GetParams(ctx sdktypes.Context) (*aatypes.Params, error)
56 | SetParams(ctx sdktypes.Context, params *aatypes.Params) error
57 | }
58 |
59 | type StakingKeeper interface {
60 | TotalBondedTokens(ctx context.Context) (math.Int, error)
61 | BondedRatio(ctx context.Context) (math.LegacyDec, error)
62 | }
63 |
--------------------------------------------------------------------------------
/app/config_test.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "strings"
5 | "testing"
6 |
7 | wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
8 | "github.com/stretchr/testify/require"
9 |
10 | "github.com/burnt-labs/xion/indexer"
11 | )
12 |
13 | func TestCustomconfigTemplate(t *testing.T) {
14 | // Create a default wasm config
15 | wasmConfig := wasmtypes.DefaultNodeConfig()
16 |
17 | // Test the template generation
18 | template := CustomconfigTemplate(wasmConfig)
19 |
20 | // Verify template is not empty
21 | require.NotEmpty(t, template)
22 |
23 | // Verify it contains wasm configuration markers
24 | require.Contains(t, template, "wasm", "Template should contain wasm configuration")
25 |
26 | // Verify it's a valid template with expected sections
27 | require.True(t, strings.Contains(template, "[") && strings.Contains(template, "]"),
28 | "Template should contain TOML sections")
29 | }
30 |
31 | func TestDefaultConfig(t *testing.T) {
32 | // Call DefaultConfig
33 | template, configInterface := DefaultConfig()
34 |
35 | // Verify template is returned
36 | require.NotEmpty(t, template)
37 | require.NotNil(t, configInterface)
38 |
39 | // Type assert to CustomConfig
40 | customConfig, ok := configInterface.(CustomConfig)
41 | require.True(t, ok, "Config should be of type CustomConfig")
42 |
43 | // Verify MinGasPrices is set correctly
44 | require.Equal(t, "0uxion", customConfig.MinGasPrices)
45 |
46 | // Verify Wasm config is set
47 | require.NotNil(t, customConfig.Wasm)
48 | require.NotNil(t, customConfig.Wasm.SimulationGasLimit)
49 | require.Equal(t, uint64(50_000_00), *customConfig.Wasm.SimulationGasLimit)
50 | require.Equal(t, uint64(50_000_00), customConfig.Wasm.SmartQueryGasLimit)
51 | require.Equal(t, uint32(1024), customConfig.Wasm.MemoryCacheSize)
52 |
53 | // Verify Indexer config is set
54 | require.NotNil(t, customConfig.Indexer)
55 | expectedIndexerConfig := indexer.DefaultConfig()
56 | require.Equal(t, expectedIndexerConfig.Enabled, customConfig.Indexer.Enabled)
57 |
58 | // Verify template contains wasm configuration
59 | require.Contains(t, template, "wasm")
60 | }
61 |
62 | func TestCustomConfig(t *testing.T) {
63 | // Test that CustomConfig struct can be created
64 | config := CustomConfig{
65 | Indexer: indexer.Config{
66 | Enabled: true,
67 | },
68 | }
69 |
70 | require.True(t, config.Indexer.Enabled)
71 | }
72 |
--------------------------------------------------------------------------------
/x/xion/types/codec.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "cosmossdk.io/x/feegrant"
5 |
6 | "github.com/cosmos/cosmos-sdk/codec"
7 | "github.com/cosmos/cosmos-sdk/codec/legacy"
8 | "github.com/cosmos/cosmos-sdk/codec/types"
9 | cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | "github.com/cosmos/cosmos-sdk/types/msgservice"
12 |
13 | feeabstypes "github.com/burnt-labs/xion/x/feeabs/types"
14 | xionMintTypes "github.com/burnt-labs/xion/x/mint/types"
15 | )
16 |
17 | // RegisterLegacyAminoCodec registers the necessary x/bank interfaces and concrete types
18 | // on the provided LegacyAmino codec. These types are used for Amino JSON serialization.
19 | func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
20 | legacy.RegisterAminoMsg(cdc, &MsgSend{}, "xion/MsgSend")
21 | legacy.RegisterAminoMsg(cdc, &MsgMultiSend{}, "xion/MsgMultiSend")
22 | legacy.RegisterAminoMsg(cdc, &MsgSetPlatformPercentage{}, "xion/MsgSetPlatformPercentage")
23 | legacy.RegisterAminoMsg(cdc, &MsgSetPlatformMinimum{}, "xion/MsgSetPlatformMinimum")
24 | legacy.RegisterAminoMsg(cdc, &xionMintTypes.MsgUpdateParams{}, "xion/x/mint/MsgUpdateParams")
25 |
26 | cdc.RegisterConcrete(&AuthzAllowance{}, "xion/AuthzAllowance", nil)
27 | cdc.RegisterConcrete(&ContractsAllowance{}, "xion/ContractsAllowance", nil)
28 | cdc.RegisterConcrete(&MultiAnyAllowance{}, "xion/MultiAnyAllowance", nil)
29 | cdc.RegisterConcrete(xionMintTypes.Params{}, "xion/x/mint/Params", nil)
30 | }
31 |
32 | func RegisterInterfaces(registry types.InterfaceRegistry) {
33 | registry.RegisterImplementations((*sdk.Msg)(nil),
34 | &MsgSend{},
35 | &MsgMultiSend{},
36 | &MsgSetPlatformPercentage{},
37 | &MsgSetPlatformMinimum{},
38 | &xionMintTypes.MsgUpdateParams{},
39 | )
40 |
41 | registry.RegisterInterface(
42 | "cosmos.feegrant.v1beta1.FeeAllowanceI",
43 | (*feegrant.FeeAllowanceI)(nil),
44 | &AuthzAllowance{},
45 | &ContractsAllowance{},
46 | &MultiAnyAllowance{},
47 | )
48 |
49 | // Register feeabs interfaces for reading historical proposals
50 | feeabstypes.RegisterInterfaces(registry)
51 |
52 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
53 | }
54 |
55 | var amino = codec.NewLegacyAmino()
56 |
57 | func init() {
58 | RegisterLegacyAminoCodec(amino)
59 | cryptocodec.RegisterCrypto(amino)
60 | sdk.RegisterLegacyAminoCodec(amino)
61 | }
62 |
--------------------------------------------------------------------------------
/x/xion/client/cli/query_webauthn.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 |
6 | "github.com/cosmos/cosmos-sdk/client"
7 | "github.com/cosmos/cosmos-sdk/client/flags"
8 |
9 | "github.com/burnt-labs/xion/x/xion/types"
10 | )
11 |
12 | func CmdWebAuthNVerifyRegister() *cobra.Command {
13 | cmd := &cobra.Command{
14 | Use: "webauthn-register [addr] [challenge] [rp] [data]",
15 | Short: "Test Webauthn Registration",
16 | Args: cobra.ExactArgs(4),
17 | RunE: func(cmd *cobra.Command, args []string) error {
18 | reqAddr := args[0]
19 | reqChallenge := args[1]
20 | reqRP := args[2]
21 | reqData := []byte(args[3])
22 |
23 | clientCtx, err := client.GetClientQueryContext(cmd)
24 | if err != nil {
25 | return err
26 | }
27 |
28 | queryClient := types.NewQueryClient(clientCtx)
29 |
30 | params := &types.QueryWebAuthNVerifyRegisterRequest{
31 | Addr: reqAddr,
32 | Challenge: reqChallenge,
33 | Rp: reqRP,
34 | Data: reqData,
35 | }
36 |
37 | res, err := queryClient.WebAuthNVerifyRegister(cmd.Context(), params)
38 | if err != nil {
39 | return err
40 | }
41 |
42 | return clientCtx.PrintProto(res)
43 | },
44 | }
45 |
46 | flags.AddQueryFlagsToCmd(cmd)
47 |
48 | return cmd
49 | }
50 |
51 | func CmdWebAuthNVerifyAuthenticate() *cobra.Command {
52 | cmd := &cobra.Command{
53 | Use: "webauthn-authenticate [addr] [challenge] [rp] [credential] [data]",
54 | Short: "Test Webauthn Authentication",
55 | Args: cobra.ExactArgs(5),
56 | RunE: func(cmd *cobra.Command, args []string) error {
57 | reqAddr := args[0]
58 | reqChallenge := args[1]
59 | reqRP := args[2]
60 | reqCredential := []byte(args[3])
61 | reqData := []byte(args[4])
62 |
63 | clientCtx, err := client.GetClientQueryContext(cmd)
64 | if err != nil {
65 | return err
66 | }
67 |
68 | queryClient := types.NewQueryClient(clientCtx)
69 |
70 | params := &types.QueryWebAuthNVerifyAuthenticateRequest{
71 | Addr: reqAddr,
72 | Challenge: reqChallenge,
73 | Rp: reqRP,
74 | Credential: reqCredential,
75 | Data: reqData,
76 | }
77 |
78 | res, err := queryClient.WebAuthNVerifyAuthenticate(cmd.Context(), params)
79 | if err != nil {
80 | return err
81 | }
82 |
83 | return clientCtx.PrintProto(res)
84 | },
85 | }
86 |
87 | flags.AddQueryFlagsToCmd(cmd)
88 |
89 | return cmd
90 | }
91 |
--------------------------------------------------------------------------------
/.github/workflows/build-release.yaml:
--------------------------------------------------------------------------------
1 | name: Build Release
2 | # Run for new release tags only
3 | # superceded by goreleaser.yaml
4 |
5 | on:
6 | workflow_call:
7 | workflow_dispatch:
8 |
9 | jobs:
10 | build-release:
11 | runs-on: ubuntu-latest
12 | env:
13 | GH_TOKEN: ${{ github.token }}
14 |
15 | steps:
16 | - name: Create release directory
17 | run: mkdir -p release
18 |
19 | - name: Build Changelog
20 | id: changelog
21 | uses: mikepenz/release-changelog-builder-action@v4
22 | with:
23 | token: ${{ secrets.GITHUB_TOKEN }}
24 |
25 | - name: Output Changelog
26 | run: echo "${{steps.changelog.outputs.changelog}}"
27 |
28 | - name: Create release for ${{ github.ref_name }}
29 | id: update-release
30 | uses: ncipollo/release-action@v1
31 | with:
32 | name: Release ${{ github.ref_name }}
33 | allowUpdates: true
34 | body: ${{ steps.changelog.outputs.changelog }}
35 | draft: false
36 | generateReleaseNotes: true
37 | prerelease: true
38 | removeArtifacts: false # important, true will remove src archives
39 | tag: ${{ github.ref_name }}
40 | token: ${{ secrets.GITHUB_TOKEN }}
41 | updateOnlyUnreleased: true
42 |
43 | - name: Download release archives
44 | working-directory: release
45 | run: |
46 | gh release download ${{ github.ref_name }} \
47 | --repo=${{ github.repository }} \
48 | --archive=tar.gz
49 | gh release download ${{ github.ref_name }} \
50 | --repo=${{ github.repository }} \
51 | --archive=zip
52 | ls
53 |
54 | - name: Download artifacts
55 | uses: actions/download-artifact@v4
56 | with:
57 | path: release
58 | pattern: xiond-*
59 | merge-multiple: true
60 |
61 | - name: Create checksums
62 | working-directory: release
63 | run: |
64 | sha256sum * | tee checksum.txt
65 |
66 | - name: Remove release archives
67 | working-directory: release
68 | run: |
69 | rm -f *.zip *.tar.gz
70 | ls
71 |
72 | - name: Upload release assets
73 | working-directory: release
74 | run: |
75 | gh release upload ${{ github.ref_name }} * \
76 | --repo ${{ github.repository }} \
77 | --clobber
78 |
--------------------------------------------------------------------------------
/x/globalfee/querier_test.go:
--------------------------------------------------------------------------------
1 | package globalfee_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | storetypes "cosmossdk.io/store/types"
9 |
10 | "github.com/cosmos/cosmos-sdk/codec"
11 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
12 | "github.com/cosmos/cosmos-sdk/testutil"
13 | paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
14 |
15 | "github.com/burnt-labs/xion/x/globalfee"
16 | "github.com/burnt-labs/xion/x/globalfee/types"
17 | )
18 |
19 | func TestNewGrpcQuerier(t *testing.T) {
20 | // Create a test subspace
21 | storeKey := storetypes.NewKVStoreKey(paramstypes.StoreKey)
22 | tkey := storetypes.NewTransientStoreKey(paramstypes.TStoreKey)
23 |
24 | subspace := paramstypes.NewSubspace(
25 | codec.NewProtoCodec(codectypes.NewInterfaceRegistry()),
26 | codec.NewLegacyAmino(),
27 | storeKey,
28 | tkey,
29 | types.ModuleName,
30 | ).WithKeyTable(types.ParamKeyTable())
31 |
32 | querier := globalfee.NewGrpcQuerier(subspace)
33 | require.NotNil(t, querier)
34 | }
35 |
36 | func TestGrpcQuerierParams(t *testing.T) {
37 | // Create a test subspace
38 | storeKey := storetypes.NewKVStoreKey(paramstypes.StoreKey)
39 | tkey := storetypes.NewTransientStoreKey(paramstypes.TStoreKey)
40 | ctx := testutil.DefaultContextWithDB(t, storeKey, tkey)
41 |
42 | subspace := paramstypes.NewSubspace(
43 | codec.NewProtoCodec(codectypes.NewInterfaceRegistry()),
44 | codec.NewLegacyAmino(),
45 | storeKey,
46 | tkey,
47 | types.ModuleName,
48 | ).WithKeyTable(types.ParamKeyTable())
49 |
50 | // Set default params
51 | params := types.DefaultParams()
52 | subspace.SetParamSet(ctx.Ctx, ¶ms)
53 |
54 | querier := globalfee.NewGrpcQuerier(subspace)
55 |
56 | // Test Params query
57 | req := &types.QueryParamsRequest{}
58 | resp, err := querier.Params(ctx.Ctx, req)
59 | require.NoError(t, err)
60 | require.NotNil(t, resp)
61 |
62 | // Compare individual fields - MinimumGasPrices can be either empty slice or nil
63 | require.True(t, (len(params.MinimumGasPrices) == 0 && len(resp.Params.MinimumGasPrices) == 0),
64 | "MinimumGasPrices should both be empty")
65 | require.Equal(t, params.BypassMinFeeMsgTypes, resp.Params.BypassMinFeeMsgTypes)
66 | require.Equal(t, params.MaxTotalBypassMinFeeMsgGasUsage, resp.Params.MaxTotalBypassMinFeeMsgGasUsage)
67 |
68 | // Test Params query with nil request
69 | resp, err = querier.Params(ctx.Ctx, nil)
70 | require.Error(t, err)
71 | require.Nil(t, resp)
72 | }
73 |
--------------------------------------------------------------------------------
/x/feeabs/types/ibc.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "time"
5 |
6 | abci "github.com/cometbft/cometbft/abci/types"
7 |
8 | codec "github.com/cosmos/cosmos-sdk/codec"
9 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | )
12 |
13 | const (
14 | // IBCPortID is the default port id that profiles module binds to.
15 | IBCPortID = "feeabs"
16 | )
17 |
18 | var ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
19 |
20 | // IBCPortKey defines the key to store the port ID in store.
21 | var (
22 | IBCPortKey = []byte{0x01}
23 | FeePoolAddressKey = []byte{0x02}
24 | )
25 |
26 | // NewQueryArithmeticTwapToNowRequest create new packet for ibc.
27 | func NewQueryArithmeticTwapToNowRequest(
28 | poolID uint64,
29 | baseDenom string,
30 | quoteDenom string,
31 | startTime time.Time,
32 | ) QueryArithmeticTwapToNowRequest {
33 | return QueryArithmeticTwapToNowRequest{
34 | PoolId: poolID,
35 | BaseAsset: baseDenom,
36 | QuoteAsset: quoteDenom,
37 | StartTime: startTime,
38 | }
39 | }
40 |
41 | func (p QueryArithmeticTwapToNowRequest) GetBytes() []byte {
42 | return ModuleCdc.MustMarshal(&p)
43 | }
44 |
45 | func SerializeCosmosQuery(reqs []abci.RequestQuery) (bz []byte, err error) {
46 | q := &CosmosQuery{
47 | Requests: reqs,
48 | }
49 | return ModuleCdc.Marshal(q)
50 | }
51 |
52 | func DeserializeCosmosQuery(bz []byte) (reqs []abci.RequestQuery, err error) {
53 | var q CosmosQuery
54 | err = ModuleCdc.Unmarshal(bz, &q)
55 | return q.Requests, err
56 | }
57 |
58 | func SerializeCosmosResponse(resps []abci.ResponseQuery) (bz []byte, err error) {
59 | r := &CosmosResponse{
60 | Responses: resps,
61 | }
62 | return ModuleCdc.Marshal(r)
63 | }
64 |
65 | func DeserializeCosmosResponse(bz []byte) (resps []abci.ResponseQuery, err error) {
66 | var r CosmosResponse
67 | err = ModuleCdc.Unmarshal(bz, &r)
68 | return r.Responses, err
69 | }
70 |
71 | func NewInterchainQueryRequest(path string, data []byte) InterchainQueryRequest {
72 | return InterchainQueryRequest{
73 | Data: data,
74 | Path: path,
75 | }
76 | }
77 |
78 | func NewInterchainQueryPacketData(data []byte, memo string) InterchainQueryPacketData {
79 | return InterchainQueryPacketData{
80 | Data: data,
81 | Memo: memo,
82 | }
83 | }
84 |
85 | // GetBytes returns the JSON marshalled interchain query packet data.
86 | func (p InterchainQueryPacketData) GetBytes() []byte {
87 | return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&p))
88 | }
89 |
--------------------------------------------------------------------------------
/x/jwk/keeper/query_audience.go:
--------------------------------------------------------------------------------
1 | package keeper
2 |
3 | import (
4 | "context"
5 |
6 | "google.golang.org/grpc/codes"
7 | "google.golang.org/grpc/status"
8 |
9 | "cosmossdk.io/store/prefix"
10 |
11 | sdk "github.com/cosmos/cosmos-sdk/types"
12 | "github.com/cosmos/cosmos-sdk/types/query"
13 |
14 | "github.com/burnt-labs/xion/x/jwk/types"
15 | )
16 |
17 | func (k Keeper) AudienceAll(goCtx context.Context, req *types.QueryAudienceAllRequest) (*types.QueryAudienceAllResponse, error) {
18 | if req == nil {
19 | return nil, status.Error(codes.InvalidArgument, "invalid request")
20 | }
21 |
22 | if req.Pagination != nil && req.Pagination.Limit > 100 {
23 | return nil, status.Error(codes.ResourceExhausted, "requests audience page size >100, too large")
24 | }
25 |
26 | var audiences []types.Audience
27 | ctx := sdk.UnwrapSDKContext(goCtx)
28 |
29 | store := ctx.KVStore(k.storeKey)
30 | audienceStore := prefix.NewStore(store, types.KeyPrefix(types.AudienceKeyPrefix))
31 |
32 | pageRes, err := query.Paginate(audienceStore, req.Pagination, func(_ []byte, value []byte) error {
33 | var audience types.Audience
34 | if err := k.cdc.Unmarshal(value, &audience); err != nil {
35 | return err
36 | }
37 |
38 | audiences = append(audiences, audience)
39 | return nil
40 | })
41 | if err != nil {
42 | return nil, status.Error(codes.Internal, err.Error())
43 | }
44 |
45 | return &types.QueryAudienceAllResponse{Audience: audiences, Pagination: pageRes}, nil
46 | }
47 |
48 | func (k Keeper) Audience(goCtx context.Context, req *types.QueryAudienceRequest) (*types.QueryAudienceResponse, error) {
49 | if req == nil {
50 | return nil, status.Error(codes.InvalidArgument, "invalid request")
51 | }
52 | ctx := sdk.UnwrapSDKContext(goCtx)
53 |
54 | val, found := k.GetAudience(
55 | ctx,
56 | req.Aud,
57 | )
58 | if !found {
59 | return nil, status.Error(codes.NotFound, "not found")
60 | }
61 |
62 | return &types.QueryAudienceResponse{Audience: val}, nil
63 | }
64 |
65 | func (k Keeper) AudienceClaim(goCtx context.Context, req *types.QueryAudienceClaimRequest) (*types.QueryAudienceClaimResponse, error) {
66 | if req == nil {
67 | return nil, status.Error(codes.InvalidArgument, "invalid request")
68 | }
69 | ctx := sdk.UnwrapSDKContext(goCtx)
70 |
71 | val, found := k.GetAudienceClaim(
72 | ctx,
73 | req.Hash,
74 | )
75 | if !found {
76 | return nil, status.Error(codes.NotFound, "not found")
77 | }
78 |
79 | return &types.QueryAudienceClaimResponse{Claim: &val}, nil
80 | }
81 |
--------------------------------------------------------------------------------
/x/jwk/migrations/v1/migration_test.go:
--------------------------------------------------------------------------------
1 | package v1_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | storetypes "cosmossdk.io/store/types"
9 |
10 | "github.com/cosmos/cosmos-sdk/codec"
11 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
12 | "github.com/cosmos/cosmos-sdk/testutil"
13 | paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
14 |
15 | v1migration "github.com/burnt-labs/xion/x/jwk/migrations/v1"
16 | "github.com/burnt-labs/xion/x/jwk/types"
17 | )
18 |
19 | func TestMigrateStore(t *testing.T) {
20 | storeKey := storetypes.NewKVStoreKey(types.StoreKey)
21 | tkey := storetypes.NewTransientStoreKey(paramstypes.TStoreKey)
22 | ctx := testutil.DefaultContextWithDB(t, storeKey, tkey)
23 | cdc := codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
24 |
25 | // Test case 1: Create param subspace WITHOUT key table first
26 | paramStore := paramstypes.NewSubspace(
27 | cdc,
28 | codec.NewLegacyAmino(),
29 | storeKey,
30 | tkey,
31 | types.ModuleName,
32 | )
33 | // Don't call WithKeyTable here to test the HasKeyTable() branch
34 |
35 | // Test MigrateStore - this should exercise the key table creation branch
36 | err := v1migration.MigrateStore(ctx.Ctx, paramStore)
37 | require.NoError(t, err)
38 |
39 | // Verify params were set correctly
40 | // After MigrateStore, the paramStore now has a key table, so we can use it directly
41 | var params types.Params
42 | paramStore.GetParamSet(ctx.Ctx, ¶ms)
43 | require.Equal(t, uint64(10_000), params.DeploymentGas)
44 | require.Equal(t, uint64(30_000), params.TimeOffset)
45 |
46 | // Test case 2: Create a fresh param subspace with key table already set
47 | storeKey2 := storetypes.NewKVStoreKey(types.StoreKey + "2")
48 | tkey2 := storetypes.NewTransientStoreKey(paramstypes.TStoreKey + "2")
49 | ctx2 := testutil.DefaultContextWithDB(t, storeKey2, tkey2)
50 |
51 | paramStoreWithKeyTable := paramstypes.NewSubspace(
52 | cdc,
53 | codec.NewLegacyAmino(),
54 | storeKey2,
55 | tkey2,
56 | types.ModuleName,
57 | ).WithKeyTable(types.ParamKeyTable())
58 |
59 | // Test MigrateStore with key table already present
60 | err = v1migration.MigrateStore(ctx2.Ctx, paramStoreWithKeyTable)
61 | require.NoError(t, err)
62 |
63 | // Verify params were set correctly
64 | var params2 types.Params
65 | paramStoreWithKeyTable.GetParamSet(ctx2.Ctx, ¶ms2)
66 | require.Equal(t, uint64(10_000), params2.DeploymentGas)
67 | require.Equal(t, uint64(30_000), params2.TimeOffset)
68 | }
69 |
--------------------------------------------------------------------------------
/proto/xion/mint/v1/query.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package xion.mint.v1;
3 |
4 | import "gogoproto/gogo.proto";
5 | import "google/api/annotations.proto";
6 | import "xion/mint/v1/mint.proto";
7 | import "amino/amino.proto";
8 |
9 | option go_package = "github.com/burnt-labs/xion/x/mint/types";
10 |
11 | // Query provides defines the gRPC querier service.
12 | service Query {
13 | // Params returns the total set of minting parameters.
14 | rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
15 | option (google.api.http).get = "/xion/mint/v1/params";
16 | }
17 |
18 | // Inflation returns the current minting inflation value.
19 | rpc Inflation(QueryInflationRequest) returns (QueryInflationResponse) {
20 | option (google.api.http).get = "/xion/mint/v1/inflation";
21 | }
22 |
23 | // AnnualProvisions current minting annual provisions value.
24 | rpc AnnualProvisions(QueryAnnualProvisionsRequest)
25 | returns (QueryAnnualProvisionsResponse) {
26 | option (google.api.http).get = "/xion/mint/v1/annual_provisions";
27 | }
28 | }
29 |
30 | // QueryParamsRequest is the request type for the Query/Params RPC method.
31 | message QueryParamsRequest {}
32 |
33 | // QueryParamsResponse is the response type for the Query/Params RPC method.
34 | message QueryParamsResponse {
35 | // params defines the parameters of the module.
36 | Params params = 1
37 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
38 | }
39 |
40 | // QueryInflationRequest is the request type for the Query/Inflation RPC method.
41 | message QueryInflationRequest {}
42 |
43 | // QueryInflationResponse is the response type for the Query/Inflation RPC
44 | // method.
45 | message QueryInflationResponse {
46 | // inflation is the current minting inflation value.
47 | bytes inflation = 1 [
48 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
49 | (gogoproto.nullable) = false,
50 | (amino.dont_omitempty) = true
51 | ];
52 | }
53 |
54 | // QueryAnnualProvisionsRequest is the request type for the
55 | // Query/AnnualProvisions RPC method.
56 | message QueryAnnualProvisionsRequest {}
57 |
58 | // QueryAnnualProvisionsResponse is the response type for the
59 | // Query/AnnualProvisions RPC method.
60 | message QueryAnnualProvisionsResponse {
61 | // annual_provisions is the current minting annual provisions value.
62 | bytes annual_provisions = 1 [
63 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
64 | (gogoproto.nullable) = false,
65 | (amino.dont_omitempty) = true
66 | ];
67 | }
68 |
--------------------------------------------------------------------------------
/e2e_tests/testdata/keys/vkey.json:
--------------------------------------------------------------------------------
1 | {
2 | "vk_alpha_1": [
3 | "20491192805390485299153009773594534940189261866228447918068658471970481763042",
4 | "9383485363053290200918347156157836566562967994039712273449902621266178545958",
5 | "1"
6 | ],
7 | "vk_beta_2": [
8 | [
9 | "6375614351688725206403948262868962793625744043794305715222011528459656738731",
10 | "4252822878758300859123897981450591353533073413197771768651442665752259397132"
11 | ],
12 | [
13 | "10505242626370262277552901082094356697409835680220590971873171140371331206856",
14 | "21847035105528745403288232691147584728191162732299865338377159692350059136679"
15 | ],
16 | [
17 | "1",
18 | "0"
19 | ]
20 | ],
21 | "vk_gamma_2": [
22 | [
23 | "10857046999023057135944570762232829481370756359578518086990519993285655852781",
24 | "11559732032986387107991004021392285783925812861821192530917403151452391805634"
25 | ],
26 | [
27 | "8495653923123431417604973247489272438418190587263600148770280649306958101930",
28 | "4082367875863433681332203403145435568316851327593401208105741076214120093531"
29 | ],
30 | [
31 | "1",
32 | "0"
33 | ]
34 | ],
35 | "vk_delta_2": [
36 | [
37 | "5681006164308251953002113925585490159382365459900616695069738099616221007440",
38 | "1784372532023285234788112912605016418785853082678430162841833688972404754526"
39 | ],
40 | [
41 | "13207372700374951217972734305987984211299541953272195804403019294285015432230",
42 | "11208098815931498258566335953255768915781024568431472973003740351242145274882"
43 | ],
44 | [
45 | "1",
46 | "0"
47 | ]
48 | ],
49 | "IC": [
50 | [
51 | "13552796159321500446542092333925789627221763995917057705025024736845721942353",
52 | "9680985285040230751644495893215382676081535876363553660374115588862060487034",
53 | "1"
54 | ],
55 | [
56 | "15254776772610533327488814281931287665893943177977310168056722368281728618662",
57 | "14367657701249547918513675533091286383358185662869887316466813062142674499260",
58 | "1"
59 | ],
60 | [
61 | "14866859177758635030079226341862601112983487838511690567895574030672212441676",
62 | "1131454229353397332841644166317603239984551930044689440752008341203688834298",
63 | "1"
64 | ],
65 | [
66 | "14452902482828558270298374737705658351270788428019585241026901331368858527948",
67 | "19097997774606523527158529552645961257150189357357601035078111643953385171384",
68 | "1"
69 | ]
70 | ]
71 | }
72 |
--------------------------------------------------------------------------------
/x/jwk/keeper/vulnerability_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | "crypto/sha256"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 |
9 | jwkMsgServer "github.com/burnt-labs/xion/x/jwk/keeper"
10 | jwktypes "github.com/burnt-labs/xion/x/jwk/types"
11 | )
12 |
13 | func TestAudienceDuplicateVulnerability(t *testing.T) {
14 | k, ctx := setupKeeper(t)
15 | admin := "cosmos1e2fuwe3uhq8zd9nkkk876nawrwdulgv4cxkq74"
16 |
17 | msgServer := jwkMsgServer.NewMsgServerImpl(k)
18 |
19 | // Create audience claim
20 | sum := sha256.Sum256([]byte("test-aud"))
21 | _, err := msgServer.CreateAudienceClaim(ctx, &jwktypes.MsgCreateAudienceClaim{
22 | Admin: admin,
23 | AudHash: sum[:],
24 | })
25 | require.NoError(t, err)
26 |
27 | // Create initial audience
28 | _, err = msgServer.CreateAudience(ctx, &jwktypes.MsgCreateAudience{
29 | Admin: admin,
30 | Aud: "test-aud",
31 | Key: "initial-key",
32 | })
33 | require.NoError(t, err)
34 |
35 | // Check initial state
36 | allAudiences := k.GetAllAudience(ctx)
37 | require.Len(t, allAudiences, 1, "Should have exactly 1 audience initially")
38 |
39 | initialAudience, found := k.GetAudience(ctx, "test-aud")
40 | require.True(t, found, "Initial audience should exist")
41 | require.Equal(t, "initial-key", initialAudience.Key, "Initial key should match")
42 |
43 | // Try to update with only Key change - this is where the vulnerability is claimed to be
44 | _, err = msgServer.UpdateAudience(ctx, &jwktypes.MsgUpdateAudience{
45 | Admin: admin,
46 | NewAdmin: admin, // Keep same admin
47 | Aud: "test-aud",
48 | Key: "updated-key",
49 | NewAud: "", // Empty NewAud - this is the key part of the vulnerability claim
50 | })
51 | require.NoError(t, err)
52 |
53 | // Check final state - this is where we test if duplicates were created
54 | allAudiences = k.GetAllAudience(ctx)
55 | require.Len(t, allAudiences, 1, "Should still have exactly 1 audience after update - NO DUPLICATES!")
56 |
57 | // Check if we can retrieve the audience and if it was properly updated
58 | audience, found := k.GetAudience(ctx, "test-aud")
59 | require.True(t, found, "Audience should still exist after update")
60 | require.Equal(t, "updated-key", audience.Key, "Key should be updated")
61 | require.Equal(t, admin, audience.Admin, "Admin should remain the same")
62 | require.Equal(t, "test-aud", audience.Aud, "Aud should remain the same")
63 |
64 | t.Logf("Test completed successfully. No duplicates were created.")
65 | t.Logf("Final audience count: %d", len(allAudiences))
66 | t.Logf("Final audience: Aud=%s, Admin=%s, Key=%s", audience.Aud, audience.Admin, audience.Key)
67 | }
68 |
--------------------------------------------------------------------------------
/x/globalfee/types/types_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "encoding/json"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 |
9 | "github.com/cosmos/cosmos-sdk/codec"
10 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
11 |
12 | "github.com/burnt-labs/xion/x/globalfee/types"
13 | )
14 |
15 | func TestGlobalFeeGenesis(t *testing.T) {
16 | // Test DefaultGenesisState
17 | defaultGenesis := types.DefaultGenesisState()
18 | require.NotNil(t, defaultGenesis)
19 | require.Equal(t, types.DefaultParams(), defaultGenesis.Params)
20 |
21 | // Test NewGenesisState
22 | params := types.DefaultParams()
23 | genesis := types.NewGenesisState(params)
24 | require.NotNil(t, genesis)
25 | require.Equal(t, params, genesis.Params)
26 |
27 | // Test GetGenesisStateFromAppState
28 | appState := map[string]interface{}{
29 | types.ModuleName: map[string]interface{}{
30 | "params": map[string]interface{}{
31 | "minimum_gas_prices": []interface{}{},
32 | "bypass_min_fee_msg_types": []interface{}{},
33 | "max_total_bypass_min_fee_msg_gas_usage": uint64(1000000),
34 | },
35 | },
36 | }
37 |
38 | cdc := codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
39 | appStateBytes := make(map[string]json.RawMessage)
40 | for k, v := range appState {
41 | if b, err := json.Marshal(v); err == nil {
42 | appStateBytes[k] = b
43 | }
44 | }
45 | genesisState := types.GetGenesisStateFromAppState(cdc, appStateBytes)
46 | require.NotNil(t, genesisState)
47 |
48 | // Test ValidateGenesis
49 | err := types.ValidateGenesis(*defaultGenesis)
50 | require.NoError(t, err)
51 | }
52 |
53 | func TestGlobalFeeParams(t *testing.T) {
54 | // Test DefaultParams
55 | params := types.DefaultParams()
56 | require.NotNil(t, params)
57 | require.NotNil(t, params.MinimumGasPrices)
58 | require.NotNil(t, params.BypassMinFeeMsgTypes)
59 | require.Equal(t, uint64(1_000_000), params.MaxTotalBypassMinFeeMsgGasUsage)
60 |
61 | // Test ParamKeyTable
62 | keyTable := types.ParamKeyTable()
63 | require.NotNil(t, keyTable)
64 |
65 | // Test ValidateBasic
66 | err := params.ValidateBasic()
67 | require.NoError(t, err)
68 |
69 | // Test ParamSetPairs
70 | pairs := params.ParamSetPairs()
71 | require.NotNil(t, pairs)
72 | require.Len(t, pairs, 3) // MinimumGasPrices, BypassMinFeeMsgTypes, MaxTotalBypassMinFeeMsgGasUsage
73 | }
74 |
75 | func TestGlobalFeeCodec(t *testing.T) {
76 | // Test codec instantiation
77 | amino := codec.NewLegacyAmino()
78 | require.NotNil(t, amino)
79 |
80 | // Test interface registry
81 | registry := codectypes.NewInterfaceRegistry()
82 | require.NotNil(t, registry)
83 | }
84 |
--------------------------------------------------------------------------------
/.github/workflows/create-release.yaml:
--------------------------------------------------------------------------------
1 | name: Create Release
2 | # Run for new release tags only
3 |
4 | on:
5 | workflow_dispatch:
6 | push:
7 | tags:
8 | - 'v[0-9]+\.[0-9]+\.[0-9]+'
9 | - 'v[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+'
10 |
11 | concurrency:
12 | group: ${{ github.workflow }}-${{ github.ref }}
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | lint:
17 | name: Golang CI Lint
18 | uses: burnt-labs/xion/.github/workflows/golangci-lint.yaml@workflows/main
19 | secrets: inherit
20 |
21 | update-swagger:
22 | name: Update Swagger
23 | uses: burnt-labs/xion/.github/workflows/update-swagger.yaml@workflows/main
24 | secrets: inherit
25 |
26 | unit-tests:
27 | name: Go Unit Tests
28 | uses: burnt-labs/xion/.github/workflows/tests.yaml@workflows/main
29 | secrets: inherit
30 |
31 | build-darwin:
32 | name: Build Binaries
33 | uses: burnt-labs/xion/.github/workflows/binaries-darwin.yaml@workflows/main
34 | secrets: inherit
35 |
36 | build-linux:
37 | name: Build Binaries
38 | uses: burnt-labs/xion/.github/workflows/binaries-linux.yaml@workflows/main
39 | secrets: inherit
40 |
41 | build-docker:
42 | name: Build Docker Images
43 | needs: build-linux
44 | uses: burnt-labs/xion/.github/workflows/docker-build.yaml@workflows/main
45 | secrets: inherit
46 |
47 | push-docker:
48 | name: Push Docker Images
49 | needs: build-docker
50 | uses: burnt-labs/xion/.github/workflows/docker-push.yaml@workflows/main
51 | secrets: inherit
52 |
53 | push-heighliner:
54 | name: Push Heighliner Images
55 | needs: build-docker
56 | uses: burnt-labs/xion/.github/workflows/heighliner-push.yaml@workflows/main
57 | secrets: inherit
58 |
59 | docker-scout:
60 | name: Docker Scout
61 | needs: build-docker
62 | uses: burnt-labs/xion/.github/workflows/docker-scout.yaml@workflows/main
63 | secrets: inherit
64 |
65 | e2e-tests:
66 | name: E2E tests
67 | needs:
68 | - build-docker
69 | uses: burnt-labs/xion/.github/workflows/e2e-tests.yaml@workflows/main
70 | secrets: inherit
71 |
72 | build-release:
73 | name: Build Release
74 | needs:
75 | - build-linux
76 | - lint
77 | - update-swagger
78 | - unit-tests
79 | - build-darwin
80 | - docker-scout
81 | - e2e-tests
82 | uses: burnt-labs/xion/.github/workflows/exec-goreleaser.yaml@workflows/main
83 | secrets: inherit
84 |
85 | verify-installers:
86 | name: Verify Package Installers
87 | needs: build-release
88 | uses: burnt-labs/xion/.github/workflows/verify-installers.yaml@workflows/main
89 | secrets: inherit
90 |
--------------------------------------------------------------------------------
/x/feeabs/types/errors_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | sdkerrors "cosmossdk.io/errors"
9 | )
10 |
11 | func TestErrors(t *testing.T) {
12 | // Test all error variables to ensure they are properly defined
13 | errorTests := []struct {
14 | name string
15 | err error
16 | code uint32
17 | codespace string
18 | message string
19 | }{
20 | {
21 | name: "ErrInvalidExchangeRate",
22 | err: ErrInvalidExchangeRate,
23 | code: 1,
24 | codespace: ModuleName,
25 | message: "invalid exchange rate",
26 | },
27 | {
28 | name: "ErrInvalidIBCFees",
29 | err: ErrInvalidIBCFees,
30 | code: 2,
31 | codespace: ModuleName,
32 | message: "invalid ibc fees",
33 | },
34 | {
35 | name: "ErrHostZoneConfigNotFound",
36 | err: ErrHostZoneConfigNotFound,
37 | code: 3,
38 | codespace: ModuleName,
39 | message: "host zone config not found",
40 | },
41 | {
42 | name: "ErrDuplicateHostZoneConfig",
43 | err: ErrDuplicateHostZoneConfig,
44 | code: 4,
45 | codespace: ModuleName,
46 | message: "duplicate host zone config",
47 | },
48 | {
49 | name: "ErrNotEnoughFundInModuleAddress",
50 | err: ErrNotEnoughFundInModuleAddress,
51 | code: 5,
52 | codespace: ModuleName,
53 | message: "not have funding yet",
54 | },
55 | {
56 | name: "ErrUnsupportedDenom",
57 | err: ErrUnsupportedDenom,
58 | code: 6,
59 | codespace: ModuleName,
60 | message: "unsupported denom",
61 | },
62 | {
63 | name: "ErrHostZoneFrozen",
64 | err: ErrHostZoneFrozen,
65 | code: 7,
66 | codespace: ModuleName,
67 | message: "host zone is frozen",
68 | },
69 | {
70 | name: "ErrHostZoneOutdated",
71 | err: ErrHostZoneOutdated,
72 | code: 8,
73 | codespace: ModuleName,
74 | message: "host zone is outdated",
75 | },
76 | {
77 | name: "ErrInvalidSigner",
78 | err: ErrInvalidSigner,
79 | code: 9,
80 | codespace: ModuleName,
81 | message: "invalid signer",
82 | },
83 | }
84 |
85 | for _, tt := range errorTests {
86 | t.Run(tt.name, func(t *testing.T) {
87 | require.NotNil(t, tt.err)
88 |
89 | // Test that it's a properly registered error
90 | sdkErr, ok := tt.err.(*sdkerrors.Error)
91 | require.True(t, ok, "error should be of type *sdkerrors.Error")
92 |
93 | require.Equal(t, tt.code, sdkErr.ABCICode())
94 | require.Equal(t, tt.codespace, sdkErr.Codespace())
95 | require.Contains(t, sdkErr.Error(), tt.message)
96 | })
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/x/jwk/keeper/audience_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
9 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
10 |
11 | "github.com/burnt-labs/xion/x/jwk/types"
12 | )
13 |
14 | func TestAudienceOperations(t *testing.T) {
15 | k, ctx := setupKeeper(t)
16 |
17 | // Test audience creation
18 | admin := authtypes.NewModuleAddress(govtypes.ModuleName).String()
19 | audience := types.Audience{
20 | Aud: "test-audience",
21 | Admin: admin,
22 | Key: "test-key",
23 | }
24 |
25 | // Test SetAudience
26 | k.SetAudience(ctx, audience)
27 |
28 | // Test GetAudience
29 | retrievedAudience, found := k.GetAudience(ctx, "test-audience")
30 | require.True(t, found)
31 | require.Equal(t, audience, retrievedAudience)
32 |
33 | // Test GetAudience with non-existent audience
34 | _, found = k.GetAudience(ctx, "non-existent")
35 | require.False(t, found)
36 |
37 | // Test GetAllAudience
38 | allAudiences := k.GetAllAudience(ctx)
39 | require.Len(t, allAudiences, 1)
40 | require.Equal(t, audience, allAudiences[0])
41 |
42 | // Add another audience
43 | audience2 := types.Audience{
44 | Aud: "test-audience-2",
45 | Admin: admin,
46 | Key: "test-key-2",
47 | }
48 | k.SetAudience(ctx, audience2)
49 |
50 | // Verify we now have 2 audiences
51 | allAudiences = k.GetAllAudience(ctx)
52 | require.Len(t, allAudiences, 2)
53 |
54 | // Test RemoveAudience
55 | k.RemoveAudience(ctx, "test-audience")
56 |
57 | // Verify audience was removed
58 | _, found = k.GetAudience(ctx, "test-audience")
59 | require.False(t, found)
60 |
61 | // Verify we now have 1 audience
62 | allAudiences = k.GetAllAudience(ctx)
63 | require.Len(t, allAudiences, 1)
64 | require.Equal(t, audience2, allAudiences[0])
65 | }
66 |
67 | func TestAudienceClaimOperations(t *testing.T) {
68 | k, ctx := setupKeeper(t)
69 |
70 | // Test audience claim creation
71 | claim := []byte("test-claim-hash")
72 | signer := authtypes.NewModuleAddress(govtypes.ModuleName)
73 |
74 | // Test SetAudienceClaim
75 | k.SetAudienceClaim(ctx, claim, signer)
76 |
77 | // Test GetAudienceClaim
78 | retrievedClaim, found := k.GetAudienceClaim(ctx, claim)
79 | require.True(t, found)
80 | require.Equal(t, signer.String(), retrievedClaim.Signer)
81 |
82 | // Test GetAudienceClaim with non-existent claim
83 | _, found = k.GetAudienceClaim(ctx, []byte("non-existent"))
84 | require.False(t, found)
85 |
86 | // Test RemoveAudienceClaim
87 | k.RemoveAudienceClaim(ctx, claim)
88 |
89 | // Verify claim was removed
90 | _, found = k.GetAudienceClaim(ctx, claim)
91 | require.False(t, found)
92 | }
93 |
--------------------------------------------------------------------------------
/app/v25_upgrade/migrator.go:
--------------------------------------------------------------------------------
1 | package v25_upgrade
2 |
3 | import (
4 | "fmt"
5 |
6 | wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
7 | "github.com/gogo/protobuf/proto"
8 |
9 | storetypes "cosmossdk.io/store/types"
10 |
11 | sdk "github.com/cosmos/cosmos-sdk/types"
12 | )
13 |
14 | // MigrateContracts fixes corrupted contracts that cannot unmarshal
15 | // This is called from the v25 upgrade handler
16 | func MigrateContracts(ctx sdk.Context, storeKey storetypes.StoreKey) error {
17 | logger := ctx.Logger()
18 | logger.Info("v25: starting contract migration")
19 |
20 | store := ctx.KVStore(storeKey)
21 |
22 | var totalContracts int
23 | var fixedContracts int
24 | var skippedContracts int
25 | var failedContracts int
26 |
27 | prefix := []byte{ContractKeyPrefix}
28 | iterator := storetypes.KVStorePrefixIterator(store, prefix)
29 | defer iterator.Close()
30 |
31 | for ; iterator.Valid(); iterator.Next() {
32 | totalContracts++
33 |
34 | key := iterator.Key()
35 | data := iterator.Value()
36 |
37 | // Get address for logging
38 | addressBytes := key[len(prefix):]
39 | address := sdk.AccAddress(addressBytes).String()
40 |
41 | // Try to unmarshal - if it succeeds, skip it (already working)
42 | var contractInfo wasmtypes.ContractInfo
43 | unmarshalErr := proto.Unmarshal(data, &contractInfo)
44 |
45 | if unmarshalErr == nil {
46 | // Contract is already working - skip it
47 | skippedContracts++
48 | if totalContracts%1000 == 0 {
49 | logger.Info("v25 migration progress",
50 | "processed", totalContracts,
51 | "fixed", fixedContracts,
52 | "skipped", skippedContracts)
53 | }
54 | continue
55 | }
56 |
57 | // Contract fails to unmarshal - needs fixing
58 | // Use the FixContract function from fixer.go
59 | result := FixContract(address, data)
60 |
61 | if !result.FixSucceeded || !result.UnmarshalAfter {
62 | logger.Error("v25: failed to fix contract",
63 | "address", address,
64 | "original_state", result.OriginalState,
65 | "error", result.Error)
66 | failedContracts++
67 | continue
68 | }
69 |
70 | // Write the fixed data
71 | store.Set(key, result.FixedData)
72 | fixedContracts++
73 |
74 | if fixedContracts%100 == 0 {
75 | logger.Info("v25 migration progress",
76 | "processed", totalContracts,
77 | "fixed", fixedContracts,
78 | "skipped", skippedContracts)
79 | }
80 | }
81 |
82 | logger.Info("v25 migration complete",
83 | "total", totalContracts,
84 | "fixed", fixedContracts,
85 | "skipped", skippedContracts,
86 | "failed", failedContracts)
87 |
88 | if failedContracts > 0 {
89 | return fmt.Errorf("failed to fix %d contracts", failedContracts)
90 | }
91 |
92 | return nil
93 | }
94 |
--------------------------------------------------------------------------------
/x/mint/types/params_legacy_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 |
8 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
9 | )
10 |
11 | func TestParamKeyTable(t *testing.T) {
12 | table := ParamKeyTable()
13 | require.NotNil(t, table)
14 |
15 | // We can't directly access the internal structure, but we can test that it doesn't panic
16 | require.NotPanics(t, func() {
17 | ParamKeyTable()
18 | })
19 | }
20 |
21 | func TestParamSetPairs(t *testing.T) {
22 | params := DefaultParams()
23 | pairs := params.ParamSetPairs()
24 |
25 | require.Len(t, pairs, 6)
26 |
27 | // Check that all expected parameter keys are present
28 | expectedKeys := [][]byte{
29 | KeyMintDenom,
30 | KeyInflationRateChange,
31 | KeyInflationMax,
32 | KeyInflationMin,
33 | KeyGoalBonded,
34 | KeyBlocksPerYear,
35 | }
36 |
37 | pairKeys := make([][]byte, len(pairs))
38 | for i, pair := range pairs {
39 | pairKeys[i] = pair.Key
40 | }
41 |
42 | for _, expectedKey := range expectedKeys {
43 | found := false
44 | for _, pairKey := range pairKeys {
45 | if string(expectedKey) == string(pairKey) {
46 | found = true
47 | break
48 | }
49 | }
50 | require.True(t, found, "Expected key %s not found in param set pairs", string(expectedKey))
51 | }
52 | }
53 |
54 | func TestParamSetPairsValidation(t *testing.T) {
55 | params := DefaultParams()
56 | pairs := params.ParamSetPairs()
57 |
58 | // Test that each pair has a validation function
59 | for _, pair := range pairs {
60 | require.NotNil(t, pair.ValidatorFn, "Validation function should not be nil for key %s", string(pair.Key))
61 |
62 | // Test that validation functions work with default values
63 | switch string(pair.Key) {
64 | case string(KeyMintDenom):
65 | err := pair.ValidatorFn(params.MintDenom)
66 | require.NoError(t, err)
67 | case string(KeyInflationRateChange):
68 | err := pair.ValidatorFn(params.InflationRateChange)
69 | require.NoError(t, err)
70 | case string(KeyInflationMax):
71 | err := pair.ValidatorFn(params.InflationMax)
72 | require.NoError(t, err)
73 | case string(KeyInflationMin):
74 | err := pair.ValidatorFn(params.InflationMin)
75 | require.NoError(t, err)
76 | case string(KeyGoalBonded):
77 | err := pair.ValidatorFn(params.GoalBonded)
78 | require.NoError(t, err)
79 | case string(KeyBlocksPerYear):
80 | err := pair.ValidatorFn(params.BlocksPerYear)
81 | require.NoError(t, err)
82 | }
83 | }
84 | }
85 |
86 | func TestParamSetImplementation(t *testing.T) {
87 | params := &Params{}
88 |
89 | // Test that Params implements paramtypes.ParamSet
90 | require.Implements(t, (*paramtypes.ParamSet)(nil), params)
91 | }
92 |
--------------------------------------------------------------------------------