From 7d0ea6358a63d15d61d9b65bf64b5887679edb35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 20:46:29 -0600 Subject: [PATCH 01/10] build(deps): Bump github.com/cosmos/ibc-go/v6 from 6.1.1 to 6.2.0 (#2078) Bumps [github.com/cosmos/ibc-go/v6](https://github.com/cosmos/ibc-go) from 6.1.1 to 6.2.0. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v6.2.0/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v6.1.1...v6.2.0) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v6 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6648b755ea..dba3ac77fa 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.3 github.com/cosmos/cosmos-sdk v0.46.12 github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/ibc-go/v6 v6.1.1 + github.com/cosmos/ibc-go/v6 v6.2.0 github.com/ethereum/go-ethereum v1.12.0 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 diff --git a/go.sum b/go.sum index c8a9f4a4e1..d9ec5a4896 100644 --- a/go.sum +++ b/go.sum @@ -441,8 +441,8 @@ github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4 github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cosmos/iavl v0.19.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v6 v6.1.1 h1:oqqMNyjj6SLQF8rvgCaDGwfdITEIsbhs8F77/8xvRIo= -github.com/cosmos/ibc-go/v6 v6.1.1/go.mod h1:NL17FpFAaWjRFVb1T7LUKuOoMSsATPpu+Icc4zL5/Ik= +github.com/cosmos/ibc-go/v6 v6.2.0 h1:HKS5WNxQrlmjowHb73J9LqlNJfvTnvkbhXZ9QzNTU7Q= +github.com/cosmos/ibc-go/v6 v6.2.0/go.mod h1:+S3sxcNwOhgraYDJAhIFDg5ipXHaUnJrg7tOQqGyWlc= github.com/cosmos/interchain-accounts v0.4.3 h1:WedxEa/Hj/2GY7AF6CafkEPJ/Z9rhl3rT1mRwNHsdts= github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= From a3235464f0df1371ae7cab0af2f995638bb0b903 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:08:17 +0530 Subject: [PATCH 02/10] build(deps): Bump github.com/golangci/golangci-lint (#2080) Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.52.2 to 1.53.0. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.52.2...v1.53.0) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 45 ++++++++++++++------------ go.sum | 99 +++++++++++++++++++++++++++++++++------------------------- 2 files changed, 81 insertions(+), 63 deletions(-) diff --git a/go.mod b/go.mod index dba3ac77fa..72f13eacf6 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 - github.com/golangci/golangci-lint v1.52.2 + github.com/golangci/golangci-lint v1.53.0 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/ignite/cli v0.26.1 @@ -48,22 +48,24 @@ require ( cloud.google.com/go/iam v0.13.0 // indirect cloud.google.com/go/storage v1.28.1 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect + github.com/4meepo/tagalign v1.2.2 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/Abirdcfly/dupword v0.0.11 // indirect - github.com/Antonboom/errname v0.1.9 // indirect - github.com/Antonboom/nilnil v0.1.3 // indirect + github.com/Antonboom/errname v0.1.10 // indirect + github.com/Antonboom/nilnil v0.1.5 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/BurntSushi/toml v1.2.1 // indirect + github.com/BurntSushi/toml v1.3.0 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/OpenPeeDeeP/depguard v1.1.1 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.0.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect + github.com/alexkohler/nakedret/v2 v2.0.1 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -79,7 +81,8 @@ require ( github.com/breml/bidichk v0.2.4 // indirect github.com/breml/errchkjson v0.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/butuzov/ireturn v0.1.1 // indirect + github.com/butuzov/ireturn v0.2.0 // indirect + github.com/butuzov/mirror v1.1.0 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -124,7 +127,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect - github.com/go-critic/go-critic v0.7.0 // indirect + github.com/go-critic/go-critic v0.8.1 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -195,18 +198,17 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/julz/importas v0.1.0 // indirect - github.com/junk1tm/musttag v0.5.0 // indirect github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kulti/thelper v0.6.3 // indirect - github.com/kunwardeep/paralleltest v1.0.6 // indirect + github.com/kunwardeep/paralleltest v1.0.7 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect github.com/ldez/gomoddirectives v0.2.3 // indirect - github.com/ldez/tagliatelle v0.4.0 // indirect + github.com/ldez/tagliatelle v0.5.0 // indirect github.com/leonklingele/grouper v1.1.1 // indirect - github.com/lib/pq v1.10.7 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -230,9 +232,9 @@ require ( github.com/mtibben/percent v0.2.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.9.5 // indirect + github.com/nishanths/exhaustive v0.10.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.9.0 // indirect + github.com/nunnatsa/ginkgolinter v0.12.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo v1.16.4 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect @@ -242,7 +244,7 @@ require ( github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.4.0 // indirect + github.com/polyfloyd/go-errorlint v1.4.2 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect @@ -261,11 +263,11 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect - github.com/securego/gosec/v2 v2.15.0 // indirect + github.com/securego/gosec/v2 v2.16.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/sivchari/containedctx v1.0.2 // indirect + github.com/sirupsen/logrus v1.9.2 // indirect + github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect github.com/sivchari/tenv v1.7.1 // indirect github.com/sonatard/noctx v0.0.2 // indirect @@ -284,7 +286,7 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/tetafro/godot v1.4.11 // indirect github.com/tidwall/btree v1.5.0 // indirect - github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect + github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect github.com/timonwong/loggercheck v0.9.4 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect @@ -297,19 +299,22 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xen0n/gosmopolitan v1.2.1 // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect + github.com/ykadowak/zerologlint v0.1.1 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.24.0 // indirect + go.tmz.dev/musttag v0.7.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/goleak v1.1.12 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.9.0 // indirect - golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect + golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect @@ -318,7 +323,7 @@ require ( golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/tools v0.9.2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.122.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index d9ec5a4896..19baa5a621 100644 --- a/go.sum +++ b/go.sum @@ -205,24 +205,26 @@ filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmG filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= +github.com/4meepo/tagalign v1.2.2 h1:kQeUTkFTaBRtd/7jm8OKJl9iHk0gAO+TDFPHGSna0aw= +github.com/4meepo/tagalign v1.2.2/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU= github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA= -github.com/Antonboom/errname v0.1.9 h1:BZDX4r3l4TBZxZ2o2LNrlGxSHran4d1u4veZdoORTT4= -github.com/Antonboom/errname v0.1.9/go.mod h1:nLTcJzevREuAsgTbG85UsuiWpMpAqbKD1HNZ29OzE58= -github.com/Antonboom/nilnil v0.1.3 h1:6RTbx3d2mcEu3Zwq9TowQpQMVpP75zugwOtqY1RTtcE= -github.com/Antonboom/nilnil v0.1.3/go.mod h1:iOov/7gRcXkeEU+EMGpBu2ORih3iyVEiWjeste1SJm8= +github.com/Antonboom/errname v0.1.10 h1:RZ7cYo/GuZqjr1nuJLNe8ZH+a+Jd9DaZzttWzak9Bls= +github.com/Antonboom/errname v0.1.10/go.mod h1:xLeiCIrvVNpUtsN0wxAh05bNIZpqE22/qDMnTBTttiA= +github.com/Antonboom/nilnil v0.1.5 h1:X2JAdEVcbPaOom2TUa1FxZ3uyuUlex0XMLGYMemu6l0= +github.com/Antonboom/nilnil v0.1.5/go.mod h1:I24toVuBKhfP5teihGWctrRiPbRKHwZIFOvc6v3HZXk= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.0 h1:Ws8e5YmnrGEHzZEzg0YvK/7COGYtTC5PbaH9oSSbgfA= +github.com/BurntSushi/toml v1.3.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= @@ -245,8 +247,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= -github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/OpenPeeDeeP/depguard/v2 v2.0.1 h1:yr9ZswukmNxl/hmJHEoLEjCF1d+f2pQrC0m1jzVljAE= +github.com/OpenPeeDeeP/depguard/v2 v2.0.1/go.mod h1:gwSk4XDpowOuQSsMWNK5F7+C3kMz7QIexKRkD/GL4GU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -268,6 +270,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexkohler/nakedret/v2 v2.0.1 h1:DLFVWaHbEntNHBYGhPX+AhCM1gCErTs35IFWPh6Bnn0= +github.com/alexkohler/nakedret/v2 v2.0.1/go.mod h1:2b8Gkk0GsOrqQv/gPWjNLDSKwG8I5moSXG1K4VIBcTQ= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= @@ -349,8 +353,10 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= -github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= +github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= +github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= @@ -583,8 +589,8 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-critic/go-critic v0.7.0 h1:tqbKzB8pqi0NsRZ+1pyU4aweAF7A7QN0Pi4Q02+rYnQ= -github.com/go-critic/go-critic v0.7.0/go.mod h1:moYzd7GdVXE2C2hYTwd7h0CPcqlUeclsyBRwMa38v64= +github.com/go-critic/go-critic v0.8.1 h1:16omCF1gN3gTzt4j4J6fKI/HnRojhEp+Eks6EuKw3vw= +github.com/go-critic/go-critic v0.8.1/go.mod h1:kpzXl09SIJX1cr9TB/g/sAG+eFEl7ZS9f9cqvZtyNl0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -601,7 +607,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -623,6 +629,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= @@ -718,8 +725,8 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.52.2 h1:FrPElUUI5rrHXg1mQ7KxI1MXPAw5lBVskiz7U7a8a1A= -github.com/golangci/golangci-lint v1.52.2/go.mod h1:S5fhC5sHM5kE22/HcATKd1XLWQxX+y7mHj8B5H91Q/0= +github.com/golangci/golangci-lint v1.53.0 h1:UigoFKBXwmoJVNWeht27A0jnuZjdOIV4lvMYuA9naj4= +github.com/golangci/golangci-lint v1.53.0/go.mod h1:Cwv11QjWoiq/UXE4pL3LInd7SNwMWV8S5Obur2pA5Ug= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= @@ -779,6 +786,7 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.3 h1:FAgZmpLl/SXurPEZyCMPBIiiYeTbqfjlbdnCNTAkbGE= @@ -972,8 +980,6 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/junk1tm/musttag v0.5.0 h1:bV1DTdi38Hi4pG4OVWa7Kap0hi0o7EczuK6wQt9zPOM= -github.com/junk1tm/musttag v0.5.0/go.mod h1:PcR7BA+oREQYvHwgjIDmw3exJeds5JzRcvEJTfjrA0M= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -1009,8 +1015,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= -github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= +github.com/kunwardeep/paralleltest v1.0.7 h1:2uCk94js0+nVNQoHZNLBkAR1DQJrVzw6T0RMzJn55dQ= +github.com/kunwardeep/paralleltest v1.0.7/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= @@ -1019,16 +1025,16 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.4.0 h1:sylp7d9kh6AdXN2DpVGHBRb5guTVAgOxqNGhbqc4b1c= -github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I= +github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= +github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -1146,14 +1152,14 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6Fx github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.9.5 h1:TzssWan6orBiLYVqewCG8faud9qlFntJE30ACpzmGME= -github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= +github.com/nishanths/exhaustive v0.10.0 h1:BMznKAcVa9WOoLq/kTGp4NJOJSMwEpcpjFNAVRfPlSo= +github.com/nishanths/exhaustive v0.10.0/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= github.com/notional-labs/wasmd v0.31.0-umee.46 h1:wsEWfXhsTw39gtIhLdMNRKVe023LZz0gO0UQS0b1t7E= github.com/notional-labs/wasmd v0.31.0-umee.46/go.mod h1:S5TjKrcwxj/h4cnAiX4z2yxYox0JgUzzADo28W52uK8= -github.com/nunnatsa/ginkgolinter v0.9.0 h1:Sm0zX5QfjJzkeCjEp+t6d3Ha0jwvoDjleP9XCsrEzOA= -github.com/nunnatsa/ginkgolinter v0.9.0/go.mod h1:FHaMLURXP7qImeH6bvxWJUpyH+2tuqe5j4rW1gxJRmI= +github.com/nunnatsa/ginkgolinter v0.12.0 h1:seZo112n+lt0gdLJ/Jh70mzvrqbABWFpXd1bZTLTByM= +github.com/nunnatsa/ginkgolinter v0.12.0/go.mod h1:dJIGXYXbkBswqa/pIzG0QlVTTDSBMxDoCFwhsl4Uras= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1169,12 +1175,12 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1229,8 +1235,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.4.0 h1:b+sQ5HibPIAjEZwtuwU8Wz/u0dMZ7YL+bk+9yWyHVJk= -github.com/polyfloyd/go-errorlint v1.4.0/go.mod h1:qJCkPeBn+0EXkdKTrUCcuFStM2xrDKfxI3MGLXPexUs= +github.com/polyfloyd/go-errorlint v1.4.2 h1:CU+O4181IxFDdPH6t/HT7IiDj1I7zxNi1RIUxYwn8d0= +github.com/polyfloyd/go-errorlint v1.4.2/go.mod h1:k6fU/+fQe38ednoZS51T7gSIGQW1y94d6TkSr35OzH8= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -1326,8 +1332,8 @@ github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1 github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/securego/gosec/v2 v2.15.0 h1:v4Ym7FF58/jlykYmmhZ7mTm7FQvN/setNm++0fgIAtw= -github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8= +github.com/securego/gosec/v2 v2.16.0 h1:Pi0JKoasQQ3NnoRao/ww/N/XdynIB9NRYYZT5CyOs5U= +github.com/securego/gosec/v2 v2.16.0/go.mod h1:xvLcVZqUfo4aAQu56TNv7/Ltz6emAOQAEsrZrt7uGlI= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= @@ -1344,10 +1350,10 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= -github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= +github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= @@ -1440,8 +1446,8 @@ github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vl github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= -github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo= -github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= @@ -1502,6 +1508,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw= +github.com/xen0n/gosmopolitan v1.2.1/go.mod h1:JsHq/Brs1o050OOdmzHeOr0N7OtlnKRAGAsElF8xBQA= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -1511,6 +1519,8 @@ github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsT github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= +github.com/ykadowak/zerologlint v0.1.1 h1:CA1+RsGS1DbBn3jJP2jpWfiMJipWdeqJfSY0GpNgqaY= +github.com/ykadowak/zerologlint v0.1.1/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1524,6 +1534,7 @@ github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= +go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -1540,6 +1551,8 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.tmz.dev/musttag v0.7.0 h1:QfytzjTWGXZmChoX0L++7uQN+yRCPfyFm+whsM+lfGc= +go.tmz.dev/musttag v0.7.0/go.mod h1:oTFPvgOkJmp5kYL02S8+jrH0eLrBIl57rzWeA26zDEM= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1600,8 +1613,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= -golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea h1:vLCWI/yYrdEHyN2JzIzPO3aaQJHQdp89IZBA/+azVC4= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 h1:J74nGeMgeFnYQJN59eFwh06jX/V8g0lB7LWpjSLxtgU= @@ -1999,8 +2012,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.9.2 h1:UXbndbirwCAx6TULftIfie/ygDNCwxEie+IiNP1IcNc= +golang.org/x/tools v0.9.2/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 2ae7d39a784df0237611ae615c260def7b9b3335 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 12:58:50 +0530 Subject: [PATCH 03/10] build(deps): Bump github.com/golangci/golangci-lint (#2082) Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.53.0 to 1.53.2. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.53.0...v1.53.2) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 72f13eacf6..0d3fe57383 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 - github.com/golangci/golangci-lint v1.53.0 + github.com/golangci/golangci-lint v1.53.2 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/ignite/cli v0.26.1 @@ -62,7 +62,7 @@ require ( github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/OpenPeeDeeP/depguard/v2 v2.0.1 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect github.com/alexkohler/nakedret/v2 v2.0.1 // indirect @@ -323,7 +323,7 @@ require ( golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.9.2 // indirect + golang.org/x/tools v0.9.3 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.122.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 19baa5a621..80078009f1 100644 --- a/go.sum +++ b/go.sum @@ -247,8 +247,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard/v2 v2.0.1 h1:yr9ZswukmNxl/hmJHEoLEjCF1d+f2pQrC0m1jzVljAE= -github.com/OpenPeeDeeP/depguard/v2 v2.0.1/go.mod h1:gwSk4XDpowOuQSsMWNK5F7+C3kMz7QIexKRkD/GL4GU= +github.com/OpenPeeDeeP/depguard/v2 v2.1.0 h1:aQl70G173h/GZYhWf36aE5H0KaujXfVMnn/f1kSDVYY= +github.com/OpenPeeDeeP/depguard/v2 v2.1.0/go.mod h1:PUBgk35fX4i7JDmwzlJwJ+GMe6NfO1723wmJMgPThNQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -725,8 +725,8 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.53.0 h1:UigoFKBXwmoJVNWeht27A0jnuZjdOIV4lvMYuA9naj4= -github.com/golangci/golangci-lint v1.53.0/go.mod h1:Cwv11QjWoiq/UXE4pL3LInd7SNwMWV8S5Obur2pA5Ug= +github.com/golangci/golangci-lint v1.53.2 h1:52pgJKXiAuyfcOa8HJPIrZk1oMgpyXeN8TUxpcteweM= +github.com/golangci/golangci-lint v1.53.2/go.mod h1:fz9DDC9UABJ7SFHTz0XnkiYzb4su7YpuB9ucsgdUfCk= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= @@ -2012,8 +2012,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.9.2 h1:UXbndbirwCAx6TULftIfie/ygDNCwxEie+IiNP1IcNc= -golang.org/x/tools v0.9.2/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 81d2d733e3a94b6300f11074702abb41efdfd8ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 17:14:20 +0200 Subject: [PATCH 04/10] build(deps): Bump github.com/CosmWasm/wasmvm from 1.2.3 to 1.2.4 (#2083) Bumps [github.com/CosmWasm/wasmvm](https://github.com/CosmWasm/wasmvm) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/CosmWasm/wasmvm/releases) - [Changelog](https://github.com/CosmWasm/wasmvm/blob/main/CHANGELOG.md) - [Commits](https://github.com/CosmWasm/wasmvm/compare/v1.2.3...v1.2.4) --- updated-dependencies: - dependency-name: github.com/CosmWasm/wasmvm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0d3fe57383..262ce76047 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/errors v1.0.0-beta.7 cosmossdk.io/math v1.0.1 github.com/CosmWasm/wasmd v0.31.0 - github.com/CosmWasm/wasmvm v1.2.3 + github.com/CosmWasm/wasmvm v1.2.4 github.com/Gravity-Bridge/Gravity-Bridge/module v1.5.3 github.com/cosmos/cosmos-proto v1.0.0-beta.3 github.com/cosmos/cosmos-sdk v0.46.12 diff --git a/go.sum b/go.sum index 80078009f1..307715a84d 100644 --- a/go.sum +++ b/go.sum @@ -228,8 +228,8 @@ github.com/BurntSushi/toml v1.3.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= -github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= -github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= +github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= +github.com/CosmWasm/wasmvm v1.2.4/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= From 193063eea47f3e531ece9fb88c6e26fb152af488 Mon Sep 17 00:00:00 2001 From: Sai Kumar <17549398+gsk967@users.noreply.github.com> Date: Wed, 7 Jun 2023 14:39:32 +0530 Subject: [PATCH 05/10] chore: disable the depguard linter temporarily (#2087) * try to fix the golanglint issues * ++ * disble depguard linter to golangci-lint * ++ * address the review comments --- .depguard.yaml | 9 +++++++++ .golangci.yml | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .depguard.yaml diff --git a/.depguard.yaml b/.depguard.yaml new file mode 100644 index 0000000000..389e0a8178 --- /dev/null +++ b/.depguard.yaml @@ -0,0 +1,9 @@ +Main: + files: + - $all + - "!$test" + allow: + - $gostd + - github.com/cosmos/** + - github.com/tendermint/** + - github.com/cosmos/cosmos-sdk \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index d532e4682c..1f542c6c9a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,7 +20,8 @@ linters: # - wsl - asciicheck - bodyclose - - depguard + # TODO; we need re-enable this linter once golangci-lint or .depguard.yaml is done + # - depguard - dogsled - errcheck - exportloopref From 841d003a6e4c66b396fc8dccc0de48df53ca3db5 Mon Sep 17 00:00:00 2001 From: Sai Kumar <17549398+gsk967@users.noreply.github.com> Date: Wed, 7 Jun 2023 15:16:55 +0530 Subject: [PATCH 06/10] tests: add qa tests to cosmwasm (#2057) * WIP: adding qa tests to cosmwasm * chore: remove duplicate gov client for tests * WIP: adding cw-plus-group contract * chore: add the flood txs to cosmwasm * fix: fix the lint * fix: fix the e2e tests * address the intitla review comments * add test flags to cw_test file * fix: fix the umee version issue * address the review comments * using codec in client.go --------- Co-authored-by: Robert Zaremba --- .gitignore | 7 +- Makefile | 3 + client/auth.go | 29 +++++ client/client.go | 3 + client/wasm.go | 19 +++ sdkclient/query/gov.go | 20 --- sdkclient/tx/client.go | 19 ++- sdkclient/tx/wasm.go | 94 ++++++++++++++ tests/artifacts/cw4_group-aarch64.wasm | Bin 0 -> 215705 bytes tests/e2e/cw_test.go | 40 ++++++ tests/e2e/e2e_setup_test.go | 19 --- tests/e2e/suite.go | 28 +++++ tests/qa/cw/config_example.yaml | 13 ++ tests/qa/cw/cw_group_types.go | 66 ++++++++++ tests/qa/cw/cw_test.go | 166 +++++++++++++++++++++++++ tests/qa/cw/cw_utils.go | 19 +++ tests/qa/cw/network_config.go | 29 +++++ tests/util/cw_util.go | 94 ++++++++++++++ 18 files changed, 625 insertions(+), 43 deletions(-) create mode 100644 client/auth.go create mode 100644 client/wasm.go delete mode 100644 sdkclient/query/gov.go create mode 100644 sdkclient/tx/wasm.go create mode 100644 tests/artifacts/cw4_group-aarch64.wasm create mode 100644 tests/e2e/cw_test.go create mode 100644 tests/e2e/suite.go create mode 100644 tests/qa/cw/config_example.yaml create mode 100644 tests/qa/cw/cw_group_types.go create mode 100644 tests/qa/cw/cw_test.go create mode 100644 tests/qa/cw/cw_utils.go create mode 100644 tests/qa/cw/network_config.go create mode 100644 tests/util/cw_util.go diff --git a/.gitignore b/.gitignore index 905a59c025..41e4cc9541 100644 --- a/.gitignore +++ b/.gitignore @@ -39,12 +39,13 @@ dist/ *.DS_Store # e2e test keychain folder -tests/e2e/keyring-test - +***/keyring-test # private files private* #IntelliJ .idea/ -.vscode \ No newline at end of file + +#VsCode +.vscode diff --git a/Makefile b/Makefile index 6e25ca6994..7eea2e8f0d 100644 --- a/Makefile +++ b/Makefile @@ -241,6 +241,9 @@ test-e2e-clean: docker stop umee0 umee1 umee2 umee-gaia-relayer gaiaval0 umee-price-feeder docker rm umee0 umee1 umee2 umee-gaia-relayer gaiaval0 umee-price-feeder +test-qa: + @go test ./tests/qa/... -timeout 30m -v -tags='test_qa' + $(MOCKS_DIR): mkdir -p $(MOCKS_DIR) mocks: $(MOCKS_DIR) diff --git a/client/auth.go b/client/auth.go new file mode 100644 index 0000000000..674bada036 --- /dev/null +++ b/client/auth.go @@ -0,0 +1,29 @@ +package client + +import ( + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (c Client) AuthQClient() authtypes.QueryClient { + return authtypes.NewQueryClient(c.Query.GrpcConn) +} + +func (c Client) QueryAuthSeq(accAddr string) (uint64, error) { + ctx, cancel := c.NewQCtx() + defer cancel() + + queryResponse, err := c.AuthQClient().Account(ctx, &authtypes.QueryAccountRequest{ + Address: accAddr, + }) + if err != nil { + return 0, err + } + + var baseAccount authtypes.AccountI + err = c.codec.UnpackAny(queryResponse.Account, &baseAccount) + if err != nil { + return 0, err + } + accSeq := baseAccount.GetSequence() + return accSeq, nil +} diff --git a/client/client.go b/client/client.go index 1cba8ba6d7..1163da9650 100644 --- a/client/client.go +++ b/client/client.go @@ -3,6 +3,7 @@ package client import ( "context" + "github.com/cosmos/cosmos-sdk/codec" sdkparams "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/umee-network/umee/v5/sdkclient" ) @@ -10,6 +11,7 @@ import ( // Client sdkclient.Client and provides umee chain specific transactions and queries. type Client struct { sdkclient.Client + codec codec.Codec } // NewClient constructs Client object. @@ -29,6 +31,7 @@ func NewClient( } return Client{ Client: c, + codec: encCfg.Codec, }, nil } diff --git a/client/wasm.go b/client/wasm.go new file mode 100644 index 0000000000..577cea7c9d --- /dev/null +++ b/client/wasm.go @@ -0,0 +1,19 @@ +package client + +import ( + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" +) + +func (c Client) WasmClient() wasmtypes.QueryClient { + return wasmtypes.NewQueryClient(c.Query.GrpcConn) +} + +func (c Client) QueryContract(contractAddr string, query []byte) (*wasmtypes.QuerySmartContractStateResponse, error) { + ctx, cancel := c.NewQCtx() + defer cancel() + + return c.WasmClient().SmartContractState(ctx, &wasmtypes.QuerySmartContractStateRequest{ + Address: contractAddr, + QueryData: query, + }) +} diff --git a/sdkclient/query/gov.go b/sdkclient/query/gov.go deleted file mode 100644 index 8880f21a6e..0000000000 --- a/sdkclient/query/gov.go +++ /dev/null @@ -1,20 +0,0 @@ -package query - -import ( - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" -) - -func (c *Client) GovClient() govtypes.QueryClient { - return govtypes.NewQueryClient(c.GrpcConn) -} - -func (c *Client) GovProposal(proposalID uint64) (*govtypes.Proposal, error) { - ctx, cancel := c.NewCtx() - defer cancel() - - queryResponse, err := c.GovClient().Proposal(ctx, &govtypes.QueryProposalRequest{ProposalId: proposalID}) - if err != nil { - return nil, err - } - return queryResponse.Proposal, nil -} diff --git a/sdkclient/tx/client.go b/sdkclient/tx/client.go index 13e0559a80..f5e976a628 100644 --- a/sdkclient/tx/client.go +++ b/sdkclient/tx/client.go @@ -114,7 +114,9 @@ func (c *Client) initTxFactory() { WithGasAdjustment(c.gasAdjustment). WithKeybase(c.ClientContext.Keyring). WithSignMode(signing.SignMode_SIGN_MODE_DIRECT). - WithSimulateAndExecute(true) + WithSimulateAndExecute(true). + WithFees("20000000uumee"). + WithGas(0) c.txFactory = &f } @@ -124,3 +126,18 @@ func (c *Client) BroadcastTx(msgs ...sdk.Msg) (*sdk.TxResponse, error) { c.ClientContext.FromAddress, _ = c.keyringRecord[0].GetAddress() return BroadcastTx(*c.ClientContext, *c.txFactory, msgs...) } + +func (c *Client) WithAccSeq(seq uint64) *Client { + c.txFactory.WithSequence(seq) + return c +} + +func (c *Client) WithAsyncBlock() *Client { + c.ClientContext.BroadcastMode = flags.BroadcastAsync + return c +} + +func (c *Client) SenderAddr() sdk.AccAddress { + addr, _ := c.keyringRecord[0].GetAddress() + return addr +} diff --git a/sdkclient/tx/wasm.go b/sdkclient/tx/wasm.go new file mode 100644 index 0000000000..bcf5828f00 --- /dev/null +++ b/sdkclient/tx/wasm.go @@ -0,0 +1,94 @@ +package tx + +import ( + "fmt" + "os" + + "github.com/CosmWasm/wasmd/x/wasm/ioutils" + "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + appparams "github.com/umee-network/umee/v5/app/params" + "github.com/umee-network/umee/v5/util/coin" +) + +func (c *Client) TxSubmitWasmContract(contractPath string) (*sdk.TxResponse, error) { + fromAddr, err := c.keyringRecord[0].GetAddress() + if err != nil { + return nil, err + } + + msg, err := readWasmCode(contractPath, fromAddr) + if err != nil { + return nil, err + } + + return c.BroadcastTx(&msg) +} + +func (c *Client) TxWasmInstantiateContract(storeCode uint64, initMsg []byte) (*sdk.TxResponse, error) { + fromAddr, err := c.keyringRecord[0].GetAddress() + if err != nil { + return nil, err + } + amount := sdk.NewCoins(sdk.NewCoin(appparams.BondDenom, sdk.NewInt(1))) + msg := types.MsgInstantiateContract{ + Sender: fromAddr.String(), + CodeID: storeCode, + Label: "label", + Funds: amount, + Msg: initMsg, + Admin: "", + } + + return c.BroadcastTx(&msg) +} + +func (c *Client) TxWasmExecuteContractByAccSeq(contractAddr string, execMsg []byte, + accSeq uint64) (*sdk.TxResponse, error) { + fromAddr, err := c.keyringRecord[0].GetAddress() + if err != nil { + return nil, err + } + amount := sdk.NewCoins(coin.Umee1) + msg := types.MsgExecuteContract{ + Sender: fromAddr.String(), + Contract: contractAddr, + Funds: amount, + Msg: execMsg, + } + if accSeq != 0 { + return c.WithAccSeq(accSeq).WithAsyncBlock().BroadcastTx(&msg) + } + return c.WithAsyncBlock().BroadcastTx(&msg) +} + +func (c *Client) TxWasmExecuteContract(contractAddr string, execMsg []byte) (*sdk.TxResponse, error) { + return c.TxWasmExecuteContractByAccSeq(contractAddr, execMsg, 0) +} + +// Prepares MsgStoreCode object from flags with gzipped wasm byte code field +func readWasmCode(file string, sender sdk.AccAddress) (types.MsgStoreCode, error) { + wasm, err := os.ReadFile(file) + if err != nil { + return types.MsgStoreCode{}, err + } + + // gzip the wasm file + if ioutils.IsWasm(wasm) { + wasm, err = ioutils.GzipIt(wasm) + + if err != nil { + return types.MsgStoreCode{}, err + } + } else if !ioutils.IsGzip(wasm) { + return types.MsgStoreCode{}, fmt.Errorf("invalid input file. Use wasm binary or gzip") + } + + msg := types.MsgStoreCode{ + Sender: sender.String(), + WASMByteCode: wasm, + InstantiatePermission: &types.AllowEverybody, + } + return msg, nil +} diff --git a/tests/artifacts/cw4_group-aarch64.wasm b/tests/artifacts/cw4_group-aarch64.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c67f563189e3ab837f8053be613c0b2093e2bcb0 GIT binary patch literal 215705 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

!{P$+prSVN_)K`^oG5@q?tGJVfl{#6SNP)rD4GQ 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%0Ao2u)D}M4fu5^~9$>Kd_hM~Ee+kAfd> zOC>1-A(i~)&O%9=1aktv=I;#)CC3@mLg^Z11H`*gne>k(lTgIpI)>CTNvcDT)}9~} zW>p8o)U�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 Vk^E+cS8$Jg1mQY_J_OuB{|B3`=Pm#M literal 0 HcmV?d00001 diff --git a/tests/e2e/cw_test.go b/tests/e2e/cw_test.go new file mode 100644 index 0000000000..16b33d4624 --- /dev/null +++ b/tests/e2e/cw_test.go @@ -0,0 +1,40 @@ +package e2e + +import "github.com/umee-network/umee/v5/tests/util" + +type TestCosmwasm struct { + IntegrationTestSuite + util.Cosmwasm +} + +/* +// TODO : needs to setup live network with dockernet +func TestCosmwasmSuite(t *testing.T) { + suite.Run(t, new(TestCosmwasm)) +} + +// TODO: re-enable this tests when we do dockernet integration +func (cw *TestCosmwasm) TestCW20() { + // TODO: needs to add contracts + accAddr, err := cw.chain.validators[0].keyInfo.GetAddress() + cw.Require().NoError(err) + cw.Sender = accAddr.String() + + // path := "" + path := "/Users/gsk967/Projects/umee-network/umee-cosmwasm/artifacts/umee_cosmwasm-aarch64.wasm" + cw.DeployWasmContract(path) + + // InstantiateContract + cw.InstantiateContract() + + // execute contract + tx := "{\"umee\":{\"leverage\":{\"supply_collateral\":{\"supplier\":\"umee19ppq83qzzy3f0fftdp2p3t5eyp44nm33we37n3\",\"asset\":{\"amount\":\"1000\",\"denom\":\"uumee\"}}}}}" + cw.CWExecute(tx) + + // query the contract + query := "{\"chain\":{\"custom\":{\"leverage_params\":{},\"assigned_query\":\"0\"}}}" + cw.CWQuery(query) + cw.Require().False(true) +} + +*/ diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index 453267e7c3..5122da1c5d 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -66,25 +66,6 @@ var ( stakeAmountCoin2 = sdk.NewCoin(appparams.BondDenom, stakeAmount2) ) -type IntegrationTestSuite struct { - suite.Suite - - tmpDirs []string - chain *chain - ethClient *ethclient.Client - gaiaRPC *rpchttp.HTTP - dkrPool *dockertest.Pool - dkrNet *dockertest.Network - ethResource *dockertest.Resource - gaiaResource *dockertest.Resource - hermesResource *dockertest.Resource - priceFeederResource *dockertest.Resource - valResources []*dockertest.Resource - orchResources []*dockertest.Resource - gravityContractAddr string - umee client.Client -} - func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } diff --git a/tests/e2e/suite.go b/tests/e2e/suite.go new file mode 100644 index 0000000000..0202e34872 --- /dev/null +++ b/tests/e2e/suite.go @@ -0,0 +1,28 @@ +package e2e + +import ( + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/suite" + rpchttp "github.com/tendermint/tendermint/rpc/client/http" + "github.com/umee-network/umee/v5/client" +) + +type IntegrationTestSuite struct { + suite.Suite + + tmpDirs []string + chain *chain + ethClient *ethclient.Client + gaiaRPC *rpchttp.HTTP + dkrPool *dockertest.Pool + dkrNet *dockertest.Network + ethResource *dockertest.Resource + gaiaResource *dockertest.Resource + hermesResource *dockertest.Resource + priceFeederResource *dockertest.Resource + valResources []*dockertest.Resource + orchResources []*dockertest.Resource + gravityContractAddr string + umee client.Client +} diff --git a/tests/qa/cw/config_example.yaml b/tests/qa/cw/config_example.yaml new file mode 100644 index 0000000000..a3633aef19 --- /dev/null +++ b/tests/qa/cw/config_example.yaml @@ -0,0 +1,13 @@ +api: "http://localhost:1317" +grpc: "localhost:9090" +rpc: "http://localhost:26657" +chain_id: "test-1" +mnemonics: + - "copper push brief egg scan entry inform record adjust fossil boss egg comic alien upon aspect dry avoid interest fury window hint race symptom" + - "maximum display century economy unlock van census kite error heart snow filter midnight usage egg venture cash kick motor survey drastic edge muffin visual" + - "banner spread envelope side kite person disagree path silver will brother under couch edit food venture squirrel civil budget number acquire point work mass" + - "veteran try aware erosion drink dance decade comic dawn museum release episode original list ability owner size tuition surface ceiling depth seminar capable only" + - "vacuum burst ordinary enact leaf rabbit gather lend left chase park action dish danger green jeans lucky dish mesh language collect acquire waste load" + - "open attitude harsh casino rent attitude midnight debris describe spare cancel crisp olive ride elite gallery leaf buffalo sheriff filter rotate path begin soldier" + - "alley afraid soup fall idea toss can goose become valve initial strong forward bright dish figure check leopard decide warfare hub unusual join cart" + - "record gift you once hip style during joke field prize dust unique length more pencil transfer quit train device arrive energy sort steak upset" diff --git a/tests/qa/cw/cw_group_types.go b/tests/qa/cw/cw_group_types.go new file mode 100644 index 0000000000..e69f1b10bf --- /dev/null +++ b/tests/qa/cw/cw_group_types.go @@ -0,0 +1,66 @@ +package cw + +import "encoding/json" + +type Member struct { + Addr string `json:"addr"` + Weight uint64 `json:"weight"` +} + +// init msg +type GroupInitMsg struct { + Admin string `json:"admin,omitempty"` + Members []Member `json:"members"` +} + +func (msg GroupInitMsg) Marshal() ([]byte, error) { + return json.Marshal(msg) +} + +// Queryies +type Admin struct{} +type AdminResp struct { + Admin string `json:"admin"` +} +type ListMembers struct { + StartAfter string `json:"start_after,omitempty"` + Limit uint64 `json:"limit,omitempty"` +} + +type ListMembersResponse struct { + Members []Member `json:"members"` +} + +type MemberResponse struct { + Weight uint64 `json:"weight"` +} + +type MemberRequest struct { + Addr string `json:"addr"` + AtHeight uint64 `json:"at_height,omitempty"` +} +type GroupQuery struct { + Admin *Admin `json:"admin,omitempty"` + Hooks *Admin `json:"hooks,omitempty"` + ListMembers *ListMembers `json:"list_members,omitempty"` + Member *MemberRequest `json:"member,omitempty"` +} + +// Transaction msgs +type GroupExecMsg struct { + UpdateAdmin *UpdateAdmin `json:"update_admin,omitempty"` + UpdateMembers *UpdateMembers `json:"update_members,omitempty"` +} + +func (msg GroupExecMsg) Marshal() ([]byte, error) { + return json.Marshal(msg) +} + +type UpdateAdmin struct { + Admin string `json:"admin,omitempty"` +} + +type UpdateMembers struct { + Remove []string `json:"remove"` + Add []Member `json:"add"` +} diff --git a/tests/qa/cw/cw_test.go b/tests/qa/cw/cw_test.go new file mode 100644 index 0000000000..3c0017e680 --- /dev/null +++ b/tests/qa/cw/cw_test.go @@ -0,0 +1,166 @@ +//go:build test_qa +// +build test_qa + +package cw + +import ( + "encoding/json" + "math/rand" + "os" + "strings" + "sync" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdkparams "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + "gotest.tools/v3/assert" + + "github.com/umee-network/umee/v5/app" + "github.com/umee-network/umee/v5/client" + cwutil "github.com/umee-network/umee/v5/tests/util" +) + +const ( + cwGroupPath = "../../artifacts/cw4_group-aarch64.wasm" +) + +var ( + SucceessRespCode = uint32(0) + TotalAccs = 1000 + TotalTxsExec = 100 + cwGroupMsgExecFunc func(name string, msg GroupExecMsg, wg *sync.WaitGroup, accSeq uint64) +) + +func TestCWPlusGroup(t *testing.T) { + accAddrs := make([]sdk.AccAddress, 0) + for i := 0; i < TotalAccs; i++ { + privateKey := secp256k1.GenPrivKey() + pubKey := privateKey.PubKey() + accAddrs = append(accAddrs, sdk.AccAddress(pubKey.Address())) + } + + // remove if old keyring exists for testing + os.RemoveAll("./keyring-test") + encConfig := app.MakeEncodingConfig() + cc, err := ReadConfig("./config_example.yaml") + assert.NilError(t, err) + // umee client + client, err := UmeeClient(cc, encConfig) + assert.NilError(t, err) + + cw := cwutil.NewCosmwasmTestSuite(t, client) + cw.DeployWasmContract(cwGroupPath) + + // sender is intital account + admin := client.Tx.SenderAddr() + // instantiate Contract + initMsg := GroupInitMsg{ + Admin: admin.String(), + Members: make([]Member, 0), + } + + initMsg.Members = append(initMsg.Members, Member{Addr: admin.String(), Weight: 1}) + for i := 0; i < TotalAccs; i++ { + initMsg.Members = append(initMsg.Members, Member{ + Addr: accAddrs[i].String(), + Weight: 1, + }) + } + + msg, err := initMsg.Marshal() + assert.NilError(t, err) + + cw.InstantiateContract(msg) + + // query the contract + cwGroupQuery := GroupQuery{ + ListMembers: &ListMembers{Limit: 30}, + } + queryMsg, err := json.Marshal(cwGroupQuery) + assert.NilError(t, err) + + queryResp := cw.CWQuery(queryMsg) + var listResp ListMembersResponse + err = json.Unmarshal([]byte(queryResp.Data), &listResp) + assert.NilError(t, err) + assert.Equal(t, 30, len(listResp.Members)) + + // doing random txs to flood the cosmwasm network + wg := &sync.WaitGroup{} + accSeq, err := client.QueryAuthSeq(admin.String()) + assert.NilError(t, err) + total := 0 + + cwGroupMsgExecFunc = func(name string, msg GroupExecMsg, wg *sync.WaitGroup, accSeq uint64) { + execMsg, err := msg.Marshal() + assert.NilError(t, err) + txResp, err := cw.CWExecuteWithSeqAndAsyncResp(execMsg, accSeq) + if err != nil && strings.Contains(err.Error(), "account sequence") { + time.Sleep(time.Second * 1) + cwGroupMsgExecFunc(name, msg, wg, accSeq) + } + if txResp == nil || (txResp != nil && txResp.Code != SucceessRespCode) { + time.Sleep(time.Second * 1) + cwGroupMsgExecFunc(name, msg, wg, accSeq) + } + if txResp != nil && txResp.Code == SucceessRespCode { + total = total + 1 + t.Log(name, " total txs successfully executed =", total) + // TODO: needs to fix panic: sync: negative WaitGroup counter + wg.Done() + } + } + + for i := 0; i < TotalTxsExec; i++ { + index := rand.Intn(1000) + updateMembers := GroupExecMsg{ + UpdateMembers: &UpdateMembers{ + Remove: []string{}, + Add: []Member{ + { + Addr: accAddrs[index].String(), + Weight: 1, + }, + }, + }, + } + accSeq = accSeq + 1 + wg.Add(1) + go func(wg *sync.WaitGroup, accSeq uint64) { + cwGroupMsgExecFunc("update_members", updateMembers, wg, accSeq) + }(wg, accSeq) + } + + // updating the admin... + updateAdmin := GroupExecMsg{ + UpdateAdmin: &UpdateAdmin{ + Admin: accAddrs[1].String(), + }, + } + + wg.Add(1) + go func(wg *sync.WaitGroup, accSeq uint64) { + cwGroupMsgExecFunc("update_admin", updateAdmin, wg, accSeq) + }(wg, accSeq+1) + + // waiting for all go routines to finish + wg.Wait() + + // query the update admin info + cwGroupQuery = GroupQuery{ + Admin: &Admin{}, + } + queryMsg, err = json.Marshal(cwGroupQuery) + assert.NilError(t, err) + queryResp = cw.CWQuery(queryMsg) + var adminQuery AdminResp + err = json.Unmarshal([]byte(queryResp.Data), &adminQuery) + assert.NilError(t, err) + assert.Equal(t, updateAdmin.UpdateAdmin.Admin, adminQuery.Admin) +} + +func UmeeClient(cc *ChainConfig, encConfig sdkparams.EncodingConfig) (client.Client, error) { + return client.NewClient(cc.ChainID, cc.RPC, cc.GRPC, cc.Mnemonics, 1.5, encConfig) +} diff --git a/tests/qa/cw/cw_utils.go b/tests/qa/cw/cw_utils.go new file mode 100644 index 0000000000..0f7908df07 --- /dev/null +++ b/tests/qa/cw/cw_utils.go @@ -0,0 +1,19 @@ +package cw + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func GetAttributeValue(resp sdk.TxResponse, eventName, attrKey string) string { + var attrVal string + for _, event := range resp.Logs[0].Events { + if event.Type == eventName { + for _, attribute := range event.Attributes { + if attribute.Key == attrKey { + attrVal = attribute.Value + } + } + } + } + return attrVal +} diff --git a/tests/qa/cw/network_config.go b/tests/qa/cw/network_config.go new file mode 100644 index 0000000000..3326789d90 --- /dev/null +++ b/tests/qa/cw/network_config.go @@ -0,0 +1,29 @@ +package cw + +import ( + "os" + + "gopkg.in/yaml.v3" +) + +type ChainConfig struct { + RPC string `yaml:"rpc"` + GRPC string `yaml:"grpc"` + API string `yaml:"api"` + ChainID string `yaml:"chain_id"` + Mnemonics []string `yaml:"mnemonics"` +} + +func ReadConfig(configFile string) (*ChainConfig, error) { + data, err := os.ReadFile(configFile) + if err != nil { + return nil, err + } + + cc := ChainConfig{} + err = yaml.Unmarshal(data, &cc) + if err != nil { + return nil, err + } + return &cc, nil +} diff --git a/tests/util/cw_util.go b/tests/util/cw_util.go new file mode 100644 index 0000000000..15f9511163 --- /dev/null +++ b/tests/util/cw_util.go @@ -0,0 +1,94 @@ +package util + +import ( + "encoding/json" + "strconv" + "testing" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "gotest.tools/v3/assert" + + "github.com/umee-network/umee/v5/client" +) + +const ( + SucceessRespCode = uint32(0) +) + +type Cosmwasm struct { + StoreCode uint64 + ContractAddr string + Sender string + T *testing.T + umee client.Client +} + +func NewCosmwasmTestSuite(t *testing.T, umee client.Client) *Cosmwasm { + return &Cosmwasm{ + T: t, + umee: umee, + } +} + +func (cw *Cosmwasm) DeployWasmContract(path string) { + cw.T.Logf("ℹ️ deploying smart contract %s", path) + resp, err := cw.umee.Tx.TxSubmitWasmContract(path) + assert.NilError(cw.T, err) + storeCode := cw.GetAttributeValue(*resp, "store_code", "code_id") + cw.StoreCode, err = strconv.ParseUint(storeCode, 10, 64) + assert.NilError(cw.T, err) + cw.T.Logf("✅ smart contract is deployed and store code is %d", cw.StoreCode) +} + +func (cw *Cosmwasm) MarshalAny(any interface{}) []byte { + data, err := json.Marshal(any) + assert.NilError(cw.T, err) + return data +} + +func (cw *Cosmwasm) InstantiateContract(initMsg []byte) { + cw.T.Log("ℹ️ smart contract is instantiating...") + resp, err := cw.umee.Tx.TxWasmInstantiateContract(cw.StoreCode, initMsg) + assert.NilError(cw.T, err) + cw.ContractAddr = cw.GetAttributeValue(*resp, "instantiate", "_contract_address") + assert.Equal(cw.T, SucceessRespCode, resp.Code) + cw.T.Log("✅ smart contract is instantiating is done.") + cw.T.Logf("smart contract address is %s", cw.ContractAddr) +} + +func (cw *Cosmwasm) CWQuery(query []byte) wasmtypes.QuerySmartContractStateResponse { + resp, err := cw.umee.QueryContract(cw.ContractAddr, query) + assert.NilError(cw.T, err) + return *resp +} + +func (cw *Cosmwasm) CWExecute(execMsg []byte) { + resp, err := cw.umee.Tx.TxWasmExecuteContract(cw.ContractAddr, execMsg) + assert.NilError(cw.T, err) + assert.Equal(cw.T, SucceessRespCode, resp.Code) +} + +func (cw *Cosmwasm) CWExecuteWithSeqAndAsync(execMsg []byte, accSeq uint64) { + resp, err := cw.umee.Tx.TxWasmExecuteContractByAccSeq(cw.ContractAddr, execMsg, accSeq) + assert.NilError(cw.T, err) + assert.Equal(cw.T, SucceessRespCode, resp.Code) +} + +func (cw *Cosmwasm) CWExecuteWithSeqAndAsyncResp(execMsg []byte, accSeq uint64) (*sdk.TxResponse, error) { + return cw.umee.Tx.TxWasmExecuteContractByAccSeq(cw.ContractAddr, execMsg, accSeq) +} + +func (cw *Cosmwasm) GetAttributeValue(resp sdk.TxResponse, eventName, attrKey string) string { + var attrVal string + for _, event := range resp.Logs[0].Events { + if event.Type == eventName { + for _, attribute := range event.Attributes { + if attribute.Key == attrKey { + attrVal = attribute.Value + } + } + } + } + return attrVal +} From 6a0c48f9b7f36889c06fb4cd9c881566ce8d64a3 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Wed, 7 Jun 2023 12:18:28 +0200 Subject: [PATCH 07/10] chore: v5 final release notes (#2077) * chore: v5 final release notes * release notes update --- CHANGELOG.md | 14 +++++++++++++- RELEASE_NOTES.md | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e50534805b..3e29880fa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,8 +50,20 @@ Ref: https://keepachangelog.com/en/1.0.0/ - [1952](https://github.com/umee-network/umee/pull/1952) Add `x/incentive` module. - [2015](https://github.com/umee-network/umee/pull/2015), [2050](https://github.com/umee-network/umee/pull/2050) Add `x/ugov` module. +- [2078](https://github.com/umee-network/umee/pull/2078) Upgrade `ibc-go` to v6.2. -## [v5.0.0](https://github.com/umee-network/umee/releases/tag/v5.0.0-rc1) - 2023-05-31 +### Improvements + +- [2057](https://github.com/umee-network/umee/pull/2057) Cosmwasm QA tests. + +## [v5.0.0](https://github.com/umee-network/umee/releases/tag/v5.0.0) - 2023-06-07 + +### Improvements + +- [2076](https://github.com/umee-network/umee/pull/2076) Cosmwasm: registering `cosmwasm_1_2` capability. +- [2083](https://github.com/umee-network/umee/pull/2083) Update `wasmvm` to 1.2.4. + +## [v5.0.0-rc1](https://github.com/umee-network/umee/releases/tag/v5.0.0-rc1) - 2023-05-31 ### Features diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 8879b71761..55de887850 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -10,18 +10,28 @@ Release Procedure is defined in the [CONTRIBUTING](CONTRIBUTING.md#release-proce Highlights: -- Cosmwasm integration. +- Cosmwasm integration (v0.31). - Gravity Bridge phase-3: shutdown of the transfers. In this release we introduce valset burn mechanism, which will block the Ethereum smart contract for processing any further transactions, as well as sending transfers back to Ethereum. This follows the plan approved through in the [prop-67](https://www.mintscan.io/umee/proposals/67). NOTE: All validators must continue to use Peggo to not get slashed. - Updated to the latest Cosmos SDK v0.46.12 +- New generic functions for storage management: `util/store`. -See [CHANGELOG](https://github.com/umee-network/umee/blob/v5.0.0-rc1/CHANGELOG.md) +See [CHANGELOG](https://github.com/umee-network/umee/blob/v5.0.0/CHANGELOG.md). ### Validators +#### libwasmvm update + +Our dependencies have been updated. Now the binary requires `libwasmvm v1.2.4`. When you build the binary from source on the server machine you probably don't need any change. However when you download a binary from GitHub, or from other source, make sure you update the `/usr/lib/libwasmvm..so`. For example: + +- copy from `$GOPATH/pkg/mod/github.com/!cosm!wasm/wasmvm@v1.2.4/internal/api/libwasmvm.$(uname -m).so` +- or download from github `wget https://raw.githubusercontent.com/CosmWasm/wasmvm/v1.2.4/internal/api/libwasmvm.$(uname -m).so -O /lib/libwasmvm.$(uname -m).so` + +You don't need to do anything if you are using our Docker image. + #### Min Gas Prices Since v4.2 release we request all validators set a `minimum-gas-prices` setting (in app `config/app.toml` file, general settings). We recommend `0.1uumee` which is equal the current Keplr _average_ setting: From fcf924cdaef106910ba4ad5a0faf91a99e295bcc Mon Sep 17 00:00:00 2001 From: Adam Moser <63419657+toteki@users.noreply.github.com> Date: Thu, 8 Jun 2023 08:49:55 -0600 Subject: [PATCH 08/10] fix: MsgSupplyCollateral and MinCollateralLiquidity (#2089) * fix: MsgSupplyCollateral and MinCollateralLiquidity * changelog --- CHANGELOG.md | 4 ++++ x/leverage/keeper/msg_server.go | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e29880fa2..5c9731b663 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ - [2076](https://github.com/umee-network/umee/pull/2076) Cosmwasm: registering `cosmwasm_1_2` capability. - [2083](https://github.com/umee-network/umee/pull/2083) Update `wasmvm` to 1.2.4. +### Fixes + +- [2089](https://github.com/umee-network/umee/pull/2089) MsgSupplyCollateral no longer fails when market is below MinCollateralLiquidity. + ## [v5.0.0-rc1](https://github.com/umee-network/umee/releases/tag/v5.0.0-rc1) - 2023-05-31 ### Features diff --git a/x/leverage/keeper/msg_server.go b/x/leverage/keeper/msg_server.go index 99127443d9..a898a9cac4 100644 --- a/x/leverage/keeper/msg_server.go +++ b/x/leverage/keeper/msg_server.go @@ -241,11 +241,6 @@ func (s msgServer) SupplyCollateral( return nil, err } - // Fail here if collateral liquidity restrictions are violated - if err := s.keeper.checkCollateralLiquidity(ctx, msg.Asset.Denom); err != nil { - return nil, err - } - // Fail here if collateral share restrictions are violated, // based on only collateral with known oracle prices if err := s.keeper.checkCollateralShare(ctx, uToken.Denom); err != nil { From a6edc64c3fb3f8db90ff64f1b4978642268f756f Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 8 Jun 2023 19:06:21 +0200 Subject: [PATCH 09/10] chore: barberry patch (#2091) * chore: barberry patch * update goleveldb --- CHANGELOG.md | 4 ++++ go.mod | 16 ++++++++-------- go.sum | 30 ++++++++++++++---------------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c9731b663..ba48c6f9d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,6 +94,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ - [2052](https://github.com/umee-network/umee/pull/2052) Allow liquidation threshold == collateral weight in token validation. - [2072](https://github.com/umee-network/umee/pull/2072) Fix an int64 overflow when computing module liquidity for high-exponent assets. +## [v4.4.2](https://github.com/umee-network/umee/releases/tag/v4.4.2) - 2023-06-08 + +- [2090](https://github.com/umee-network/umee/pull/2090) Bump Cosmos SDK to v0.46.13 and CometBFT to v0.34.28 and IAVL to v0.19.6. + ## [v4.4.1](https://github.com/umee-network/umee/releases/tag/v4.4.1) - 2023-05-25 ### Improvements diff --git a/go.mod b/go.mod index 262ce76047..e8af8a5f43 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/CosmWasm/wasmvm v1.2.4 github.com/Gravity-Bridge/Gravity-Bridge/module v1.5.3 github.com/cosmos/cosmos-proto v1.0.0-beta.3 - github.com/cosmos/cosmos-sdk v0.46.12 + github.com/cosmos/cosmos-sdk v0.46.13 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ibc-go/v6 v6.2.0 github.com/ethereum/go-ethereum v1.12.0 @@ -97,7 +97,7 @@ require ( github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/gogoproto v1.4.8 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.5 // indirect + github.com/cosmos/iavl v0.19.6 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect @@ -105,7 +105,7 @@ require ( github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect @@ -201,7 +201,7 @@ require ( github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/klauspost/compress v1.15.15 // indirect + github.com/klauspost/compress v1.16.0 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.7 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -236,12 +236,11 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.12.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo v1.16.4 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polyfloyd/go-errorlint v1.4.2 // indirect @@ -279,7 +278,7 @@ require ( github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect @@ -341,10 +340,11 @@ require ( replace ( github.com/CosmWasm/wasmd => github.com/notional-labs/wasmd v0.31.0-umee.46 github.com/Gravity-Bridge/Gravity-Bridge/module => github.com/umee-network/Gravity-Bridge/module v1.5.3-umee-8 - github.com/cosmos/cosmos-sdk => github.com/umee-network/cosmos-sdk v0.46.12-umee + github.com/cosmos/cosmos-sdk => github.com/umee-network/cosmos-sdk v0.46.13-umee // dgrijalva/jwt-go is deprecated and doesn't receive security updates. github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/osmosis-labs/bech32-ibc => github.com/umee-network/bech32-ibc v0.3.3 + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.28 ) diff --git a/go.sum b/go.sum index 307715a84d..3408eef058 100644 --- a/go.sum +++ b/go.sum @@ -353,6 +353,7 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bufbuild/protocompile v0.1.0 h1:HjgJBI85hY/qmW5tw/66sNDZ7z0UDdVSi/5r40WHw4s= github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= @@ -445,8 +446,8 @@ github.com/cosmos/gogoproto v1.4.8 h1:BrHKc6WFZt8+jRV71vKSQE+JrfF+JAnzrKo2VP7wIZ github.com/cosmos/gogoproto v1.4.8/go.mod h1:hnb0DIEWTv+wdNzNcqus5xCQXq5+CXauq1FJuurRfVY= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= -github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/iavl v0.19.6 h1:XY78yEeNPrEYyNCKlqr9chrwoeSDJ0bV2VjocTk//OU= +github.com/cosmos/iavl v0.19.6/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ibc-go/v6 v6.2.0 h1:HKS5WNxQrlmjowHb73J9LqlNJfvTnvkbhXZ9QzNTU7Q= github.com/cosmos/ibc-go/v6 v6.2.0/go.mod h1:+S3sxcNwOhgraYDJAhIFDg5ipXHaUnJrg7tOQqGyWlc= github.com/cosmos/interchain-accounts v0.4.3 h1:WedxEa/Hj/2GY7AF6CafkEPJ/Z9rhl3rT1mRwNHsdts= @@ -481,8 +482,9 @@ github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6 github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= @@ -628,7 +630,6 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= @@ -948,7 +949,7 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= @@ -995,8 +996,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= @@ -1160,9 +1161,8 @@ github.com/notional-labs/wasmd v0.31.0-umee.46 h1:wsEWfXhsTw39gtIhLdMNRKVe023LZz github.com/notional-labs/wasmd v0.31.0-umee.46/go.mod h1:S5TjKrcwxj/h4cnAiX4z2yxYox0JgUzzADo28W52uK8= github.com/nunnatsa/ginkgolinter v0.12.0 h1:seZo112n+lt0gdLJ/Jh70mzvrqbABWFpXd1bZTLTByM= github.com/nunnatsa/ginkgolinter v0.12.0/go.mod h1:dJIGXYXbkBswqa/pIzG0QlVTTDSBMxDoCFwhsl4Uras= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -1172,9 +1172,8 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1220,8 +1219,9 @@ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNc github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= +github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= @@ -1484,8 +1484,8 @@ github.com/umee-network/Gravity-Bridge/module v1.5.3-umee-8 h1:wTu1bGrlgGtBKoWT4 github.com/umee-network/Gravity-Bridge/module v1.5.3-umee-8/go.mod h1:NR6UwQPZUoLckpOtCxgROWNEDzepe2JhxQ2u9cL+pbo= github.com/umee-network/bech32-ibc v0.3.3 h1:wUX5uSYZl8yiFdttOvunfRihsE4miYmzl7pK2FEUs+U= github.com/umee-network/bech32-ibc v0.3.3/go.mod h1:UbhzCKN+Z7RoUdCkAanmIy+wufwQ/aQJrDEoVORhC2Y= -github.com/umee-network/cosmos-sdk v0.46.12-umee h1:s8/vB6M5psGNBFfwakV2z6oWFkZ377DDlh0TZfwRqbM= -github.com/umee-network/cosmos-sdk v0.46.12-umee/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM= +github.com/umee-network/cosmos-sdk v0.46.13-umee h1:EeSalZHGoWdkKkCNhNd80jzRMNEQWLyDPUU5aUJQpIs= +github.com/umee-network/cosmos-sdk v0.46.13-umee/go.mod h1:EfY521ATNEla8eJ6oJuZBdgP5+p360s7InnRqX+TWdM= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -1832,7 +1832,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1991,7 +1990,6 @@ golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= From 97ebd71da3dd23112390fc8bfe7ab294afc3c2b9 Mon Sep 17 00:00:00 2001 From: Sai Kumar <17549398+gsk967@users.noreply.github.com> Date: Fri, 9 Jun 2023 18:29:43 +0530 Subject: [PATCH 10/10] chore: updating the swagger docs (#2055) * WIP: adding cosmos,ibc swagger docs * chore: remove cosmos and ibc-go swagger * chore: add update-swagger docs as per release * chore: removed statik and swagger-ui data * move statik import to tools * chore: updating release workflow and swagger docs section in readme * chore: add update swagger docs to docker build action * fix: fix the lint issue * fix: fix the markdown lint --- .github/workflows/release-umee-docker.yml | 5 + .github/workflows/release-umee.yml | 5 + .gitignore | 7 +- Makefile | 5 + README.md | 24 +- contrib/scripts/protoc-swagger-gen.sh | 4 +- contrib/scripts/protoc-update-swagger-docs.sh | 55 + swagger/proto-config-gen.json | 26 +- swagger/statik/init.go | 1 + swagger/swagger.go | 18 +- swagger/swagger.yaml | 3252 ++++++++++++++--- tools/tools.go | 3 + 12 files changed, 2868 insertions(+), 537 deletions(-) create mode 100644 contrib/scripts/protoc-update-swagger-docs.sh create mode 100644 swagger/statik/init.go diff --git a/.github/workflows/release-umee-docker.yml b/.github/workflows/release-umee-docker.yml index d86ed84951..bd2275015d 100644 --- a/.github/workflows/release-umee-docker.yml +++ b/.github/workflows/release-umee-docker.yml @@ -46,6 +46,11 @@ jobs: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate swagger docs + run: | + make proto-swagger-gen + make proto-update-swagger-docs - name: Build and push uses: docker/build-push-action@v4 diff --git a/.github/workflows/release-umee.yml b/.github/workflows/release-umee.yml index 5ef76af362..591964ffb6 100644 --- a/.github/workflows/release-umee.yml +++ b/.github/workflows/release-umee.yml @@ -29,6 +29,11 @@ jobs: run: echo "TM_VERSION=$(go list -m github.com/tendermint/tendermint | sed 's:.* ::')" >> $GITHUB_ENV # useful to test builds. However will require to add "push" rule to the "on" section + - name: generate and update swagger docs + run: | + make proto-swagger-gen + make proto-update-swagger-docs + - name: goreleaser test-build uses: goreleaser/goreleaser-action@v4 if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'Enable:ReleaseBuild') diff --git a/.gitignore b/.gitignore index 41e4cc9541..e4ee17afb9 100644 --- a/.gitignore +++ b/.gitignore @@ -47,5 +47,10 @@ private* #IntelliJ .idea/ -#VsCode +#Vscode .vscode + +# Swagger UI +swagger/statik/statik.go +swagger/swagger-ui + diff --git a/Makefile b/Makefile index 7eea2e8f0d..cb80315b8a 100644 --- a/Makefile +++ b/Makefile @@ -359,3 +359,8 @@ proto-lint: proto-check-breaking: @echo "Checking for breaking changes" @$(DOCKER_BUF) breaking --against $(HTTPS_GIT)#branch=main + +proto-update-swagger-docs: + @echo "Updating Protobuf Swagger Docs" + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGenSwagger}$$"; then docker start -a $(containerProtoGenSwagger); else docker run --name $(containerProtoGenSwagger) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ + sh ./contrib/scripts/protoc-update-swagger-docs.sh; fi \ No newline at end of file diff --git a/README.md b/README.md index 5e2e5da1b6..c9414119a3 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,11 @@ Umee will allow a multitude of decentralized debt products. - [Table of Contents](#table-of-contents) - [Releases](#releases) - [Release Compatibility Matrix](#release-compatibility-matrix) -- [Active Networks](#active-networks) + - [Price Feeder](#price-feeder) + - [libwasmvm](#libwasmvm) + - [Active Networks](#active-networks) - [Build](#build) + - [Recommended Database Backend](#recommended-database-backend) - [Swagger](#swagger) - [Cosmovisor](#cosmovisor) - [Liquidators](#liquidators) @@ -107,6 +110,25 @@ db_backend = "rocksdb" ### Swagger +- To update the latest swagger docs, follow these steps + +Generate the latest swagger: + + ```bash + $ make proto-swagger-gen + $ make proto-update-swagger-docs + ``` + +Build the new binary or install the new binary with the latest swagger docs: + + ```bash + $ make build + # or + $ make install + ``` + +Make sure to execute these commands whenever you want to update the swagger documentation. + - To enable it, modify the node config at `$UMEE_HOME/config/app.toml` to `api.swagger` `true` - Run the node normally `umeed start` - Enter the swagger docs `http://localhost:1317/swagger/` diff --git a/contrib/scripts/protoc-swagger-gen.sh b/contrib/scripts/protoc-swagger-gen.sh index 0d23ccdc6a..dae416773d 100755 --- a/contrib/scripts/protoc-swagger-gen.sh +++ b/contrib/scripts/protoc-swagger-gen.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash - set -eo pipefail -if ! [ -x "$(command -v swagger-combine )" ]; then +if ! [ -x "$(command -v swagger-combine)" ]; then echo 'Error: swagger-combine is not installed. Install with $~ npm i -g swagger-combine' >&2 exit 1 fi @@ -19,6 +18,7 @@ for dir in $proto_dirs; do done cd .. + # combine swagger files # uses nodejs package `swagger-combine`. # all the individual swagger files need to be configured in `config.json` for merging diff --git a/contrib/scripts/protoc-update-swagger-docs.sh b/contrib/scripts/protoc-update-swagger-docs.sh new file mode 100644 index 0000000000..a2e60ce704 --- /dev/null +++ b/contrib/scripts/protoc-update-swagger-docs.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -eo pipefail + +SWAGGER_DIR=./swagger +SWAGGER_UI_DIR=${SWAGGER_DIR}/swagger-ui + +# TODO: needs to fix merge issue of cosmos swagger and ibc-go swagger +# SDK_VERSION=$(go list -m -f '{{ .Version }}' github.com/cosmos/cosmos-sdk) +# IBC_VERSION=$(go list -m -f '{{ .Version }}' github.com/cosmos/ibc-go/v6) + +# SDK_RAW_URL=https://raw.githubusercontent.com/cosmos/cosmos-sdk/${SDK_VERSION}/client/docs/swagger-ui/swagger.yaml +# IBC_RAW_URL=https://raw.githubusercontent.com/cosmos/ibc-go/${IBC_VERSION}/docs/client/swagger-ui/swagger.yaml + +# # download Cosmos SDK swagger yaml file +# echo "SDK version ${SDK_VERSION}" +# wget "${SDK_RAW_URL}" -O ./tmp-swagger-gen/cosmos-sdk-swagger.yaml + +# # download IBC swagger yaml file +# echo "IBC version ${IBC_VERSION}" +# wget "${IBC_RAW_URL}" -O ./tmp-swagger-gen/ibc-go-swagger.yaml + +SWAGGER_UI_VERSION=4.18.3 +SWAGGER_UI_DOWNLOAD_URL=https://github.com/swagger-api/swagger-ui/archive/refs/tags/v${SWAGGER_UI_VERSION}.zip +SWAGGER_UI_PACKAGE_NAME=${SWAGGER_DIR}/swagger-ui-${SWAGGER_UI_VERSION} + +# if swagger-ui does not exist locally, download swagger-ui and move dist directory to +# swagger-ui directory, then remove zip file and unzipped swagger-ui directory +if [ ! -d ${SWAGGER_UI_DIR} ]; then + # download swagger-ui + wget ${SWAGGER_UI_DOWNLOAD_URL} -O ${SWAGGER_UI_PACKAGE_NAME}.zip + # unzip swagger-ui package + unzip ${SWAGGER_UI_PACKAGE_NAME}.zip -d ${SWAGGER_DIR} + # move swagger-ui dist directory to swagger-ui directory + mv ${SWAGGER_UI_PACKAGE_NAME}/dist ${SWAGGER_UI_DIR} + # remove swagger-ui zip file and unzipped swagger-ui directory + rm -rf ${SWAGGER_UI_PACKAGE_NAME}.zip ${SWAGGER_UI_PACKAGE_NAME} + # replacing default swagger with our generated swagger yaml file + sed -i 's+https://petstore.swagger.io/v2/swagger.json+./swagger.yaml+g' ${SWAGGER_DIR}/swagger-ui/swagger-initializer.js +fi + +# move generated swagger yaml file to swagger-ui directory +cp ${SWAGGER_DIR}/swagger.yaml ${SWAGGER_DIR}/swagger-ui/ + +# install statik if not present +go install github.com/rakyll/statik + +# generate statik golang code using updated swagger-ui directory +statik -src=${SWAGGER_DIR}/swagger-ui -dest=${SWAGGER_DIR} -f -m + +# log whether or not the swagger directory was updated +if [ -n "$(git status ${SWAGGER_DIR} --porcelain)" ]; then + echo "Swagger is updated" +else + echo "Swagger in sync" +fi \ No newline at end of file diff --git a/swagger/proto-config-gen.json b/swagger/proto-config-gen.json index f3bfaee077..a658f766ef 100644 --- a/swagger/proto-config-gen.json +++ b/swagger/proto-config-gen.json @@ -21,6 +21,30 @@ "Params": "OracleParams" } } + }, + { + "url": "./tmp-swagger-gen/umee/uibc/v1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "UIBCParams" + } + } + }, + { + "url": "./tmp-swagger-gen/umee/ugov/v1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "UGovParams" + } + } + }, + { + "url": "./tmp-swagger-gen/umee/incentive/v1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "IncentiveParams" + } + } } ] -} +} \ No newline at end of file diff --git a/swagger/statik/init.go b/swagger/statik/init.go new file mode 100644 index 0000000000..defdb7673f --- /dev/null +++ b/swagger/statik/init.go @@ -0,0 +1 @@ +package statik diff --git a/swagger/swagger.go b/swagger/swagger.go index fdfc801c31..604c8bc2e6 100644 --- a/swagger/swagger.go +++ b/swagger/swagger.go @@ -1,18 +1,22 @@ package swagger import ( - "embed" "net/http" "github.com/gorilla/mux" - "github.com/ignite/cli/ignite/pkg/openapiconsole" -) + "github.com/rakyll/statik/fs" -//go:embed swagger.yaml -var Docs embed.FS + // unnamed import of statik for swagger UI support + _ "github.com/umee-network/umee/v5/swagger/statik" +) // RegisterSwaggerAPI registers swagger route with API Server func RegisterSwaggerAPI(rtr *mux.Router) { - rtr.Handle("/swagger.yaml", http.FileServer(http.FS(Docs))) - rtr.HandleFunc("/swagger/", openapiconsole.Handler("umee", "/swagger.yaml")) + statikFS, err := fs.New() + if err != nil { + panic(err) + } + + staticServer := http.FileServer(statikFS) + rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer)) } diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index 19d2c72598..8d9e322d50 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -1905,6 +1905,1333 @@ paths: type: string tags: - Query + /umee/uibc/v1/all-outflows: + get: + summary: AllOutflow returns outflows for each denom in the current quota period. + operationId: AllOutflows + responses: + '200': + description: A successful response. + schema: + type: object + properties: + outflows: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + DecCoin defines a token with a denomination and a decimal + amount. + + + NOTE: The amount field is an Dec which implements the custom + method + + signatures required by gogoproto. + title: QueryOutflowResponse defines response type of Query/Outflow + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/uibc/v1/outflows: + get: + summary: |- + Outflow returns IBC denom outflows in the current quota period. + If denom is not specified, returns sum of all registered outflows. + operationId: Outflows + responses: + '200': + description: A successful response. + schema: + type: object + properties: + amount: + type: string + title: QueryOutflowResponse defines response type of Query/Outflow + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: denom + in: query + required: false + type: string + tags: + - Query + /umee/uibc/v1/params: + get: + summary: Params queries the parameters of the x/uibc module. + operationId: UIBCParams + responses: + '200': + description: A successful response. + schema: + type: object + properties: + params: + type: object + properties: + ibc_status: + description: >- + ibc_status defines the IBC ICS20 status (transfer quota or + transfers disabled). + type: string + enum: + - IBC_TRANSFER_STATUS_UNSPECIFIED + - IBC_TRANSFER_STATUS_QUOTA_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_ENABLED + - IBC_TRANSFER_STATUS_QUOTA_OUT_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_IN_DISABLED + - IBC_TRANSFER_STATUS_TRANSFERS_PAUSED + default: IBC_TRANSFER_STATUS_UNSPECIFIED + title: >- + IBCTransferStatus status of ibc-transfer quota check for + inflow and outflow + total_quota: + type: string + title: >- + total_quota defines the total outflow limit of + ibc-transfer in USD + token_quota: + type: string + title: token_quota defines the outflow limit per token in USD + quota_duration: + type: string + title: >- + quota_duration defines quota expires for each ibc-transfer + denom in seconds + title: Params of x/uibc module + description: >- + QueryParamsResponse defines the response structure for the Params + gRPC + + service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/ugov/v1/min-gas-price: + get: + summary: MinGasPrice returns minimum transaction fees. + operationId: MinGasPrice + responses: + '200': + description: A successful response. + schema: + type: object + properties: + min_gas_price: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + DecCoin defines a token with a denomination and a decimal + amount. + + + NOTE: The amount field is an Dec which implements the custom + method + + signatures required by gogoproto. + description: QueryMinGasPriceResponse response type. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/incentive/v1/account_bonds/{address}: + get: + summary: >- + AccountBonds queries all bonded collateral and unbondings associated + with an account. + operationId: AccountBonds + responses: + '200': + description: A successful response. + schema: + type: object + properties: + bonded: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + unbonding: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + unbondings: + type: array + items: + type: object + properties: + start: + type: string + format: int64 + end: + type: string + format: int64 + uToken: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + description: >- + Unbonding is a structure that tracks an in-progress token + unbonding. + + It tracks both its start time and end time, so that if the + module's + + unbonding time changes, the unbonding can complete at the + earlier of + + its original end time or its new one based on the new + parameter. + description: >- + QueryAccountBondsResponse defines the response structure for the + AccountBonds gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: address + in: path + required: true + type: string + tags: + - Query + /umee/incentive/v1/actual_rates: + get: + summary: >- + ActualRates queries the hypothetical return of a bonded uToken + denomination + + if current incentive rewards continued for one year. The response is an + sdk.Dec + + representing an oracle-adjusted APY. + operationId: ActualRates + responses: + '200': + description: A successful response. + schema: + type: object + properties: + APY: + type: string + description: APY is the oracle price-adjusted APY of the bonded uToken. + description: >- + QueryActualRatesResponse defines the response structure for the + ActualRates gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: uToken + description: >- + uToken is the uToken denomination whose current annual rate of + rewards is being queried. + in: query + required: false + type: string + tags: + - Query + /umee/incentive/v1/current_rates: + get: + summary: >- + CurrentRates queries the hypothetical return of a bonded uToken + denomination + + if current incentive rewards continued for one year. The response is an + sdk.Coins + + of base token rewards, per reference amount (usually 10^exponent of the + uToken.) + operationId: CurrentRates + responses: + '200': + description: A successful response. + schema: + type: object + properties: + reference_bond: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + rewards: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + Rewards are the amount of base token rewards that the + reference amount of bonded uTokens would earn + + if current rates continued for a full year. + description: >- + QueryCurrentRatesResponse defines the response structure for the + CurrentRates gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: uToken + description: >- + uToken is the uToken denomination whose current annual rate of + rewards is being queried. + in: query + required: false + type: string + tags: + - Query + /umee/incentive/v1/last_reward_time: + get: + summary: >- + LastRewardTime queries the last block time at which incentive rewards + were calculated. + operationId: LastRewardTime + responses: + '200': + description: A successful response. + schema: + type: object + properties: + time: + type: string + format: int64 + description: >- + QueryLastRewardTimeResponse defines the response structure for the + LastRewardTime gRPC + + service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/incentive/v1/params: + get: + summary: Params queries the parameters of the x/incentive module. + operationId: IncentiveParams + responses: + '200': + description: A successful response. + schema: + type: object + properties: + params: + type: object + properties: + max_unbondings: + type: integer + format: int64 + description: >- + max_unbondings is the maximum amount of concurrent + unbondings an address can have + + of each bonded uToken denom. Zero is interpreted as no + limit. + unbonding_duration: + type: string + format: int64 + description: unbonding_duration is the unbonding duration (in seconds). + emergency_unbond_fee: + type: string + description: >- + emergency_unbond_fee is the portion of a bond that is paid + when it is instantly + + released using MsgEmergencyUnbond. For example, 0.01 is a + 1% fee. Ranges 0-1. + description: Params defines the parameters for the incentive module. + description: >- + QueryParamsResponse defines the response structure for the Params + gRPC + + service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/incentive/v1/pending_rewards/{address}: + get: + summary: >- + PendingRewards queries unclaimed incentive rewards associated with an + account. + operationId: PendingRewards + responses: + '200': + description: A successful response. + schema: + type: object + properties: + rewards: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + QueryPendingRewardsResponse defines the response structure for the + PendingRewards gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: address + in: path + required: true + type: string + tags: + - Query + /umee/incentive/v1/program/{id}: + get: + summary: IncentiveProgram queries a single incentive program by ID. + operationId: IncentiveProgram + responses: + '200': + description: A successful response. + schema: + type: object + properties: + program: + type: object + properties: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it has + been created. + + It is zero when the program is being proposed by + governance, and is set + + to its final value when the proposal passes. + start_time: + type: string + format: int64 + description: >- + start_time is the unix time (in seconds) at which the + incentives begin. + + If a program is passed after its intended start time, its + start time + + will be increased to the current time, with program + duration unchanged. + duration: + type: string + format: int64 + description: >- + duration is the length of the incentive program from start + time to + + completion in seconds. + uToken: + type: string + description: >- + uToken is the incentivized uToken collateral denom. + Suppliers who collateralize + + this asset then bond it to the incentive module are + eligible for this program's + + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This + can happen when + + a program passes if funding from community fund, or any + time before the + + program's start time if funding with MsgSponsor. A program + that reaches + + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive program + on a single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryIncentivePrograResponse defines the response structure for + the + + IncentiveProgram gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: id + description: ID specifies which program to query for + in: path + required: true + type: integer + format: int64 + tags: + - Query + /umee/incentive/v1/programs/completed: + get: + summary: >- + CompletedIncentivePrograms queries for all incentives programs that have + been passed + + by governance, and either run to completion or expired immediately due + to not being funded. + operationId: CompletedIncentivePrograms + responses: + '200': + description: A successful response. + schema: + type: object + properties: + programs: + type: array + items: + type: object + properties: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it + has been created. + + It is zero when the program is being proposed by + governance, and is set + + to its final value when the proposal passes. + start_time: + type: string + format: int64 + description: >- + start_time is the unix time (in seconds) at which the + incentives begin. + + If a program is passed after its intended start time, + its start time + + will be increased to the current time, with program + duration unchanged. + duration: + type: string + format: int64 + description: >- + duration is the length of the incentive program from + start time to + + completion in seconds. + uToken: + type: string + description: >- + uToken is the incentivized uToken collateral denom. + Suppliers who collateralize + + this asset then bond it to the incentive module are + eligible for this program's + + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This + can happen when + + a program passes if funding from community fund, or any + time before the + + program's start time if funding with MsgSponsor. A + program that reaches + + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive + program on a single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryCompletedIncentiveProgramsResponse defines the response + structure for the + + CompletedIncentivePrograms gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/incentive/v1/programs/ongoing: + get: + summary: >- + OngoingIncentivePrograms queries for all incentives programs that have + been passed + + by governance, funded, and started but not yet completed. + operationId: OngoingIncentivePrograms + responses: + '200': + description: A successful response. + schema: + type: object + properties: + programs: + type: array + items: + type: object + properties: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it + has been created. + + It is zero when the program is being proposed by + governance, and is set + + to its final value when the proposal passes. + start_time: + type: string + format: int64 + description: >- + start_time is the unix time (in seconds) at which the + incentives begin. + + If a program is passed after its intended start time, + its start time + + will be increased to the current time, with program + duration unchanged. + duration: + type: string + format: int64 + description: >- + duration is the length of the incentive program from + start time to + + completion in seconds. + uToken: + type: string + description: >- + uToken is the incentivized uToken collateral denom. + Suppliers who collateralize + + this asset then bond it to the incentive module are + eligible for this program's + + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This + can happen when + + a program passes if funding from community fund, or any + time before the + + program's start time if funding with MsgSponsor. A + program that reaches + + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive + program on a single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryOngoingIncentiveProgramsResponse defines the response + structure for the + + OngoingIncentivePrograms and UpcomingIncentivePrograms gRPC + service handlers. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/incentive/v1/programs/upcoming: + get: + summary: >- + UpcomingIncentivePrograms queries for all incentives programs that have + been passed + + by governance, but not yet started. They may or may not have been + funded. + operationId: UpcomingIncentivePrograms + responses: + '200': + description: A successful response. + schema: + type: object + properties: + programs: + type: array + items: + type: object + properties: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it + has been created. + + It is zero when the program is being proposed by + governance, and is set + + to its final value when the proposal passes. + start_time: + type: string + format: int64 + description: >- + start_time is the unix time (in seconds) at which the + incentives begin. + + If a program is passed after its intended start time, + its start time + + will be increased to the current time, with program + duration unchanged. + duration: + type: string + format: int64 + description: >- + duration is the length of the incentive program from + start time to + + completion in seconds. + uToken: + type: string + description: >- + uToken is the incentivized uToken collateral denom. + Suppliers who collateralize + + this asset then bond it to the incentive module are + eligible for this program's + + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This + can happen when + + a program passes if funding from community fund, or any + time before the + + program's start time if funding with MsgSponsor. A + program that reaches + + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the + custom method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive + program on a single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryUpcomingIncentiveProgramsResponse defines the response + structure for the + + OngoingIncentivePrograms and UpcomingIncentivePrograms gRPC + service handlers. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /umee/incentive/v1/total_bonded: + get: + summary: TotalBonded queries the sum of all bonded collateral uTokens. + operationId: TotalBonded + responses: + '200': + description: A successful response. + schema: + type: object + properties: + bonded: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + QueryTotalBondedResponse defines the response structure for the + TotalBonded gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: denom + description: >- + denom is an optional field which causes the query to return the + totals of only one uToken. + in: query + required: false + type: string + tags: + - Query + /umee/incentive/v1/total_unbonding: + get: + summary: TotalUnbonding queries the sum of all unbonding collateral uTokens. + operationId: TotalUnbonding + responses: + '200': + description: A successful response. + schema: + type: object + properties: + unbonding: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + QueryTotalUnbondingResponse defines the response structure for the + TotalUnbonding gRPC service handler. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: denom + description: >- + denom is an optional field which causes the query to return the + totals of only one uToken. + in: query + required: false + type: string + tags: + - Query definitions: cosmos.base.v1beta1.Coin: type: object @@ -2721,535 +4048,1414 @@ definitions: for the affected Token. - The time span covered by the historic median will be: - oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians. - description: >- - Token defines a token, along with its metadata and parameters, in - the Umee + The time span covered by the historic median will be: + oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians. + description: >- + Token defines a token, along with its metadata and parameters, in + the Umee + + capital facility that can be supplied and borrowed. + + See + https://github.com/umee-network/umee/blob/main/docs/design_docs/010-market-params.md + + for more details. + description: |- + QueryRegisteredTokensResponse defines the response structure for the + RegisteredTokens gRPC service handler. + umee.leverage.v1.Token: + type: object + properties: + base_denom: + type: string + description: >- + Base Denom is the denomination of the underlying base token. Must be + the base + + denom as registered in the Bank module (so IBC denom for IBC tokens). + reserve_factor: + type: string + description: >- + Reserve Factor defines what portion of accrued interest goes to + reserves + + when this token is borrowed. + + Valid values: 0-1. + collateral_weight: + type: string + description: >- + Collateral Weight defines what portion of the total value of the asset + + can contribute to a users borrowing power. If the collateral weight is + + zero, using this asset as collateral against borrowing will be + disabled. + + Must be smaller than `liquidation_threshold`. + + Valid values: 0-1. + liquidation_threshold: + type: string + description: |- + Liquidation Threshold defines what amount of the total value of the + asset as a collateral can contribute to a user's liquidation threshold + (above which they become eligible for liquidation). + Must be bigger than `collateral_weight`. + Valid values: 0-1. + See also: min_close_factor. + base_borrow_rate: + type: string + title: |- + Base Borrow Rate defines the minimum interest rate for borrowing this + asset. + Valid values: 0-∞ + kink_borrow_rate: + type: string + title: |- + Kink Borrow Rate defines the interest rate for borrowing this + asset when supply utilization is equal to 'kink_utilization'. + Valid values: 0-∞ + max_borrow_rate: + type: string + title: |- + Max Borrow Rate defines the interest rate for borrowing this + asset when supply utilization is at its maximum. + Valid values: 0-∞ + kink_utilization: + type: string + description: |- + Kink Utilization defines the supply utilization value where + the kink in the borrow interest rate function occurs. + Valid values: 0-1. + liquidation_incentive: + type: string + description: |- + Liquidation Incentive determines the portion of bonus collateral of + a token type liquidators receive as a liquidation reward. + Valid values: 0-1. + symbol_denom: + type: string + description: Symbol Denom is the human readable denomination of this token. + exponent: + type: integer + format: int64 + description: >- + Exponent is the power of ten by which to multiply, in order to convert + + an amount of the token denoted in its symbol denom to the actual + amount + + of its base denom. + enable_msg_supply: + type: boolean + description: >- + Enable Msg Supply allows supplying for lending or collateral using + this + + token. `false` means that a token can no longer be supplied. + + Note that withdrawing is always enabled. Disabling supply would + + be one step in phasing out an asset type. + enable_msg_borrow: + type: boolean + description: >- + Enable Msg Borrow allows borrowing of this token. Note that repaying + is + + always enabled. Disabling borrowing would be one step in phasing out + an + + asset type, but could also be used from the start for asset types + meant + + to be collateral only, like meTokens. + blacklist: + type: boolean + description: >- + Blacklist should only be used to eliminate an asset completely. A + blacklisted + + asset is treated as though its oracle price is zero, and thus ignored + by + + calculations such as collateral value and borrow limit. Can still be + repaid + + or withdrawn, but not liquidated. A blacklisted token must have + enable_msg_supply + + and enable_msg_borrow set to false. Such tokens can be safely removed + from the + + oracle and price feeder as well. + max_collateral_share: + type: string + description: >- + Max Collateral Share specifies how much of the system's overall + collateral + + can be provided by a given token. 1.0 means that the token has no + restriction. + + 0.1 means maximum 10% of system's total collateral value can be + provided by this token. + + Valid values: 0-1. + max_supply_utilization: + type: string + description: >- + Max Supply Utilization specifies the maximum supply utilization a + token is + + allowed to reach as a direct result of user borrowing. New borrows are + not allowed when + + the supply utilization is above `max_supply_utilization`. + supply_utilization(token) = total_borrowed(token) / total_supply(token) + Valid values: 0-1. + min_collateral_liquidity: + type: string + title: >- + Min Collateral Liquidity specifies min limit for the following + function: + collateral_liquidity(token) = available(token) / total_collateral(token) + Borrowing, collateralizing, or withdrawing assets is not allowed when + the + + result of such action invalidates min_collateral_liquidity. + + Liquidity can only drop below this value due to interest or + liquidations. + + The goal is to assure that there is enough available (not borrowed) + token to be available + + for withdraw when there is a collateral liquidation and the liquidator + needs to + + withdraw uToken. + + Valid values: 0 - inf + max_supply: + type: string + description: >- + Max Supply is the maximum amount of tokens the protocol can hold. + + Adding more supply of the given token to the protocol will return an + error. + + Must be a non negative value. 0 means that there is no limit. + + To mark a token as not valid for supply, `msg_supply` must be set to + false. + historic_medians: + type: integer + format: int64 + description: >- + Historic Medians is the number of median historic prices to request + from + + the oracle module when evaluating new borrow positions containing this + token. + + All MsgBorrow, MsgWithdraw, and MsgDecollateralize must result in + healthy + + borrow positions under both current and historic prices. The default + value of + + zero for this field causes current price to be used in those + calculations + + for the affected Token. + + The time span covered by the historic median will be: + oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians. + description: >- + Token defines a token, along with its metadata and parameters, in the Umee + + capital facility that can be supplied and borrowed. - capital facility that can be supplied and borrowed. + See + https://github.com/umee-network/umee/blob/main/docs/design_docs/010-market-params.md - See - https://github.com/umee-network/umee/blob/main/docs/design_docs/010-market-params.md + for more details. + cosmos.base.v1beta1.DecCoin: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + DecCoin defines a token with a denomination and a decimal amount. - for more details. + NOTE: The amount field is an Dec which implements the custom method + signatures required by gogoproto. + umee.oracle.v1.AggregateExchangeRatePrevote: + type: object + properties: + hash: + type: string + voter: + type: string + submit_block: + type: string + format: uint64 + title: |- + AggregateExchangeRatePrevote - + struct for aggregate prevoting on the ExchangeRateVote. + The purpose of aggregate prevote is to hide vote exchange rates with hash + which is formatted as hex string in SHA256("{salt}:{exchange + rate}{denom},...,{exchange rate}{denom}:{voter}") + umee.oracle.v1.AggregateExchangeRateVote: + type: object + properties: + exchange_rate_tuples: + type: array + items: + type: object + properties: + denom: + type: string + exchange_rate: + type: string + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates data + to store + voter: + type: string description: |- - QueryRegisteredTokensResponse defines the response structure for the - RegisteredTokens gRPC service handler. - umee.leverage.v1.Token: + AggregateExchangeRateVote - struct for voting on + the exchange rates of USD denominated in various assets. + umee.oracle.v1.Denom: type: object properties: base_denom: type: string - description: >- - Base Denom is the denomination of the underlying base token. Must be - the base - - denom as registered in the Bank module (so IBC denom for IBC tokens). - reserve_factor: + symbol_denom: type: string - description: >- - Reserve Factor defines what portion of accrued interest goes to - reserves - - when this token is borrowed. - - Valid values: 0-1. - collateral_weight: + exponent: + type: integer + format: int64 + title: Denom - the object to hold configurations of each denom + umee.oracle.v1.ExchangeRateTuple: + type: object + properties: + denom: type: string - description: >- - Collateral Weight defines what portion of the total value of the asset - - can contribute to a users borrowing power. If the collateral weight is - - zero, using this asset as collateral against borrowing will be - disabled. - - Must be smaller than `liquidation_threshold`. - - Valid values: 0-1. - liquidation_threshold: + exchange_rate: type: string - description: |- - Liquidation Threshold defines what amount of the total value of the - asset as a collateral can contribute to a user's liquidation threshold - (above which they become eligible for liquidation). - Must be bigger than `collateral_weight`. - Valid values: 0-1. - See also: min_close_factor. - base_borrow_rate: + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates data to + store + umee.oracle.v1.Params: + type: object + properties: + vote_period: type: string - title: |- - Base Borrow Rate defines the minimum interest rate for borrowing this - asset. - Valid values: 0-∞ - kink_borrow_rate: + format: uint64 + vote_threshold: type: string - title: |- - Kink Borrow Rate defines the interest rate for borrowing this - asset when supply utilization is equal to 'kink_utilization'. - Valid values: 0-∞ - max_borrow_rate: + reward_band: type: string - title: |- - Max Borrow Rate defines the interest rate for borrowing this - asset when supply utilization is at its maximum. - Valid values: 0-∞ - kink_utilization: + reward_distribution_window: + type: string + format: uint64 + accept_list: + type: array + items: + type: object + properties: + base_denom: + type: string + symbol_denom: + type: string + exponent: + type: integer + format: int64 + title: Denom - the object to hold configurations of each denom + slash_fraction: + type: string + slash_window: type: string + format: uint64 + min_valid_per_window: + type: string + historic_stamp_period: + type: string + format: uint64 description: |- - Kink Utilization defines the supply utilization value where - the kink in the borrow interest rate function occurs. - Valid values: 0-1. - liquidation_incentive: + Historic Stamp Period represents the amount of blocks the oracle + module waits before recording a new historic price. + median_stamp_period: type: string + format: uint64 description: |- - Liquidation Incentive determines the portion of bonus collateral of - a token type liquidators receive as a liquidation reward. - Valid values: 0-1. - symbol_denom: + Median Stamp Period represents the amount blocks the oracle module + waits between calculating and stamping a new median and standard + deviation of that median. + maximum_price_stamps: type: string - description: Symbol Denom is the human readable denomination of this token. - exponent: - type: integer - format: int64 + format: uint64 + description: |- + Maximum Price Stamps represents the maximum amount of historic prices + the oracle module will store before pruning via FIFO. + maximum_median_stamps: + type: string + format: uint64 + description: |- + Maximum Median Stamps represents the maximum amount of medians the + oracle module will store before pruning via FIFO. + description: Params defines the parameters for the oracle module. + umee.oracle.v1.Price: + type: object + properties: + exchange_rate_tuple: + type: object + properties: + denom: + type: string + exchange_rate: + type: string + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates data to + store + block_num: + type: string + format: uint64 + title: Price is an instance of a price "stamp" + umee.oracle.v1.QueryActiveExchangeRatesResponse: + type: object + properties: + active_rates: + type: array + items: + type: string description: >- - Exponent is the power of ten by which to multiply, in order to convert + activeRates defines a list of the denomination which oracle prices + agreed + + upon. + description: |- + QueryActiveExchangeRatesResponse is response type for the + Query/ActiveExchangeRates RPC method. + umee.oracle.v1.QueryAggregatePrevoteResponse: + type: object + properties: + aggregate_prevote: + type: object + properties: + hash: + type: string + voter: + type: string + submit_block: + type: string + format: uint64 + title: >- + AggregateExchangeRatePrevote - + + struct for aggregate prevoting on the ExchangeRateVote. + + The purpose of aggregate prevote is to hide vote exchange rates with + hash + + which is formatted as hex string in SHA256("{salt}:{exchange + + rate}{denom},...,{exchange rate}{denom}:{voter}") + description: |- + QueryAggregatePrevoteResponse is response type for the + Query/AggregatePrevote RPC method. + umee.oracle.v1.QueryAggregatePrevotesResponse: + type: object + properties: + aggregate_prevotes: + type: array + items: + type: object + properties: + hash: + type: string + voter: + type: string + submit_block: + type: string + format: uint64 + title: >- + AggregateExchangeRatePrevote - - an amount of the token denoted in its symbol denom to the actual - amount + struct for aggregate prevoting on the ExchangeRateVote. - of its base denom. - enable_msg_supply: - type: boolean - description: >- - Enable Msg Supply allows supplying for lending or collateral using - this + The purpose of aggregate prevote is to hide vote exchange rates with + hash - token. `false` means that a token can no longer be supplied. + which is formatted as hex string in SHA256("{salt}:{exchange - Note that withdrawing is always enabled. Disabling supply would + rate}{denom},...,{exchange rate}{denom}:{voter}") + title: >- + aggregate_prevotes defines all oracle aggregate prevotes submitted in + the - be one step in phasing out an asset type. - enable_msg_borrow: - type: boolean - description: >- - Enable Msg Borrow allows borrowing of this token. Note that repaying - is + current vote period + description: |- + QueryAggregatePrevotesResponse is response type for the + Query/AggregatePrevotes RPC method. + umee.oracle.v1.QueryAggregateVoteResponse: + type: object + properties: + aggregate_vote: + title: >- + aggregate_vote defines oracle aggregate vote submitted by a validator + in - always enabled. Disabling borrowing would be one step in phasing out - an + the current vote period + type: object + properties: + exchange_rate_tuples: + type: array + items: + type: object + properties: + denom: + type: string + exchange_rate: + type: string + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates + data to store + voter: + type: string + description: |- + AggregateExchangeRateVote - struct for voting on + the exchange rates of USD denominated in various assets. + description: |- + QueryAggregateVoteResponse is response type for the + Query/AggregateVote RPC method. + umee.oracle.v1.QueryAggregateVotesResponse: + type: object + properties: + aggregate_votes: + type: array + items: + type: object + properties: + exchange_rate_tuples: + type: array + items: + type: object + properties: + denom: + type: string + exchange_rate: + type: string + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates + data to store + voter: + type: string + description: |- + AggregateExchangeRateVote - struct for voting on + the exchange rates of USD denominated in various assets. + title: >- + aggregate_votes defines all oracle aggregate votes submitted in the + current - asset type, but could also be used from the start for asset types - meant + vote period + description: |- + QueryAggregateVotesResponse is response type for the + Query/AggregateVotes RPC method. + umee.oracle.v1.QueryAvgPriceResponse: + type: object + properties: + price: + type: string + title: QueryAvgPriceResponse is a response type for AvgPrice method + umee.oracle.v1.QueryExchangeRatesResponse: + type: object + properties: + exchange_rates: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + DecCoin defines a token with a denomination and a decimal amount. - to be collateral only, like meTokens. - blacklist: - type: boolean + NOTE: The amount field is an Dec which implements the custom method + signatures required by gogoproto. + description: |- + exchange_rates defines a list of the exchange rate for all whitelisted + denoms. + description: |- + QueryExchangeRatesResponse is response type for the + Query/ExchangeRates RPC method. + umee.oracle.v1.QueryFeederDelegationResponse: + type: object + properties: + feeder_addr: + type: string + title: feeder_addr defines the feeder delegation of a validator + description: |- + QueryFeederDelegationResponse is response type for the + Query/FeederDelegation RPC method. + umee.oracle.v1.QueryMedianDeviationsResponse: + type: object + properties: + medianDeviations: + type: array + items: + type: object + properties: + exchange_rate_tuple: + type: object + properties: + denom: + type: string + exchange_rate: + type: string + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates + data to store + block_num: + type: string + format: uint64 + title: Price is an instance of a price "stamp" description: >- - Blacklist should only be used to eliminate an asset completely. A - blacklisted - - asset is treated as though its oracle price is zero, and thus ignored - by - - calculations such as collateral value and borrow limit. Can still be - repaid - - or withdrawn, but not liquidated. A blacklisted token must have - enable_msg_supply - - and enable_msg_borrow set to false. Such tokens can be safely removed - from the + medians defines a list of the median deviations for all stamped + denoms. + description: |- + QueryMedianDeviationsResponse is response type for the + Query/MedianDeviations RPC method. + umee.oracle.v1.QueryMediansResponse: + type: object + properties: + medians: + type: array + items: + type: object + properties: + exchange_rate_tuple: + type: object + properties: + denom: + type: string + exchange_rate: + type: string + title: >- + ExchangeRateTuple - struct to store interpreted exchange rates + data to store + block_num: + type: string + format: uint64 + title: Price is an instance of a price "stamp" + description: medians defines a list of the medians for all stamped denoms. + description: |- + QueryMediansResponse is response type for the + Query/Medians RPC method. + umee.oracle.v1.QueryMissCounterResponse: + type: object + properties: + miss_counter: + type: string + format: uint64 + title: miss_counter defines the oracle miss counter of a validator + description: |- + QueryMissCounterResponse is response type for the + Query/MissCounter RPC method. + umee.oracle.v1.QueryParamsResponse: + type: object + properties: + params: + description: params defines the parameters of the module. + type: object + properties: + vote_period: + type: string + format: uint64 + vote_threshold: + type: string + reward_band: + type: string + reward_distribution_window: + type: string + format: uint64 + accept_list: + type: array + items: + type: object + properties: + base_denom: + type: string + symbol_denom: + type: string + exponent: + type: integer + format: int64 + title: Denom - the object to hold configurations of each denom + slash_fraction: + type: string + slash_window: + type: string + format: uint64 + min_valid_per_window: + type: string + historic_stamp_period: + type: string + format: uint64 + description: |- + Historic Stamp Period represents the amount of blocks the oracle + module waits before recording a new historic price. + median_stamp_period: + type: string + format: uint64 + description: |- + Median Stamp Period represents the amount blocks the oracle module + waits between calculating and stamping a new median and standard + deviation of that median. + maximum_price_stamps: + type: string + format: uint64 + description: >- + Maximum Price Stamps represents the maximum amount of historic + prices - oracle and price feeder as well. - max_collateral_share: + the oracle module will store before pruning via FIFO. + maximum_median_stamps: + type: string + format: uint64 + description: |- + Maximum Median Stamps represents the maximum amount of medians the + oracle module will store before pruning via FIFO. + description: QueryParamsResponse is the response type for the Query/Params RPC method. + umee.oracle.v1.QuerySlashWindowResponse: + type: object + properties: + window_progress: type: string + format: uint64 + description: |- + window_progress defines the number of voting periods + since the last slashing event would have taken place. + description: |- + QuerySlashWindowResponse is response type for the + Query/SlashWindow RPC method. + umee.uibc.v1.IBCTransferStatus: + type: string + enum: + - IBC_TRANSFER_STATUS_UNSPECIFIED + - IBC_TRANSFER_STATUS_QUOTA_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_ENABLED + - IBC_TRANSFER_STATUS_QUOTA_OUT_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_IN_DISABLED + - IBC_TRANSFER_STATUS_TRANSFERS_PAUSED + default: IBC_TRANSFER_STATUS_UNSPECIFIED + description: |- + - IBC_TRANSFER_STATUS_UNSPECIFIED: UNSPECIFIED defines a no-op status. + - IBC_TRANSFER_STATUS_QUOTA_DISABLED: DISABLED: all inflow and outflow quota checks are disabled. + - IBC_TRANSFER_STATUS_QUOTA_ENABLED: ENABLED: all inflow and outflow quota checks are enabled. + - IBC_TRANSFER_STATUS_QUOTA_OUT_DISABLED: DISABLED OUT: outflow quota check is disabled, while the inflow quota check is enabled. + - IBC_TRANSFER_STATUS_QUOTA_IN_DISABLED: DISABLED IN: inflow quota check is disabled, while the outflow quota check is enabled. + - IBC_TRANSFER_STATUS_TRANSFERS_PAUSED: PAUSED: all IBC transfers are paused. + title: >- + IBCTransferStatus status of ibc-transfer quota check for inflow and + outflow + umee.uibc.v1.Params: + type: object + properties: + ibc_status: description: >- - Max Collateral Share specifies how much of the system's overall - collateral - - can be provided by a given token. 1.0 means that the token has no - restriction. - - 0.1 means maximum 10% of system's total collateral value can be - provided by this token. - - Valid values: 0-1. - max_supply_utilization: + ibc_status defines the IBC ICS20 status (transfer quota or transfers + disabled). type: string - description: >- - Max Supply Utilization specifies the maximum supply utilization a - token is - - allowed to reach as a direct result of user borrowing. New borrows are - not allowed when - - the supply utilization is above `max_supply_utilization`. - supply_utilization(token) = total_borrowed(token) / total_supply(token) - Valid values: 0-1. - min_collateral_liquidity: + enum: + - IBC_TRANSFER_STATUS_UNSPECIFIED + - IBC_TRANSFER_STATUS_QUOTA_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_ENABLED + - IBC_TRANSFER_STATUS_QUOTA_OUT_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_IN_DISABLED + - IBC_TRANSFER_STATUS_TRANSFERS_PAUSED + default: IBC_TRANSFER_STATUS_UNSPECIFIED + title: >- + IBCTransferStatus status of ibc-transfer quota check for inflow and + outflow + total_quota: + type: string + title: total_quota defines the total outflow limit of ibc-transfer in USD + token_quota: + type: string + title: token_quota defines the outflow limit per token in USD + quota_duration: type: string title: >- - Min Collateral Liquidity specifies min limit for the following - function: - collateral_liquidity(token) = available(token) / total_collateral(token) - Borrowing, collateralizing, or withdrawing assets is not allowed when - the - - result of such action invalidates min_collateral_liquidity. - - Liquidity can only drop below this value due to interest or - liquidations. + quota_duration defines quota expires for each ibc-transfer denom in + seconds + title: Params of x/uibc module + umee.uibc.v1.QueryAllOutflowsResponse: + type: object + properties: + outflows: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + DecCoin defines a token with a denomination and a decimal amount. - The goal is to assure that there is enough available (not borrowed) - token to be available + NOTE: The amount field is an Dec which implements the custom method + signatures required by gogoproto. + title: QueryOutflowResponse defines response type of Query/Outflow + umee.uibc.v1.QueryOutflowsResponse: + type: object + properties: + amount: + type: string + title: QueryOutflowResponse defines response type of Query/Outflow + umee.uibc.v1.QueryParamsResponse: + type: object + properties: + params: + type: object + properties: + ibc_status: + description: >- + ibc_status defines the IBC ICS20 status (transfer quota or + transfers disabled). + type: string + enum: + - IBC_TRANSFER_STATUS_UNSPECIFIED + - IBC_TRANSFER_STATUS_QUOTA_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_ENABLED + - IBC_TRANSFER_STATUS_QUOTA_OUT_DISABLED + - IBC_TRANSFER_STATUS_QUOTA_IN_DISABLED + - IBC_TRANSFER_STATUS_TRANSFERS_PAUSED + default: IBC_TRANSFER_STATUS_UNSPECIFIED + title: >- + IBCTransferStatus status of ibc-transfer quota check for inflow + and outflow + total_quota: + type: string + title: total_quota defines the total outflow limit of ibc-transfer in USD + token_quota: + type: string + title: token_quota defines the outflow limit per token in USD + quota_duration: + type: string + title: >- + quota_duration defines quota expires for each ibc-transfer denom + in seconds + title: Params of x/uibc module + description: |- + QueryParamsResponse defines the response structure for the Params gRPC + service handler. + umee.ugov.v1.QueryMinGasPriceResponse: + type: object + properties: + min_gas_price: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + DecCoin defines a token with a denomination and a decimal amount. - for withdraw when there is a collateral liquidation and the liquidator - needs to + NOTE: The amount field is an Dec which implements the custom method + signatures required by gogoproto. + description: QueryMinGasPriceResponse response type. + umee.incentive.v1.IncentiveProgram: + type: object + properties: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it has been + created. - withdraw uToken. + It is zero when the program is being proposed by governance, and is + set - Valid values: 0 - inf - max_supply: + to its final value when the proposal passes. + start_time: type: string + format: int64 description: >- - Max Supply is the maximum amount of tokens the protocol can hold. - - Adding more supply of the given token to the protocol will return an - error. + start_time is the unix time (in seconds) at which the incentives + begin. - Must be a non negative value. 0 means that there is no limit. + If a program is passed after its intended start time, its start time - To mark a token as not valid for supply, `msg_supply` must be set to - false. - historic_medians: - type: integer + will be increased to the current time, with program duration + unchanged. + duration: + type: string format: int64 + description: |- + duration is the length of the incentive program from start time to + completion in seconds. + uToken: + type: string description: >- - Historic Medians is the number of median historic prices to request - from - - the oracle module when evaluating new borrow positions containing this - token. - - All MsgBorrow, MsgWithdraw, and MsgDecollateralize must result in - healthy + uToken is the incentivized uToken collateral denom. Suppliers who + collateralize - borrow positions under both current and historic prices. The default - value of + this asset then bond it to the incentive module are eligible for this + program's - zero for this field causes current price to be used in those - calculations + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This can happen + when - for the affected Token. + a program passes if funding from community fund, or any time before + the - The time span covered by the historic median will be: - oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians. - description: >- - Token defines a token, along with its metadata and parameters, in the Umee + program's start time if funding with MsgSponsor. A program that + reaches - capital facility that can be supplied and borrowed. + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + Coin defines a token with a denomination and an amount. - See - https://github.com/umee-network/umee/blob/main/docs/design_docs/010-market-params.md + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + Coin defines a token with a denomination and an amount. - for more details. - cosmos.base.v1beta1.DecCoin: - type: object - properties: - denom: - type: string - amount: - type: string + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. description: |- - DecCoin defines a token with a denomination and a decimal amount. - - NOTE: The amount field is an Dec which implements the custom method - signatures required by gogoproto. - umee.oracle.v1.AggregateExchangeRatePrevote: + IncentiveProgram defines a liquidity mining incentive program on a single + locked uToken denom that will run for a set amount of time. + umee.incentive.v1.Params: type: object properties: - hash: - type: string - voter: + max_unbondings: + type: integer + format: int64 + description: >- + max_unbondings is the maximum amount of concurrent unbondings an + address can have + + of each bonded uToken denom. Zero is interpreted as no limit. + unbonding_duration: type: string - submit_block: + format: int64 + description: unbonding_duration is the unbonding duration (in seconds). + emergency_unbond_fee: type: string - format: uint64 - title: |- - AggregateExchangeRatePrevote - - struct for aggregate prevoting on the ExchangeRateVote. - The purpose of aggregate prevote is to hide vote exchange rates with hash - which is formatted as hex string in SHA256("{salt}:{exchange - rate}{denom},...,{exchange rate}{denom}:{voter}") - umee.oracle.v1.AggregateExchangeRateVote: + description: >- + emergency_unbond_fee is the portion of a bond that is paid when it is + instantly + + released using MsgEmergencyUnbond. For example, 0.01 is a 1% fee. + Ranges 0-1. + description: Params defines the parameters for the incentive module. + umee.incentive.v1.QueryAccountBondsResponse: type: object properties: - exchange_rate_tuples: + bonded: type: array items: type: object properties: denom: type: string - exchange_rate: + amount: type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates data - to store - voter: - type: string - description: |- - AggregateExchangeRateVote - struct for voting on - the exchange rates of USD denominated in various assets. - umee.oracle.v1.Denom: - type: object - properties: - base_denom: - type: string - symbol_denom: - type: string - exponent: - type: integer - format: int64 - title: Denom - the object to hold configurations of each denom - umee.oracle.v1.ExchangeRateTuple: + description: |- + Coin defines a token with a denomination and an amount. + + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + unbonding: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + Coin defines a token with a denomination and an amount. + + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + unbondings: + type: array + items: + type: object + properties: + start: + type: string + format: int64 + end: + type: string + format: int64 + uToken: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: |- + Unbonding is a structure that tracks an in-progress token unbonding. + It tracks both its start time and end time, so that if the module's + unbonding time changes, the unbonding can complete at the earlier of + its original end time or its new one based on the new parameter. + description: >- + QueryAccountBondsResponse defines the response structure for the + AccountBonds gRPC service handler. + umee.incentive.v1.QueryActualRatesResponse: type: object properties: - denom: - type: string - exchange_rate: + APY: type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates data to - store - umee.oracle.v1.Params: + description: APY is the oracle price-adjusted APY of the bonded uToken. + description: >- + QueryActualRatesResponse defines the response structure for the + ActualRates gRPC service handler. + umee.incentive.v1.QueryCompletedIncentiveProgramsResponse: type: object properties: - vote_period: - type: string - format: uint64 - vote_threshold: - type: string - reward_band: - type: string - reward_distribution_window: - type: string - format: uint64 - accept_list: + programs: type: array items: type: object properties: - base_denom: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it has been + created. + + It is zero when the program is being proposed by governance, and + is set + + to its final value when the proposal passes. + start_time: type: string - symbol_denom: + format: int64 + description: >- + start_time is the unix time (in seconds) at which the incentives + begin. + + If a program is passed after its intended start time, its start + time + + will be increased to the current time, with program duration + unchanged. + duration: type: string - exponent: - type: integer format: int64 - title: Denom - the object to hold configurations of each denom - slash_fraction: - type: string - slash_window: - type: string - format: uint64 - min_valid_per_window: - type: string - historic_stamp_period: - type: string - format: uint64 - description: |- - Historic Stamp Period represents the amount of blocks the oracle - module waits before recording a new historic price. - median_stamp_period: - type: string - format: uint64 - description: |- - Median Stamp Period represents the amount blocks the oracle module - waits between calculating and stamping a new median and standard - deviation of that median. - maximum_price_stamps: - type: string - format: uint64 - description: |- - Maximum Price Stamps represents the maximum amount of historic prices - the oracle module will store before pruning via FIFO. - maximum_median_stamps: - type: string - format: uint64 - description: |- - Maximum Median Stamps represents the maximum amount of medians the - oracle module will store before pruning via FIFO. - description: Params defines the parameters for the oracle module. - umee.oracle.v1.Price: + description: >- + duration is the length of the incentive program from start time + to + + completion in seconds. + uToken: + type: string + description: >- + uToken is the incentivized uToken collateral denom. Suppliers + who collateralize + + this asset then bond it to the incentive module are eligible for + this program's + + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This can + happen when + + a program passes if funding from community fund, or any time + before the + + program's start time if funding with MsgSponsor. A program that + reaches + + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive program on a + single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryCompletedIncentiveProgramsResponse defines the response structure for + the + + CompletedIncentivePrograms gRPC service handler. + umee.incentive.v1.QueryCurrentRatesResponse: type: object properties: - exchange_rate_tuple: + reference_bond: type: object properties: denom: type: string - exchange_rate: + amount: type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates data to - store - block_num: - type: string - format: uint64 - title: Price is an instance of a price "stamp" - umee.oracle.v1.QueryActiveExchangeRatesResponse: - type: object - properties: - active_rates: + description: |- + Coin defines a token with a denomination and an amount. + + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + rewards: type: array items: - type: string + type: object + properties: + denom: + type: string + amount: + type: string + description: |- + Coin defines a token with a denomination and an amount. + + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. description: >- - activeRates defines a list of the denomination which oracle prices - agreed + Rewards are the amount of base token rewards that the reference amount + of bonded uTokens would earn - upon. - description: |- - QueryActiveExchangeRatesResponse is response type for the - Query/ActiveExchangeRates RPC method. - umee.oracle.v1.QueryAggregatePrevoteResponse: + if current rates continued for a full year. + description: >- + QueryCurrentRatesResponse defines the response structure for the + CurrentRates gRPC service handler. + umee.incentive.v1.QueryIncentiveProgramResponse: type: object properties: - aggregate_prevote: + program: type: object properties: - hash: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it has been + created. + + It is zero when the program is being proposed by governance, and + is set + + to its final value when the proposal passes. + start_time: type: string - voter: + format: int64 + description: >- + start_time is the unix time (in seconds) at which the incentives + begin. + + If a program is passed after its intended start time, its start + time + + will be increased to the current time, with program duration + unchanged. + duration: type: string - submit_block: + format: int64 + description: |- + duration is the length of the incentive program from start time to + completion in seconds. + uToken: type: string - format: uint64 - title: >- - AggregateExchangeRatePrevote - + description: >- + uToken is the incentivized uToken collateral denom. Suppliers who + collateralize - struct for aggregate prevoting on the ExchangeRateVote. + this asset then bond it to the incentive module are eligible for + this program's - The purpose of aggregate prevote is to hide vote exchange rates with - hash + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This can + happen when - which is formatted as hex string in SHA256("{salt}:{exchange + a program passes if funding from community fund, or any time + before the - rate}{denom},...,{exchange rate}{denom}:{voter}") + program's start time if funding with MsgSponsor. A program that + reaches + + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + remaining_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive program on a + single + + locked uToken denom that will run for a set amount of time. description: |- - QueryAggregatePrevoteResponse is response type for the - Query/AggregatePrevote RPC method. - umee.oracle.v1.QueryAggregatePrevotesResponse: + QueryIncentivePrograResponse defines the response structure for the + IncentiveProgram gRPC service handler. + umee.incentive.v1.QueryLastRewardTimeResponse: type: object properties: - aggregate_prevotes: + time: + type: string + format: int64 + description: >- + QueryLastRewardTimeResponse defines the response structure for the + LastRewardTime gRPC + + service handler. + umee.incentive.v1.QueryOngoingIncentiveProgramsResponse: + type: object + properties: + programs: type: array items: type: object properties: - hash: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it has been + created. + + It is zero when the program is being proposed by governance, and + is set + + to its final value when the proposal passes. + start_time: type: string - voter: + format: int64 + description: >- + start_time is the unix time (in seconds) at which the incentives + begin. + + If a program is passed after its intended start time, its start + time + + will be increased to the current time, with program duration + unchanged. + duration: type: string - submit_block: + format: int64 + description: >- + duration is the length of the incentive program from start time + to + + completion in seconds. + uToken: type: string - format: uint64 - title: >- - AggregateExchangeRatePrevote - + description: >- + uToken is the incentivized uToken collateral denom. Suppliers + who collateralize - struct for aggregate prevoting on the ExchangeRateVote. + this asset then bond it to the incentive module are eligible for + this program's - The purpose of aggregate prevote is to hide vote exchange rates with - hash + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This can + happen when - which is formatted as hex string in SHA256("{salt}:{exchange + a program passes if funding from community fund, or any time + before the - rate}{denom},...,{exchange rate}{denom}:{voter}") - title: >- - aggregate_prevotes defines all oracle aggregate prevotes submitted in - the + program's start time if funding with MsgSponsor. A program that + reaches - current vote period - description: |- - QueryAggregatePrevotesResponse is response type for the - Query/AggregatePrevotes RPC method. - umee.oracle.v1.QueryAggregateVoteResponse: - type: object - properties: - aggregate_vote: - title: >- - aggregate_vote defines oracle aggregate vote submitted by a validator - in + its start time without being funded is cancelled. + total_rewards: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. - the current vote period - type: object - properties: - exchange_rate_tuples: - type: array - items: + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + remaining_rewards: type: object properties: denom: type: string - exchange_rate: + amount: type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates - data to store - voter: + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive program on a + single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryOngoingIncentiveProgramsResponse defines the response structure for + the + + OngoingIncentivePrograms and UpcomingIncentivePrograms gRPC service + handlers. + umee.incentive.v1.QueryParamsResponse: + type: object + properties: + params: + type: object + properties: + max_unbondings: + type: integer + format: int64 + description: >- + max_unbondings is the maximum amount of concurrent unbondings an + address can have + + of each bonded uToken denom. Zero is interpreted as no limit. + unbonding_duration: type: string - description: |- - AggregateExchangeRateVote - struct for voting on - the exchange rates of USD denominated in various assets. + format: int64 + description: unbonding_duration is the unbonding duration (in seconds). + emergency_unbond_fee: + type: string + description: >- + emergency_unbond_fee is the portion of a bond that is paid when it + is instantly + + released using MsgEmergencyUnbond. For example, 0.01 is a 1% fee. + Ranges 0-1. + description: Params defines the parameters for the incentive module. description: |- - QueryAggregateVoteResponse is response type for the - Query/AggregateVote RPC method. - umee.oracle.v1.QueryAggregateVotesResponse: + QueryParamsResponse defines the response structure for the Params gRPC + service handler. + umee.incentive.v1.QueryPendingRewardsResponse: type: object properties: - aggregate_votes: + rewards: type: array items: type: object properties: - exchange_rate_tuples: - type: array - items: - type: object - properties: - denom: - type: string - exchange_rate: - type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates - data to store - voter: + denom: + type: string + amount: type: string description: |- - AggregateExchangeRateVote - struct for voting on - the exchange rates of USD denominated in various assets. - title: >- - aggregate_votes defines all oracle aggregate votes submitted in the - current + Coin defines a token with a denomination and an amount. - vote period - description: |- - QueryAggregateVotesResponse is response type for the - Query/AggregateVotes RPC method. - umee.oracle.v1.QueryAvgPriceResponse: - type: object - properties: - price: - type: string - title: QueryAvgPriceResponse is a response type for AvgPrice method - umee.oracle.v1.QueryExchangeRatesResponse: + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + description: >- + QueryPendingRewardsResponse defines the response structure for the + PendingRewards gRPC service handler. + umee.incentive.v1.QueryTotalBondedResponse: type: object properties: - exchange_rates: + bonded: type: array items: type: object @@ -3259,163 +5465,159 @@ definitions: amount: type: string description: |- - DecCoin defines a token with a denomination and a decimal amount. + Coin defines a token with a denomination and an amount. - NOTE: The amount field is an Dec which implements the custom method + NOTE: The amount field is an Int which implements the custom method signatures required by gogoproto. - description: |- - exchange_rates defines a list of the exchange rate for all whitelisted - denoms. - description: |- - QueryExchangeRatesResponse is response type for the - Query/ExchangeRates RPC method. - umee.oracle.v1.QueryFeederDelegationResponse: - type: object - properties: - feeder_addr: - type: string - title: feeder_addr defines the feeder delegation of a validator - description: |- - QueryFeederDelegationResponse is response type for the - Query/FeederDelegation RPC method. - umee.oracle.v1.QueryMedianDeviationsResponse: + description: >- + QueryTotalBondedResponse defines the response structure for the + TotalBonded gRPC service handler. + umee.incentive.v1.QueryTotalUnbondingResponse: type: object properties: - medianDeviations: + unbonding: type: array items: type: object properties: - exchange_rate_tuple: - type: object - properties: - denom: - type: string - exchange_rate: - type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates - data to store - block_num: + denom: type: string - format: uint64 - title: Price is an instance of a price "stamp" - description: >- - medians defines a list of the median deviations for all stamped - denoms. - description: |- - QueryMedianDeviationsResponse is response type for the - Query/MedianDeviations RPC method. - umee.oracle.v1.QueryMediansResponse: + amount: + type: string + description: |- + Coin defines a token with a denomination and an amount. + + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. + description: >- + QueryTotalUnbondingResponse defines the response structure for the + TotalUnbonding gRPC service handler. + umee.incentive.v1.QueryUpcomingIncentiveProgramsResponse: type: object properties: - medians: + programs: type: array items: type: object properties: - exchange_rate_tuple: + ID: + type: integer + format: int64 + description: >- + ID uniquely identifies the incentive program after it has been + created. + + It is zero when the program is being proposed by governance, and + is set + + to its final value when the proposal passes. + start_time: + type: string + format: int64 + description: >- + start_time is the unix time (in seconds) at which the incentives + begin. + + If a program is passed after its intended start time, its start + time + + will be increased to the current time, with program duration + unchanged. + duration: + type: string + format: int64 + description: >- + duration is the length of the incentive program from start time + to + + completion in seconds. + uToken: + type: string + description: >- + uToken is the incentivized uToken collateral denom. Suppliers + who collateralize + + this asset then bond it to the incentive module are eligible for + this program's + + rewards. + funded: + type: boolean + description: >- + funded indicates whether a program bas been funded. This can + happen when + + a program passes if funding from community fund, or any time + before the + + program's start time if funding with MsgSponsor. A program that + reaches + + its start time without being funded is cancelled. + total_rewards: type: object properties: denom: type: string - exchange_rate: + amount: type: string - title: >- - ExchangeRateTuple - struct to store interpreted exchange rates - data to store - block_num: - type: string - format: uint64 - title: Price is an instance of a price "stamp" - description: medians defines a list of the medians for all stamped denoms. - description: |- - QueryMediansResponse is response type for the - Query/Medians RPC method. - umee.oracle.v1.QueryMissCounterResponse: - type: object - properties: - miss_counter: - type: string - format: uint64 - title: miss_counter defines the oracle miss counter of a validator - description: |- - QueryMissCounterResponse is response type for the - Query/MissCounter RPC method. - umee.oracle.v1.QueryParamsResponse: - type: object - properties: - params: - description: params defines the parameters of the module. - type: object - properties: - vote_period: - type: string - format: uint64 - vote_threshold: - type: string - reward_band: - type: string - reward_distribution_window: - type: string - format: uint64 - accept_list: - type: array - items: + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + remaining_rewards: type: object properties: - base_denom: + denom: type: string - symbol_denom: + amount: type: string - exponent: - type: integer - format: int64 - title: Denom - the object to hold configurations of each denom - slash_fraction: - type: string - slash_window: - type: string - format: uint64 - min_valid_per_window: - type: string - historic_stamp_period: - type: string - format: uint64 - description: |- - Historic Stamp Period represents the amount of blocks the oracle - module waits before recording a new historic price. - median_stamp_period: - type: string - format: uint64 - description: |- - Median Stamp Period represents the amount blocks the oracle module - waits between calculating and stamping a new median and standard - deviation of that median. - maximum_price_stamps: - type: string - format: uint64 - description: >- - Maximum Price Stamps represents the maximum amount of historic - prices + description: >- + Coin defines a token with a denomination and an amount. - the oracle module will store before pruning via FIFO. - maximum_median_stamps: - type: string - format: uint64 - description: |- - Maximum Median Stamps represents the maximum amount of medians the - oracle module will store before pruning via FIFO. - description: QueryParamsResponse is the response type for the Query/Params RPC method. - umee.oracle.v1.QuerySlashWindowResponse: + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + description: >- + IncentiveProgram defines a liquidity mining incentive program on a + single + + locked uToken denom that will run for a set amount of time. + description: >- + QueryUpcomingIncentiveProgramsResponse defines the response structure for + the + + OngoingIncentivePrograms and UpcomingIncentivePrograms gRPC service + handlers. + umee.incentive.v1.Unbonding: type: object properties: - window_progress: + start: type: string - format: uint64 + format: int64 + end: + type: string + format: int64 + uToken: + type: object + properties: + denom: + type: string + amount: + type: string description: |- - window_progress defines the number of voting periods - since the last slashing event would have taken place. + Coin defines a token with a denomination and an amount. + + NOTE: The amount field is an Int which implements the custom method + signatures required by gogoproto. description: |- - QuerySlashWindowResponse is response type for the - Query/SlashWindow RPC method. + Unbonding is a structure that tracks an in-progress token unbonding. + It tracks both its start time and end time, so that if the module's + unbonding time changes, the unbonding can complete at the earlier of + its original end time or its new one based on the new parameter. diff --git a/tools/tools.go b/tools/tools.go index ed7e85ad23..226740cf4b 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -11,4 +11,7 @@ import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/mgechev/revive" _ "mvdan.cc/gofumpt" + + // unnamed import of statik for swagger UI support + _ "github.com/umee-network/umee/v4/swagger/statik" )