From b2943816f30812c4e55551ead43ad2956c608a7e Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 14:46:19 +0200 Subject: [PATCH 01/17] Create consistent prebuild script in all packages --- packages/cli/package.json | 1 + packages/cosmwasm/package.json | 3 ++- packages/crypto/package.json | 3 ++- packages/encoding/package.json | 3 ++- packages/faucet/package.json | 3 ++- packages/json-rpc/package.json | 3 ++- packages/launchpad/package.json | 3 ++- packages/math/package.json | 3 ++- packages/proto-signing/package.json | 3 ++- packages/socket/package.json | 3 ++- packages/stargate/package.json | 3 ++- packages/stream/package.json | 3 ++- packages/tendermint-rpc/package.json | 3 ++- packages/utils/package.json | 3 ++- 14 files changed, 27 insertions(+), 13 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 1976419c..4a398b2b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -19,6 +19,7 @@ "format-text": "prettier --write --prose-wrap always --print-width 80 \"./*.md\"", "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", + "prebuild": "shx rm -rf ./build", "build": "tsc", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "start": "yarn build-or-skip && ./bin/cosmwasm-cli", diff --git a/packages/cosmwasm/package.json b/packages/cosmwasm/package.json index ad633fe9..89d8ee64 100644 --- a/packages/cosmwasm/package.json +++ b/packages/cosmwasm/package.json @@ -28,7 +28,8 @@ "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 4ac5120a..5d7c27d9 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -38,7 +38,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/encoding/package.json b/packages/encoding/package.json index 151c4ff6..b2b32e77 100644 --- a/packages/encoding/package.json +++ b/packages/encoding/package.json @@ -37,7 +37,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/faucet/package.json b/packages/faucet/package.json index 72d0fea2..80e33c1b 100644 --- a/packages/faucet/package.json +++ b/packages/faucet/package.json @@ -27,7 +27,8 @@ "format-text": "prettier --write --prose-wrap always --print-width 80 \"./*.md\"", "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", - "build": "shx rm -rf ./build && tsc", + "prebuild": "shx rm -rf ./build", + "build": "tsc", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test": "yarn build-or-skip && yarn test-node", diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json index 99ea16b0..b6846b0a 100644 --- a/packages/json-rpc/package.json +++ b/packages/json-rpc/package.json @@ -39,7 +39,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && tsc -p tsconfig.workers.json && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && tsc -p tsconfig.workers.json && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/launchpad/package.json b/packages/launchpad/package.json index a89e7411..43070c22 100644 --- a/packages/launchpad/package.json +++ b/packages/launchpad/package.json @@ -31,7 +31,8 @@ "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/math/package.json b/packages/math/package.json index 77bf6de9..19a101d1 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -37,7 +37,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/proto-signing/package.json b/packages/proto-signing/package.json index 0c0c20af..ffaa1a19 100644 --- a/packages/proto-signing/package.json +++ b/packages/proto-signing/package.json @@ -29,7 +29,8 @@ "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/socket/package.json b/packages/socket/package.json index 87b793e4..7a1eed45 100644 --- a/packages/socket/package.json +++ b/packages/socket/package.json @@ -39,7 +39,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/stargate/package.json b/packages/stargate/package.json index 9353b1b5..665b84cd 100644 --- a/packages/stargate/package.json +++ b/packages/stargate/package.json @@ -28,7 +28,8 @@ "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/stream/package.json b/packages/stream/package.json index 2fc0b767..a8c9a1ce 100644 --- a/packages/stream/package.json +++ b/packages/stream/package.json @@ -39,7 +39,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/tendermint-rpc/package.json b/packages/tendermint-rpc/package.json index be5e4efc..61f83c74 100644 --- a/packages/tendermint-rpc/package.json +++ b/packages/tendermint-rpc/package.json @@ -39,7 +39,8 @@ "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/utils/package.json b/packages/utils/package.json index 4252d9da..b349e8da 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -30,7 +30,8 @@ "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "prebuild": "shx rm -rf ./build", + "build": "tsc && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test": "yarn build-or-skip && yarn test-node", From 0dc22c252534728c1e3d4f76e219e09971296200 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 14:50:14 +0200 Subject: [PATCH 02/17] CReate consistent postbuild script --- packages/cosmwasm/package.json | 3 ++- packages/crypto/package.json | 3 ++- packages/encoding/package.json | 3 ++- packages/json-rpc/package.json | 3 ++- packages/launchpad/package.json | 3 ++- packages/math/package.json | 3 ++- packages/proto-signing/package.json | 3 ++- packages/socket/package.json | 3 ++- packages/stargate/package.json | 3 ++- packages/stream/package.json | 3 ++- packages/tendermint-rpc/package.json | 3 ++- packages/utils/package.json | 3 ++- 12 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/cosmwasm/package.json b/packages/cosmwasm/package.json index 89d8ee64..5c0596ea 100644 --- a/packages/cosmwasm/package.json +++ b/packages/cosmwasm/package.json @@ -29,7 +29,8 @@ "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 5d7c27d9..93addc23 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -39,7 +39,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/encoding/package.json b/packages/encoding/package.json index b2b32e77..75f4eaa5 100644 --- a/packages/encoding/package.json +++ b/packages/encoding/package.json @@ -38,7 +38,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json index b6846b0a..dde78942 100644 --- a/packages/json-rpc/package.json +++ b/packages/json-rpc/package.json @@ -40,7 +40,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && tsc -p tsconfig.workers.json && yarn move-types && yarn format-types", + "build": "tsc && tsc -p tsconfig.workers.json", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/launchpad/package.json b/packages/launchpad/package.json index 43070c22..0e02e3a7 100644 --- a/packages/launchpad/package.json +++ b/packages/launchpad/package.json @@ -32,7 +32,8 @@ "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/math/package.json b/packages/math/package.json index 19a101d1..24f14e51 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -38,7 +38,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/proto-signing/package.json b/packages/proto-signing/package.json index ffaa1a19..fb9d40f2 100644 --- a/packages/proto-signing/package.json +++ b/packages/proto-signing/package.json @@ -30,7 +30,8 @@ "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated && yarn move-types && yarn format-types", + "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/socket/package.json b/packages/socket/package.json index 7a1eed45..ff2e8799 100644 --- a/packages/socket/package.json +++ b/packages/socket/package.json @@ -40,7 +40,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/stargate/package.json b/packages/stargate/package.json index 665b84cd..732e2325 100644 --- a/packages/stargate/package.json +++ b/packages/stargate/package.json @@ -29,7 +29,8 @@ "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated && yarn move-types && yarn format-types", + "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/stream/package.json b/packages/stream/package.json index a8c9a1ce..679dac1b 100644 --- a/packages/stream/package.json +++ b/packages/stream/package.json @@ -40,7 +40,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/tendermint-rpc/package.json b/packages/tendermint-rpc/package.json index 61f83c74..a021075e 100644 --- a/packages/tendermint-rpc/package.json +++ b/packages/tendermint-rpc/package.json @@ -40,7 +40,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, diff --git a/packages/utils/package.json b/packages/utils/package.json index b349e8da..9d65b425 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -31,7 +31,8 @@ "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && yarn move-types && yarn format-types", + "build": "tsc", + "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test": "yarn build-or-skip && yarn test-node", From 01506951e712dd6a81b96ff44cbd4151fab7b703 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 15:18:43 +0200 Subject: [PATCH 03/17] Create query client --- packages/stargate/src/queryclient.ts | 183 ++++++++++++++++++++ packages/stargate/src/stargateclient.ts | 48 +---- packages/stargate/types/queryclient.d.ts | 109 ++++++++++++ packages/stargate/types/stargateclient.d.ts | 3 +- 4 files changed, 300 insertions(+), 43 deletions(-) create mode 100644 packages/stargate/src/queryclient.ts create mode 100644 packages/stargate/types/queryclient.d.ts diff --git a/packages/stargate/src/queryclient.ts b/packages/stargate/src/queryclient.ts new file mode 100644 index 00000000..fedc9a0f --- /dev/null +++ b/packages/stargate/src/queryclient.ts @@ -0,0 +1,183 @@ +/* eslint-disable no-dupe-class-members, @typescript-eslint/ban-types, @typescript-eslint/naming-convention */ +import { toHex } from "@cosmjs/encoding"; +import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { arrayContentEquals, assert, isNonNullObject } from "@cosmjs/utils"; + +type QueryExtensionSetup

= (base: QueryClient) => P; + +export class QueryClient { + /** Constructs a QueryClient with 0 extensions */ + public static withExtensions(tmClient: TendermintClient): QueryClient; + + /** Constructs a QueryClient with 1 extension */ + public static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + ): QueryClient & A; + + /** Constructs a QueryClient with 2 extensions */ + public static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + ): QueryClient & A & B; + + /** Constructs a QueryClient with 3 extensions */ + public static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + ): QueryClient & A & B & C; + + /** Constructs a QueryClient with 4 extensions */ + public static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + ): QueryClient & A & B & C & D; + + /** Constructs a QueryClient with 5 extensions */ + public static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E; + + /** Constructs a QueryClient with 6 extensions */ + public static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object, + F extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F; + + /** Constructs a QueryClient with 7 extensions */ + public static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object, + F extends object, + G extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G; + + /** Constructs a QueryClient with 8 extensions */ + public static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object, + F extends object, + G extends object, + H extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H; + + public static withExtensions( + tmClient: TendermintClient, + ...extensionSetups: Array> + ): any { + const client = new QueryClient(tmClient); + const extensions = extensionSetups.map((setupExtension) => setupExtension(client)); + for (const extension of extensions) { + assert(isNonNullObject(extension), `Extension must be a non-null object`); + for (const [moduleKey, moduleValue] of Object.entries(extension)) { + assert( + isNonNullObject(moduleValue), + `Module must be a non-null object. Found type ${typeof moduleValue} for module "${moduleKey}".`, + ); + const current = (client as any)[moduleKey] || {}; + (client as any)[moduleKey] = { + ...current, + ...moduleValue, + }; + } + } + return client; + } + + private readonly tmClient: TendermintClient; + + public constructor(tmClient: TendermintClient) { + this.tmClient = tmClient; + } + + public async queryVerified(store: string, key: Uint8Array): Promise { + const response = await this.tmClient.abciQuery({ + // we need the StoreKey for the module, not the module name + // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L12 + path: `/store/${store}/key`, + data: key, + prove: true, + }); + + if (response.code) { + throw new Error(`Query failed with (${response.code}): ${response.log}`); + } + + if (!arrayContentEquals(response.key, key)) { + throw new Error(`Response key ${toHex(response.key)} doesn't match query key ${toHex(key)}`); + } + + // TODO: implement proof verification + // https://github.com/CosmWasm/cosmjs/issues/347 + + return response.value; + } + + public async queryUnverified(path: string, request: Uint8Array): Promise { + const response = await this.tmClient.abciQuery({ + path: path, + data: request, + prove: false, + }); + + if (response.code) { + throw new Error(`Query failed with (${response.code}): ${response.log}`); + } + + return response.value; + } +} diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 75b18ec9..566c0602 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -13,10 +13,11 @@ import { import { Uint53, Uint64 } from "@cosmjs/math"; import { decodeAny } from "@cosmjs/proto-signing"; import { broadcastTxCommitSuccess, Client as TendermintClient, QueryString } from "@cosmjs/tendermint-rpc"; -import { arrayContentEquals, assert, assertDefined } from "@cosmjs/utils"; +import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; import { cosmos } from "./generated/codecimpl"; +import { QueryClient } from "./queryclient"; /** A transaction that is indexed as part of the transaction history */ export interface IndexedTx { @@ -114,6 +115,7 @@ export interface PrivateStargateClient { export class StargateClient { private readonly tmClient: TendermintClient; + private readonly queryClient: QueryClient; private chainId: string | undefined; public static async connect(endpoint: string): Promise { @@ -123,6 +125,7 @@ export class StargateClient { private constructor(tmClient: TendermintClient) { this.tmClient = tmClient; + this.queryClient = QueryClient.withExtensions(tmClient); } public async getChainId(): Promise { @@ -145,7 +148,7 @@ export class StargateClient { const { prefix, data: binAddress } = Bech32.decode(searchAddress); // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L29-L32 const accountKey = Uint8Array.from([0x01, ...binAddress]); - const responseData = await this.queryVerified("acc", accountKey); + const responseData = await this.queryClient.queryVerified("acc", accountKey); if (responseData.length === 0) return null; @@ -198,7 +201,7 @@ export class StargateClient { const binAddress = Bech32.decode(address).data; const bankKey = Uint8Array.from([...toAscii("balances"), ...binAddress, ...toAscii(searchDenom)]); - const responseData = await this.queryVerified("bank", bankKey); + const responseData = await this.queryClient.queryVerified("bank", bankKey); const { amount, denom } = cosmos.Coin.decode(responseData); if (denom === "") { return null; @@ -221,7 +224,7 @@ export class StargateClient { const request = cosmos.bank.QueryAllBalancesRequest.encode({ address: Bech32.decode(address).data, }).finish(); - const responseData = await this.queryUnverified(path, request); + const responseData = await this.queryClient.queryUnverified(path, request); const response = cosmos.bank.QueryAllBalancesResponse.decode(responseData); return response.balances.map(coinFromProto); } @@ -280,43 +283,6 @@ export class StargateClient { }; } - private async queryVerified(store: string, key: Uint8Array): Promise { - const response = await this.tmClient.abciQuery({ - // we need the StoreKey for the module, not the module name - // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L12 - path: `/store/${store}/key`, - data: key, - prove: true, - }); - - if (response.code) { - throw new Error(`Query failed with (${response.code}): ${response.log}`); - } - - if (!arrayContentEquals(response.key, key)) { - throw new Error(`Response key ${toHex(response.key)} doesn't match query key ${toHex(key)}`); - } - - // TODO: implement proof verification - // https://github.com/CosmWasm/cosmjs/issues/347 - - return response.value; - } - - private async queryUnverified(path: string, request: Uint8Array): Promise { - const response = await this.tmClient.abciQuery({ - path: path, - data: request, - prove: false, - }); - - if (response.code) { - throw new Error(`Query failed with (${response.code}): ${response.log}`); - } - - return response.value; - } - private async txsQuery(query: string): Promise { const params = { query: query as QueryString, diff --git a/packages/stargate/types/queryclient.d.ts b/packages/stargate/types/queryclient.d.ts new file mode 100644 index 00000000..c00db57b --- /dev/null +++ b/packages/stargate/types/queryclient.d.ts @@ -0,0 +1,109 @@ +import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +declare type QueryExtensionSetup

= (base: QueryClient) => P; +export declare class QueryClient { + /** Constructs a QueryClient with 0 extensions */ + static withExtensions(tmClient: TendermintClient): QueryClient; + /** Constructs a QueryClient with 1 extension */ + static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + ): QueryClient & A; + /** Constructs a QueryClient with 2 extensions */ + static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + ): QueryClient & A & B; + /** Constructs a QueryClient with 3 extensions */ + static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + ): QueryClient & A & B & C; + /** Constructs a QueryClient with 4 extensions */ + static withExtensions( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + ): QueryClient & A & B & C & D; + /** Constructs a QueryClient with 5 extensions */ + static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E; + /** Constructs a QueryClient with 6 extensions */ + static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object, + F extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F; + /** Constructs a QueryClient with 7 extensions */ + static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object, + F extends object, + G extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G; + /** Constructs a QueryClient with 8 extensions */ + static withExtensions< + A extends object, + B extends object, + C extends object, + D extends object, + E extends object, + F extends object, + G extends object, + H extends object + >( + tmClient: TendermintClient, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H; + private readonly tmClient; + constructor(tmClient: TendermintClient); + queryVerified(store: string, key: Uint8Array): Promise; + queryUnverified(path: string, request: Uint8Array): Promise; +} +export {}; diff --git a/packages/stargate/types/stargateclient.d.ts b/packages/stargate/types/stargateclient.d.ts index d641352f..b8c8e460 100644 --- a/packages/stargate/types/stargateclient.d.ts +++ b/packages/stargate/types/stargateclient.d.ts @@ -49,6 +49,7 @@ export interface PrivateStargateClient { } export declare class StargateClient { private readonly tmClient; + private readonly queryClient; private chainId; static connect(endpoint: string): Promise; private constructor(); @@ -68,7 +69,5 @@ export declare class StargateClient { searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise; disconnect(): void; broadcastTx(tx: Uint8Array): Promise; - private queryVerified; - private queryUnverified; private txsQuery; } From dfe61c4522ff8c38681755c7ec3af20ad0bb97f9 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 15:23:42 +0200 Subject: [PATCH 04/17] Create BankExtension --- packages/stargate/src/queries/bank.ts | 29 +++++++++++++++++++++++ packages/stargate/src/stargateclient.ts | 26 ++++++-------------- packages/stargate/types/queries/bank.d.ts | 8 +++++++ 3 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 packages/stargate/src/queries/bank.ts create mode 100644 packages/stargate/types/queries/bank.d.ts diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts new file mode 100644 index 00000000..3fa8f3b4 --- /dev/null +++ b/packages/stargate/src/queries/bank.ts @@ -0,0 +1,29 @@ +import { Bech32, toAscii } from "@cosmjs/encoding"; + +import { cosmos } from "../generated/codecimpl"; +import { QueryClient } from "../queryclient"; + +export interface BankExtension { + readonly bank: { + readonly balance: (address: string, denom: string) => Promise; + }; +} + +export function setupBankExtension(base: QueryClient): BankExtension { + return { + bank: { + balance: async (address: string, denom: string) => { + // balance key is a bit tricker, using some prefix stores + // https://github.com/cosmwasm/cosmos-sdk/blob/80f7ff62f79777a487d0c7a53c64b0f7e43c47b9/x/bank/keeper/view.go#L74-L77 + // ("balances", binAddress, denom) + // it seem like prefix stores just do a dumb concat with the keys (no tricks to avoid overlap) + // https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L61-L64 + // https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L37-L43 + const binAddress = Bech32.decode(address).data; + const bankKey = Uint8Array.from([...toAscii("balances"), ...binAddress, ...toAscii(denom)]); + const responseData = await base.queryVerified("bank", bankKey); + return cosmos.Coin.decode(responseData); + }, + }, + }; +} diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 566c0602..4532b8b3 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { Bech32, toAscii, toHex } from "@cosmjs/encoding"; +import { Bech32, toHex } from "@cosmjs/encoding"; import { Block, Coin, @@ -17,6 +17,7 @@ import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; import { cosmos } from "./generated/codecimpl"; +import { BankExtension, setupBankExtension } from "./queries/bank"; import { QueryClient } from "./queryclient"; /** A transaction that is indexed as part of the transaction history */ @@ -115,7 +116,7 @@ export interface PrivateStargateClient { export class StargateClient { private readonly tmClient: TendermintClient; - private readonly queryClient: QueryClient; + private readonly queryClient: QueryClient & BankExtension; private chainId: string | undefined; public static async connect(endpoint: string): Promise { @@ -125,7 +126,7 @@ export class StargateClient { private constructor(tmClient: TendermintClient) { this.tmClient = tmClient; - this.queryClient = QueryClient.withExtensions(tmClient); + this.queryClient = QueryClient.withExtensions(tmClient, setupBankExtension); } public async getChainId(): Promise { @@ -192,24 +193,11 @@ export class StargateClient { } public async getBalance(address: string, searchDenom: string): Promise { - // balance key is a bit tricker, using some prefix stores - // https://github.com/cosmwasm/cosmos-sdk/blob/80f7ff62f79777a487d0c7a53c64b0f7e43c47b9/x/bank/keeper/view.go#L74-L77 - // ("balances", binAddress, denom) - // it seem like prefix stores just do a dumb concat with the keys (no tricks to avoid overlap) - // https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L61-L64 - // https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L37-L43 - const binAddress = Bech32.decode(address).data; - const bankKey = Uint8Array.from([...toAscii("balances"), ...binAddress, ...toAscii(searchDenom)]); - - const responseData = await this.queryClient.queryVerified("bank", bankKey); - const { amount, denom } = cosmos.Coin.decode(responseData); - if (denom === "") { + const balance = await this.queryClient.bank.balance(address, searchDenom); + if (!balance.denom) { return null; } else { - return { - amount: amount, - denom: denom, - }; + return coinFromProto(balance); } } diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts new file mode 100644 index 00000000..e55feda0 --- /dev/null +++ b/packages/stargate/types/queries/bank.d.ts @@ -0,0 +1,8 @@ +import { cosmos } from "../generated/codecimpl"; +import { QueryClient } from "../queryclient"; +export interface BankExtension { + readonly bank: { + readonly balance: (address: string, denom: string) => Promise; + }; +} +export declare function setupBankExtension(base: QueryClient): BankExtension; From d7efe229e5edf083e64171191fa4c254808ab18f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 12 Aug 2020 14:24:58 +0200 Subject: [PATCH 05/17] Pull out balances query --- packages/stargate/src/queries/bank.ts | 10 ++++++++++ packages/stargate/src/stargateclient.ts | 9 ++------- packages/stargate/types/queries/bank.d.ts | 1 + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 3fa8f3b4..8bd8b97e 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -6,6 +6,7 @@ import { QueryClient } from "../queryclient"; export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; + readonly balances: (address: string) => Promise; }; } @@ -24,6 +25,15 @@ export function setupBankExtension(base: QueryClient): BankExtension { const responseData = await base.queryVerified("bank", bankKey); return cosmos.Coin.decode(responseData); }, + balances: async (address: string) => { + const path = "/cosmos.bank.Query/AllBalances"; + const request = cosmos.bank.QueryAllBalancesRequest.encode({ + address: Bech32.decode(address).data, + }).finish(); + const responseData = await base.queryUnverified(path, request); + const response = cosmos.bank.QueryAllBalancesResponse.decode(responseData); + return response.balances; + }, }, }; } diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 4532b8b3..61563561 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -208,13 +208,8 @@ export class StargateClient { * proofs from such a method. */ public async getAllBalancesUnverified(address: string): Promise { - const path = "/cosmos.bank.Query/AllBalances"; - const request = cosmos.bank.QueryAllBalancesRequest.encode({ - address: Bech32.decode(address).data, - }).finish(); - const responseData = await this.queryClient.queryUnverified(path, request); - const response = cosmos.bank.QueryAllBalancesResponse.decode(responseData); - return response.balances.map(coinFromProto); + const balances = await this.queryClient.bank.balances(address); + return balances.map(coinFromProto); } public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise { diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index e55feda0..fd6fb445 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -3,6 +3,7 @@ import { QueryClient } from "../queryclient"; export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; + readonly balances: (address: string) => Promise; }; } export declare function setupBankExtension(base: QueryClient): BankExtension; From 5620bb3d80462f4e74ec5531d300919dad6bef82 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 12 Aug 2020 15:25:19 +0200 Subject: [PATCH 06/17] Use autogenerated typed queries --- packages/stargate/src/queries/bank.ts | 28 +++++++++++++++-------- packages/stargate/src/stargateclient.ts | 4 ++-- packages/stargate/types/queries/bank.d.ts | 4 +++- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 8bd8b97e..29f4629d 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -6,11 +6,24 @@ import { QueryClient } from "../queryclient"; export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; - readonly balances: (address: string) => Promise; + readonly unverified: { + readonly balances: (address: string) => Promise; + }; }; } export function setupBankExtension(base: QueryClient): BankExtension { + // Use this service to get easy typed access to query methods + // This cannot be used to for proof verification + const queryService = cosmos.bank.Query.create((method: any, requestData, callback) => { + // Parts of the path are unavailable, so we hardcode them here. See https://github.com/protobufjs/protobuf.js/issues/1229 + const path = `/cosmos.bank.Query/${method.name}`; + base + .queryUnverified(path, requestData) + .then((response) => callback(null, response)) + .catch((error) => callback(error)); + }); + return { bank: { balance: async (address: string, denom: string) => { @@ -25,14 +38,11 @@ export function setupBankExtension(base: QueryClient): BankExtension { const responseData = await base.queryVerified("bank", bankKey); return cosmos.Coin.decode(responseData); }, - balances: async (address: string) => { - const path = "/cosmos.bank.Query/AllBalances"; - const request = cosmos.bank.QueryAllBalancesRequest.encode({ - address: Bech32.decode(address).data, - }).finish(); - const responseData = await base.queryUnverified(path, request); - const response = cosmos.bank.QueryAllBalancesResponse.decode(responseData); - return response.balances; + unverified: { + balances: async (address: string) => { + const response = await queryService.allBalances({ address: Bech32.decode(address).data }); + return response.balances; + }, }, }, }; diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 61563561..6354e302 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -194,7 +194,7 @@ export class StargateClient { public async getBalance(address: string, searchDenom: string): Promise { const balance = await this.queryClient.bank.balance(address, searchDenom); - if (!balance.denom) { + if (!balance?.denom) { return null; } else { return coinFromProto(balance); @@ -208,7 +208,7 @@ export class StargateClient { * proofs from such a method. */ public async getAllBalancesUnverified(address: string): Promise { - const balances = await this.queryClient.bank.balances(address); + const balances = await this.queryClient.bank.unverified.balances(address); return balances.map(coinFromProto); } diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index fd6fb445..4e626954 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -3,7 +3,9 @@ import { QueryClient } from "../queryclient"; export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; - readonly balances: (address: string) => Promise; + readonly unverified: { + readonly balances: (address: string) => Promise; + }; }; } export declare function setupBankExtension(base: QueryClient): BankExtension; From 735617aa182a37625c77b1019f24b3a803017c22 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 12 Aug 2020 23:46:06 +0200 Subject: [PATCH 07/17] Test and update BankExtension.balance --- packages/stargate/package.json | 2 +- packages/stargate/src/queries/bank.spec.ts | 47 ++++++++++++++++++++++ packages/stargate/src/queries/bank.ts | 12 +++++- packages/stargate/src/stargateclient.ts | 6 +-- packages/stargate/types/queries/bank.d.ts | 2 +- 5 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 packages/stargate/src/queries/bank.spec.ts diff --git a/packages/stargate/package.json b/packages/stargate/package.json index 732e2325..26ed5950 100644 --- a/packages/stargate/package.json +++ b/packages/stargate/package.json @@ -26,7 +26,7 @@ "format-text": "prettier --write --prose-wrap always --print-width 80 \"./*.md\"", "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", - "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", + "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated", diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts new file mode 100644 index 00000000..bb50bcd3 --- /dev/null +++ b/packages/stargate/src/queries/bank.spec.ts @@ -0,0 +1,47 @@ +import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; + +import { QueryClient } from "../queryclient"; +import { nonExistentAddress, pendingWithoutSimapp, simapp, unused } from "../testutils.spec"; +import { BankExtension, setupBankExtension } from "./bank"; + +async function makeBankClient(rpcUrl: string): Promise { + // TODO: tmClient is not owned by QueryClient but should be disconnected somehow (once we use WebSockets) + const tmClient = await TendermintClient.connect(rpcUrl); + return QueryClient.withExtensions(tmClient, setupBankExtension); +} + +describe("BankExtension", () => { + describe("balance", () => { + it("works for different existing balances", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response1 = await client.bank.balance(unused.address, simapp.denomFee); + expect(response1).toEqual({ + amount: unused.balanceFee, + denom: simapp.denomFee, + }); + const response2 = await client.bank.balance(unused.address, simapp.denomStaking); + expect(response2).toEqual({ + amount: unused.balanceStaking, + denom: simapp.denomStaking, + }); + }); + + it("returns null for non-existent balance", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.balance(unused.address, "gintonic"); + expect(response).toBeNull(); + }); + + it("returns null for non-existent address", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.balance(nonExistentAddress, simapp.denomFee); + expect(response).toBeNull(); + }); + }); +}); diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 29f4629d..b6a93a0d 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -3,9 +3,17 @@ import { Bech32, toAscii } from "@cosmjs/encoding"; import { cosmos } from "../generated/codecimpl"; import { QueryClient } from "../queryclient"; +/** + * Use this to convert a protobuf.js class to the interface (e.g. Coin to ICoin) + * in a ways that makes Jasmine's toEqual happy. + */ +function toObject(thing: I): O { + return { ...thing }; +} + export interface BankExtension { readonly bank: { - readonly balance: (address: string, denom: string) => Promise; + readonly balance: (address: string, denom: string) => Promise; readonly unverified: { readonly balances: (address: string) => Promise; }; @@ -36,7 +44,7 @@ export function setupBankExtension(base: QueryClient): BankExtension { const binAddress = Bech32.decode(address).data; const bankKey = Uint8Array.from([...toAscii("balances"), ...binAddress, ...toAscii(denom)]); const responseData = await base.queryVerified("bank", bankKey); - return cosmos.Coin.decode(responseData); + return responseData.length ? toObject(cosmos.Coin.decode(responseData)) : null; }, unverified: { balances: async (address: string) => { diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 6354e302..9cf168f6 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -194,11 +194,7 @@ export class StargateClient { public async getBalance(address: string, searchDenom: string): Promise { const balance = await this.queryClient.bank.balance(address, searchDenom); - if (!balance?.denom) { - return null; - } else { - return coinFromProto(balance); - } + return balance ? coinFromProto(balance) : null; } /** diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index 4e626954..48cabf7d 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -2,7 +2,7 @@ import { cosmos } from "../generated/codecimpl"; import { QueryClient } from "../queryclient"; export interface BankExtension { readonly bank: { - readonly balance: (address: string, denom: string) => Promise; + readonly balance: (address: string, denom: string) => Promise; readonly unverified: { readonly balances: (address: string) => Promise; }; From 59687d0fd6e7c615fcb66504605064908906e73b Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 00:12:53 +0200 Subject: [PATCH 08/17] Test BankExtension.allBalances --- packages/stargate/src/queries/bank.spec.ts | 27 ++++++++++++++++++++++ packages/stargate/src/queries/bank.ts | 11 +++++---- packages/stargate/src/stargateclient.ts | 2 +- packages/stargate/types/queries/bank.d.ts | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index bb50bcd3..14a0f6c5 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -44,4 +44,31 @@ describe("BankExtension", () => { expect(response).toBeNull(); }); }); + + describe("allBalances", () => { + it("returns all balances for unused account", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const balances = await client.bank.unverified.allBalances(unused.address); + expect(balances).toEqual([ + { + amount: unused.balanceFee, + denom: simapp.denomFee, + }, + { + amount: unused.balanceStaking, + denom: simapp.denomStaking, + }, + ]); + }); + + it("returns an empty list for non-existent account", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const balances = await client.bank.unverified.allBalances(nonExistentAddress); + expect(balances).toEqual([]); + }); + }); }); diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index b6a93a0d..2207f8e6 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -7,7 +7,8 @@ import { QueryClient } from "../queryclient"; * Use this to convert a protobuf.js class to the interface (e.g. Coin to ICoin) * in a ways that makes Jasmine's toEqual happy. */ -function toObject(thing: I): O { +// eslint-disable-next-line @typescript-eslint/ban-types +function toObject(thing: I): Omit { return { ...thing }; } @@ -15,7 +16,7 @@ export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; readonly unverified: { - readonly balances: (address: string) => Promise; + readonly allBalances: (address: string) => Promise; }; }; } @@ -47,9 +48,9 @@ export function setupBankExtension(base: QueryClient): BankExtension { return responseData.length ? toObject(cosmos.Coin.decode(responseData)) : null; }, unverified: { - balances: async (address: string) => { - const response = await queryService.allBalances({ address: Bech32.decode(address).data }); - return response.balances; + allBalances: async (address: string) => { + const { balances } = await queryService.allBalances({ address: Bech32.decode(address).data }); + return balances.map(toObject); }, }, }, diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 9cf168f6..64e34451 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -204,7 +204,7 @@ export class StargateClient { * proofs from such a method. */ public async getAllBalancesUnverified(address: string): Promise { - const balances = await this.queryClient.bank.unverified.balances(address); + const balances = await this.queryClient.bank.unverified.allBalances(address); return balances.map(coinFromProto); } diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index 48cabf7d..6b62b2c4 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -4,7 +4,7 @@ export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; readonly unverified: { - readonly balances: (address: string) => Promise; + readonly allBalances: (address: string) => Promise; }; }; } From b222f49cab46b1752f669eede95c12ce0172c8be Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 11:39:25 +0200 Subject: [PATCH 09/17] Pull out toAccAddress/toObject --- packages/stargate/src/queries/bank.ts | 19 +++++-------------- packages/stargate/src/queries/index.ts | 1 + packages/stargate/src/queries/utils.ts | 19 +++++++++++++++++++ packages/stargate/src/stargateclient.ts | 2 +- packages/stargate/types/queries/index.d.ts | 1 + packages/stargate/types/queries/utils.d.ts | 11 +++++++++++ 6 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 packages/stargate/src/queries/index.ts create mode 100644 packages/stargate/src/queries/utils.ts create mode 100644 packages/stargate/types/queries/index.d.ts create mode 100644 packages/stargate/types/queries/utils.d.ts diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 2207f8e6..4266f288 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -1,16 +1,8 @@ -import { Bech32, toAscii } from "@cosmjs/encoding"; +import { toAscii } from "@cosmjs/encoding"; import { cosmos } from "../generated/codecimpl"; import { QueryClient } from "../queryclient"; - -/** - * Use this to convert a protobuf.js class to the interface (e.g. Coin to ICoin) - * in a ways that makes Jasmine's toEqual happy. - */ -// eslint-disable-next-line @typescript-eslint/ban-types -function toObject(thing: I): Omit { - return { ...thing }; -} +import { toAccAddress, toObject } from "./utils"; export interface BankExtension { readonly bank: { @@ -42,14 +34,13 @@ export function setupBankExtension(base: QueryClient): BankExtension { // it seem like prefix stores just do a dumb concat with the keys (no tricks to avoid overlap) // https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L61-L64 // https://github.com/cosmos/cosmos-sdk/blob/2879c0702c87dc9dd828a8c42b9224dc054e28ad/store/prefix/store.go#L37-L43 - const binAddress = Bech32.decode(address).data; - const bankKey = Uint8Array.from([...toAscii("balances"), ...binAddress, ...toAscii(denom)]); - const responseData = await base.queryVerified("bank", bankKey); + const key = Uint8Array.from([...toAscii("balances"), ...toAccAddress(address), ...toAscii(denom)]); + const responseData = await base.queryVerified("bank", key); return responseData.length ? toObject(cosmos.Coin.decode(responseData)) : null; }, unverified: { allBalances: async (address: string) => { - const { balances } = await queryService.allBalances({ address: Bech32.decode(address).data }); + const { balances } = await queryService.allBalances({ address: toAccAddress(address) }); return balances.map(toObject); }, }, diff --git a/packages/stargate/src/queries/index.ts b/packages/stargate/src/queries/index.ts new file mode 100644 index 00000000..07dc15ed --- /dev/null +++ b/packages/stargate/src/queries/index.ts @@ -0,0 +1 @@ +export { BankExtension, setupBankExtension } from "./bank"; diff --git a/packages/stargate/src/queries/utils.ts b/packages/stargate/src/queries/utils.ts new file mode 100644 index 00000000..0466765e --- /dev/null +++ b/packages/stargate/src/queries/utils.ts @@ -0,0 +1,19 @@ +import { Bech32 } from "@cosmjs/encoding"; + +/** + * Takes a bech32 encoded address and returns the data part. The prefix is ignored and discarded. + * This is called AccAddress in Cosmos SDK, which is basically an alias for raw binary data. + * The result is typically 20 bytes long but not restricted to that. + */ +export function toAccAddress(address: string): Uint8Array { + return Bech32.decode(address).data; +} + +/** + * Use this to convert a protobuf.js class to the interface (e.g. Coin to ICoin) + * in a ways that makes Jasmine's toEqual happy. + */ +// eslint-disable-next-line @typescript-eslint/ban-types +export function toObject(thing: I): Omit { + return { ...thing }; +} diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 64e34451..8d8d147b 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -17,7 +17,7 @@ import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; import { cosmos } from "./generated/codecimpl"; -import { BankExtension, setupBankExtension } from "./queries/bank"; +import { BankExtension, setupBankExtension } from "./queries"; import { QueryClient } from "./queryclient"; /** A transaction that is indexed as part of the transaction history */ diff --git a/packages/stargate/types/queries/index.d.ts b/packages/stargate/types/queries/index.d.ts new file mode 100644 index 00000000..07dc15ed --- /dev/null +++ b/packages/stargate/types/queries/index.d.ts @@ -0,0 +1 @@ +export { BankExtension, setupBankExtension } from "./bank"; diff --git a/packages/stargate/types/queries/utils.d.ts b/packages/stargate/types/queries/utils.d.ts new file mode 100644 index 00000000..3d99f5c2 --- /dev/null +++ b/packages/stargate/types/queries/utils.d.ts @@ -0,0 +1,11 @@ +/** + * Takes a bech32 encoded address and returns the data part. The prefix is ignored and discarded. + * This is called AccAddress in Cosmos SDK, which is basically an alias for raw binary data. + * The result is typically 20 bytes long but not restricted to that. + */ +export declare function toAccAddress(address: string): Uint8Array; +/** + * Use this to convert a protobuf.js class to the interface (e.g. Coin to ICoin) + * in a ways that makes Jasmine's toEqual happy. + */ +export declare function toObject(thing: I): Omit; From 71b07280428b26551cbf0ce476455b1eeccdebc6 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 11:43:53 +0200 Subject: [PATCH 10/17] Add unverified balance query --- packages/stargate/src/queries/bank.spec.ts | 74 +++++++++++++++++----- packages/stargate/src/queries/bank.ts | 7 ++ packages/stargate/types/queries/bank.d.ts | 1 + 3 files changed, 66 insertions(+), 16 deletions(-) diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index 14a0f6c5..323d6635 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -45,30 +45,72 @@ describe("BankExtension", () => { }); }); - describe("allBalances", () => { - it("returns all balances for unused account", async () => { - pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + describe("unverified", () => { + describe("balance", () => { + it("works for different existing balances", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); - const balances = await client.bank.unverified.allBalances(unused.address); - expect(balances).toEqual([ - { + const response1 = await client.bank.unverified.balance(unused.address, simapp.denomFee); + expect(response1).toEqual({ amount: unused.balanceFee, denom: simapp.denomFee, - }, - { + }); + const response2 = await client.bank.unverified.balance(unused.address, simapp.denomStaking); + expect(response2).toEqual({ amount: unused.balanceStaking, denom: simapp.denomStaking, - }, - ]); + }); + }); + + it("returns zero for non-existent balance", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.unverified.balance(unused.address, "gintonic"); + expect(response).toEqual({ + amount: "0", + denom: "gintonic", + }); + }); + + it("returns zero for non-existent address", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.unverified.balance(nonExistentAddress, simapp.denomFee); + expect(response).toEqual({ + amount: "0", + denom: simapp.denomFee, + }); + }); }); - it("returns an empty list for non-existent account", async () => { - pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + describe("allBalances", () => { + it("returns all balances for unused account", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); - const balances = await client.bank.unverified.allBalances(nonExistentAddress); - expect(balances).toEqual([]); + const balances = await client.bank.unverified.allBalances(unused.address); + expect(balances).toEqual([ + { + amount: unused.balanceFee, + denom: simapp.denomFee, + }, + { + amount: unused.balanceStaking, + denom: simapp.denomStaking, + }, + ]); + }); + + it("returns an empty list for non-existent account", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const balances = await client.bank.unverified.allBalances(nonExistentAddress); + expect(balances).toEqual([]); + }); }); }); }); diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 4266f288..3d6b1092 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -1,4 +1,5 @@ import { toAscii } from "@cosmjs/encoding"; +import { assert } from "@cosmjs/utils"; import { cosmos } from "../generated/codecimpl"; import { QueryClient } from "../queryclient"; @@ -8,6 +9,7 @@ export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; readonly unverified: { + readonly balance: (address: string, denom: string) => Promise; readonly allBalances: (address: string) => Promise; }; }; @@ -39,6 +41,11 @@ export function setupBankExtension(base: QueryClient): BankExtension { return responseData.length ? toObject(cosmos.Coin.decode(responseData)) : null; }, unverified: { + balance: async (address: string, denom: string) => { + const { balance } = await queryService.balance({ address: toAccAddress(address), denom: denom }); + assert(balance); + return toObject(balance); + }, allBalances: async (address: string) => { const { balances } = await queryService.allBalances({ address: toAccAddress(address) }); return balances.map(toObject); diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index 6b62b2c4..e9311a92 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -4,6 +4,7 @@ export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; readonly unverified: { + readonly balance: (address: string, denom: string) => Promise; readonly allBalances: (address: string) => Promise; }; }; From 894084a433c0a1f3a4849ce34faf285c04c7a9a6 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 11:51:56 +0200 Subject: [PATCH 11/17] Add totalSupply query --- packages/stargate/src/queries/bank.spec.ts | 27 +++++++++++++++++++++- packages/stargate/src/queries/bank.ts | 5 ++++ packages/stargate/src/testutils.spec.ts | 1 + packages/stargate/types/queries/bank.d.ts | 1 + 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index 323d6635..3761d892 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -1,7 +1,13 @@ import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { QueryClient } from "../queryclient"; -import { nonExistentAddress, pendingWithoutSimapp, simapp, unused } from "../testutils.spec"; +import { + nonExistentAddress, + nonNegativeIntegerMatcher, + pendingWithoutSimapp, + simapp, + unused, +} from "../testutils.spec"; import { BankExtension, setupBankExtension } from "./bank"; async function makeBankClient(rpcUrl: string): Promise { @@ -112,5 +118,24 @@ describe("BankExtension", () => { expect(balances).toEqual([]); }); }); + + describe("totalSupply", () => { + it("works", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.unverified.totalSupply(); + expect(response).toEqual([ + { + amount: "18000000000", + denom: simapp.denomFee, + }, + { + amount: jasmine.stringMatching(nonNegativeIntegerMatcher), + denom: simapp.denomStaking, + }, + ]); + }); + }); }); }); diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 3d6b1092..33824098 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -11,6 +11,7 @@ export interface BankExtension { readonly unverified: { readonly balance: (address: string, denom: string) => Promise; readonly allBalances: (address: string) => Promise; + readonly totalSupply: () => Promise; }; }; } @@ -50,6 +51,10 @@ export function setupBankExtension(base: QueryClient): BankExtension { const { balances } = await queryService.allBalances({ address: toAccAddress(address) }); return balances.map(toObject); }, + totalSupply: async () => { + const { supply } = await queryService.totalSupply({}); + return supply.map(toObject); + }, }, }, }; diff --git a/packages/stargate/src/testutils.spec.ts b/packages/stargate/src/testutils.spec.ts index 25d985b9..4bfbfafa 100644 --- a/packages/stargate/src/testutils.spec.ts +++ b/packages/stargate/src/testutils.spec.ts @@ -64,4 +64,5 @@ export const validator = { export const nonExistentAddress = "cosmos1p79apjaufyphcmsn4g07cynqf0wyjuezqu84hd"; +export const nonNegativeIntegerMatcher = /^[0-9]+$/; export const tendermintIdMatcher = /^[0-9A-F]{64}$/; diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index e9311a92..83db8a76 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -6,6 +6,7 @@ export interface BankExtension { readonly unverified: { readonly balance: (address: string, denom: string) => Promise; readonly allBalances: (address: string) => Promise; + readonly totalSupply: () => Promise; }; }; } From 0c5f72a55fc45a3481d5b3bbc66bafcff864d0cb Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 11:56:42 +0200 Subject: [PATCH 12/17] Add supplyOf query --- packages/stargate/src/queries/bank.spec.ts | 24 ++++++++++++++++++++++ packages/stargate/src/queries/bank.ts | 6 ++++++ packages/stargate/types/queries/bank.d.ts | 1 + 3 files changed, 31 insertions(+) diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index 3761d892..89831469 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -137,5 +137,29 @@ describe("BankExtension", () => { ]); }); }); + + describe("supplyOf", () => { + it("works for existing denom", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.unverified.supplyOf(simapp.denomFee); + expect(response).toEqual({ + amount: "18000000000", + denom: simapp.denomFee, + }); + }); + + it("returns zero for non-existent denom", async () => { + pendingWithoutSimapp(); + const client = await makeBankClient(simapp.tendermintUrl); + + const response = await client.bank.unverified.supplyOf("gintonic"); + expect(response).toEqual({ + amount: "0", + denom: "gintonic", + }); + }); + }); }); }); diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 33824098..a4b66ba6 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -12,6 +12,7 @@ export interface BankExtension { readonly balance: (address: string, denom: string) => Promise; readonly allBalances: (address: string) => Promise; readonly totalSupply: () => Promise; + readonly supplyOf: (denom: string) => Promise; }; }; } @@ -55,6 +56,11 @@ export function setupBankExtension(base: QueryClient): BankExtension { const { supply } = await queryService.totalSupply({}); return supply.map(toObject); }, + supplyOf: async (denom: string) => { + const { amount } = await queryService.supplyOf({ denom: denom }); + assert(amount); + return toObject(amount); + }, }, }, }; diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index 83db8a76..4cb53485 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -7,6 +7,7 @@ export interface BankExtension { readonly balance: (address: string, denom: string) => Promise; readonly allBalances: (address: string) => Promise; readonly totalSupply: () => Promise; + readonly supplyOf: (denom: string) => Promise; }; }; } From 5ccc71c261d29a6e9d274669d1e7db30f7d8c39d Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 11:59:08 +0200 Subject: [PATCH 13/17] Move QueryClient into subfolder --- packages/stargate/src/queries/bank.spec.ts | 2 +- packages/stargate/src/queries/bank.ts | 2 +- packages/stargate/src/queries/index.ts | 6 ++++++ packages/stargate/src/{ => queries}/queryclient.ts | 0 packages/stargate/src/stargateclient.ts | 3 +-- packages/stargate/types/queries/bank.d.ts | 2 +- packages/stargate/types/queries/index.d.ts | 1 + packages/stargate/types/{ => queries}/queryclient.d.ts | 0 8 files changed, 11 insertions(+), 5 deletions(-) rename packages/stargate/src/{ => queries}/queryclient.ts (100%) rename packages/stargate/types/{ => queries}/queryclient.d.ts (100%) diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index 89831469..7f7d7a11 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -1,6 +1,5 @@ import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; -import { QueryClient } from "../queryclient"; import { nonExistentAddress, nonNegativeIntegerMatcher, @@ -9,6 +8,7 @@ import { unused, } from "../testutils.spec"; import { BankExtension, setupBankExtension } from "./bank"; +import { QueryClient } from "./queryclient"; async function makeBankClient(rpcUrl: string): Promise { // TODO: tmClient is not owned by QueryClient but should be disconnected somehow (once we use WebSockets) diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index a4b66ba6..6f6c3a93 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -2,7 +2,7 @@ import { toAscii } from "@cosmjs/encoding"; import { assert } from "@cosmjs/utils"; import { cosmos } from "../generated/codecimpl"; -import { QueryClient } from "../queryclient"; +import { QueryClient } from "./queryclient"; import { toAccAddress, toObject } from "./utils"; export interface BankExtension { diff --git a/packages/stargate/src/queries/index.ts b/packages/stargate/src/queries/index.ts index 07dc15ed..854d741c 100644 --- a/packages/stargate/src/queries/index.ts +++ b/packages/stargate/src/queries/index.ts @@ -1 +1,7 @@ +// Base symbols + +export { QueryClient } from "./queryclient"; + +// Extensions + export { BankExtension, setupBankExtension } from "./bank"; diff --git a/packages/stargate/src/queryclient.ts b/packages/stargate/src/queries/queryclient.ts similarity index 100% rename from packages/stargate/src/queryclient.ts rename to packages/stargate/src/queries/queryclient.ts diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 8d8d147b..93970323 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -17,8 +17,7 @@ import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; import { cosmos } from "./generated/codecimpl"; -import { BankExtension, setupBankExtension } from "./queries"; -import { QueryClient } from "./queryclient"; +import { BankExtension, QueryClient, setupBankExtension } from "./queries"; /** A transaction that is indexed as part of the transaction history */ export interface IndexedTx { diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index 4cb53485..5e02551c 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -1,5 +1,5 @@ import { cosmos } from "../generated/codecimpl"; -import { QueryClient } from "../queryclient"; +import { QueryClient } from "./queryclient"; export interface BankExtension { readonly bank: { readonly balance: (address: string, denom: string) => Promise; diff --git a/packages/stargate/types/queries/index.d.ts b/packages/stargate/types/queries/index.d.ts index 07dc15ed..1e80a28e 100644 --- a/packages/stargate/types/queries/index.d.ts +++ b/packages/stargate/types/queries/index.d.ts @@ -1 +1,2 @@ +export { QueryClient } from "./queryclient"; export { BankExtension, setupBankExtension } from "./bank"; diff --git a/packages/stargate/types/queryclient.d.ts b/packages/stargate/types/queries/queryclient.d.ts similarity index 100% rename from packages/stargate/types/queryclient.d.ts rename to packages/stargate/types/queries/queryclient.d.ts From 4003f5eb6502b11714b9d0cefeb885d0bf1d3589 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 13:45:31 +0200 Subject: [PATCH 14/17] Create AuthExtension --- packages/stargate/src/queries/auth.spec.ts | 96 ++++++++++++++++++++++ packages/stargate/src/queries/auth.ts | 60 ++++++++++++++ packages/stargate/src/queries/index.ts | 1 + packages/stargate/types/queries/auth.d.ts | 11 +++ packages/stargate/types/queries/index.d.ts | 1 + 5 files changed, 169 insertions(+) create mode 100644 packages/stargate/src/queries/auth.spec.ts create mode 100644 packages/stargate/src/queries/auth.ts create mode 100644 packages/stargate/types/queries/auth.d.ts diff --git a/packages/stargate/src/queries/auth.spec.ts b/packages/stargate/src/queries/auth.spec.ts new file mode 100644 index 00000000..4befcb65 --- /dev/null +++ b/packages/stargate/src/queries/auth.spec.ts @@ -0,0 +1,96 @@ +import { encodeAminoPubkey } from "@cosmjs/launchpad"; +import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { assert } from "@cosmjs/utils"; +import Long from "long"; + +import { nonExistentAddress, pendingWithoutSimapp, simapp, unused, validator } from "../testutils.spec"; +import { AuthExtension, setupAuthExtension } from "./auth"; +import { QueryClient } from "./queryclient"; +import { toAccAddress } from "./utils"; + +async function makeAuthClient(rpcUrl: string): Promise { + // TODO: tmClient is not owned by QueryClient but should be disconnected somehow (once we use WebSockets) + const tmClient = await TendermintClient.connect(rpcUrl); + return QueryClient.withExtensions(tmClient, setupAuthExtension); +} + +describe("AuthExtension", () => { + describe("account", () => { + it("works for unused account", async () => { + pendingWithoutSimapp(); + const client = await makeAuthClient(simapp.tendermintUrl); + + const account = await client.auth.account(unused.address); + assert(account); + expect(account).toEqual({ + address: toAccAddress(unused.address), + // pubKey not set + accountNumber: Long.fromNumber(unused.accountNumber, true), + // sequence not set + }); + }); + + it("works for account with pubkey and non-zero sequence", async () => { + pendingWithoutSimapp(); + const client = await makeAuthClient(simapp.tendermintUrl); + + const account = await client.auth.account(validator.address); + assert(account); + expect(account).toEqual({ + address: toAccAddress(validator.address), + pubKey: encodeAminoPubkey(validator.pubkey), + // accountNumber not set + sequence: Long.fromNumber(validator.sequence, true), + }); + }); + + it("returns null for non-existent address", async () => { + pendingWithoutSimapp(); + const client = await makeAuthClient(simapp.tendermintUrl); + + const account = await client.auth.account(nonExistentAddress); + expect(account).toBeNull(); + }); + }); + + describe("unverified", () => { + describe("account", () => { + it("works for unused account", async () => { + pendingWithoutSimapp(); + const client = await makeAuthClient(simapp.tendermintUrl); + + const account = await client.auth.unverified.account(unused.address); + assert(account); + expect(account).toEqual({ + address: toAccAddress(unused.address), + // pubKey not set + accountNumber: Long.fromNumber(unused.accountNumber, true), + // sequence not set + }); + }); + + it("works for account with pubkey and non-zero sequence", async () => { + pendingWithoutSimapp(); + const client = await makeAuthClient(simapp.tendermintUrl); + + const account = await client.auth.unverified.account(validator.address); + assert(account); + expect(account).toEqual({ + address: toAccAddress(validator.address), + pubKey: encodeAminoPubkey(validator.pubkey), + // accountNumber not set + sequence: Long.fromNumber(validator.sequence, true), + }); + }); + + it("returns null for non-existent address", async () => { + pending("This fails with Error: Query failed with (1): internal"); + pendingWithoutSimapp(); + const client = await makeAuthClient(simapp.tendermintUrl); + + const account = await client.auth.unverified.account(nonExistentAddress); + expect(account).toBeNull(); + }); + }); + }); +}); diff --git a/packages/stargate/src/queries/auth.ts b/packages/stargate/src/queries/auth.ts new file mode 100644 index 00000000..fbc4c470 --- /dev/null +++ b/packages/stargate/src/queries/auth.ts @@ -0,0 +1,60 @@ +import { assert } from "@cosmjs/utils"; + +import { cosmos, google } from "../generated/codecimpl"; +import { QueryClient } from "./queryclient"; +import { toAccAddress, toObject } from "./utils"; + +export interface AuthExtension { + readonly auth: { + readonly account: (address: string) => Promise; + readonly unverified: { + readonly account: (address: string) => Promise; + }; + }; +} + +export function setupAuthExtension(base: QueryClient): AuthExtension { + // Use this service to get easy typed access to query methods + // This cannot be used to for proof verification + const queryService = cosmos.auth.Query.create((method: any, requestData, callback) => { + // Parts of the path are unavailable, so we hardcode them here. See https://github.com/protobufjs/protobuf.js/issues/1229 + const path = `/cosmos.auth.Query/${method.name}`; + base + .queryUnverified(path, requestData) + .then((response) => callback(null, response)) + .catch((error) => callback(error)); + }); + + return { + auth: { + account: async (address: string) => { + // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L29-L32 + const key = Uint8Array.from([0x01, ...toAccAddress(address)]); + const responseData = await base.queryVerified("acc", key); + if (responseData.length === 0) return null; + const account = google.protobuf.Any.decode(responseData); + switch (account.type_url) { + case "/cosmos.auth.BaseAccount": { + return toObject(cosmos.auth.BaseAccount.decode(account.value)); + } + default: + throw new Error(`Unsupported type: '${account.type_url}'`); + } + }, + unverified: { + account: async (address: string) => { + const { account } = await queryService.account({ address: toAccAddress(address) }); + if (!account) return null; + switch (account.type_url) { + case "/cosmos.auth.BaseAccount": { + assert(account.value); + return toObject(cosmos.auth.BaseAccount.decode(account.value)); + } + default: + throw new Error(`Unsupported type: '${account.type_url}'`); + } + }, + }, + }, + }; +} diff --git a/packages/stargate/src/queries/index.ts b/packages/stargate/src/queries/index.ts index 854d741c..afcfb022 100644 --- a/packages/stargate/src/queries/index.ts +++ b/packages/stargate/src/queries/index.ts @@ -4,4 +4,5 @@ export { QueryClient } from "./queryclient"; // Extensions +export { AuthExtension, setupAuthExtension } from "./auth"; export { BankExtension, setupBankExtension } from "./bank"; diff --git a/packages/stargate/types/queries/auth.d.ts b/packages/stargate/types/queries/auth.d.ts new file mode 100644 index 00000000..db6bcb4f --- /dev/null +++ b/packages/stargate/types/queries/auth.d.ts @@ -0,0 +1,11 @@ +import { cosmos } from "../generated/codecimpl"; +import { QueryClient } from "./queryclient"; +export interface AuthExtension { + readonly auth: { + readonly account: (address: string) => Promise; + readonly unverified: { + readonly account: (address: string) => Promise; + }; + }; +} +export declare function setupAuthExtension(base: QueryClient): AuthExtension; diff --git a/packages/stargate/types/queries/index.d.ts b/packages/stargate/types/queries/index.d.ts index 1e80a28e..3aacc3e3 100644 --- a/packages/stargate/types/queries/index.d.ts +++ b/packages/stargate/types/queries/index.d.ts @@ -1,2 +1,3 @@ export { QueryClient } from "./queryclient"; +export { AuthExtension, setupAuthExtension } from "./auth"; export { BankExtension, setupBankExtension } from "./bank"; From 98b81f8fa8ba18a629b3bcea1ecb1b45b3a55c67 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 15:31:19 +0200 Subject: [PATCH 15/17] Use AuthExtension in StargateClient --- packages/proto-signing/src/any.ts | 13 ---------- packages/proto-signing/src/index.ts | 1 - packages/proto-signing/types/any.d.ts | 10 -------- packages/proto-signing/types/index.d.ts | 1 - packages/stargate/src/stargateclient.ts | 34 +++++++++---------------- 5 files changed, 12 insertions(+), 47 deletions(-) delete mode 100644 packages/proto-signing/src/any.ts delete mode 100644 packages/proto-signing/types/any.d.ts diff --git a/packages/proto-signing/src/any.ts b/packages/proto-signing/src/any.ts deleted file mode 100644 index 27a49698..00000000 --- a/packages/proto-signing/src/any.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { google } from "./generated/codecimpl"; - -/** - * Decodes a serialized [google.protobuf.Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto) - * and returns the components. - */ -export function decodeAny(serialized: Uint8Array): { readonly typeUrl: string; readonly value: Uint8Array } { - const envelope = google.protobuf.Any.decode(serialized); - return { - typeUrl: envelope.type_url, - value: envelope.value, - }; -} diff --git a/packages/proto-signing/src/index.ts b/packages/proto-signing/src/index.ts index ce95215d..114a1bd7 100644 --- a/packages/proto-signing/src/index.ts +++ b/packages/proto-signing/src/index.ts @@ -1,5 +1,4 @@ export { omitDefaults } from "./adr27"; -export { decodeAny } from "./any"; export { Coin } from "./msgs"; export { cosmosField } from "./decorator"; export { Registry } from "./registry"; diff --git a/packages/proto-signing/types/any.d.ts b/packages/proto-signing/types/any.d.ts deleted file mode 100644 index c76a6b15..00000000 --- a/packages/proto-signing/types/any.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Decodes a serialized [google.protobuf.Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto) - * and returns the components. - */ -export declare function decodeAny( - serialized: Uint8Array, -): { - readonly typeUrl: string; - readonly value: Uint8Array; -}; diff --git a/packages/proto-signing/types/index.d.ts b/packages/proto-signing/types/index.d.ts index ce95215d..114a1bd7 100644 --- a/packages/proto-signing/types/index.d.ts +++ b/packages/proto-signing/types/index.d.ts @@ -1,5 +1,4 @@ export { omitDefaults } from "./adr27"; -export { decodeAny } from "./any"; export { Coin } from "./msgs"; export { cosmosField } from "./decorator"; export { Registry } from "./registry"; diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 93970323..03a89048 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -11,13 +11,12 @@ import { SearchTxQuery, } from "@cosmjs/launchpad"; import { Uint53, Uint64 } from "@cosmjs/math"; -import { decodeAny } from "@cosmjs/proto-signing"; import { broadcastTxCommitSuccess, Client as TendermintClient, QueryString } from "@cosmjs/tendermint-rpc"; import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; import { cosmos } from "./generated/codecimpl"; -import { BankExtension, QueryClient, setupBankExtension } from "./queries"; +import { AuthExtension, BankExtension, QueryClient, setupAuthExtension, setupBankExtension } from "./queries"; /** A transaction that is indexed as part of the transaction history */ export interface IndexedTx { @@ -81,14 +80,16 @@ export function assertIsBroadcastTxSuccess( } } -function uint64FromProto(input: number | Long): Uint64 { +function uint64FromProto(input: number | Long | null | undefined): Uint64 { + if (!input) return Uint64.fromNumber(0); return Uint64.fromString(input.toString()); } -function decodeBaseAccount(data: Uint8Array, prefix: string): Account { - const { address, pubKey, accountNumber, sequence } = cosmos.auth.BaseAccount.decode(data); +function accountFromProto(input: cosmos.auth.IBaseAccount, prefix: string): Account { + const { address, pubKey, accountNumber, sequence } = input; // Pubkey is still Amino-encoded in BaseAccount (https://github.com/cosmos/cosmos-sdk/issues/6886) - const pubkey = pubKey.length ? decodeAminoPubkey(pubKey) : null; + const pubkey = pubKey && pubKey.length ? decodeAminoPubkey(pubKey) : null; + assert(address); return { address: Bech32.encode(prefix, address), pubkey: pubkey, @@ -115,7 +116,7 @@ export interface PrivateStargateClient { export class StargateClient { private readonly tmClient: TendermintClient; - private readonly queryClient: QueryClient & BankExtension; + private readonly queryClient: QueryClient & AuthExtension & BankExtension; private chainId: string | undefined; public static async connect(endpoint: string): Promise { @@ -125,7 +126,7 @@ export class StargateClient { private constructor(tmClient: TendermintClient) { this.tmClient = tmClient; - this.queryClient = QueryClient.withExtensions(tmClient, setupBankExtension); + this.queryClient = QueryClient.withExtensions(tmClient, setupAuthExtension, setupBankExtension); } public async getChainId(): Promise { @@ -145,21 +146,10 @@ export class StargateClient { } public async getAccount(searchAddress: string): Promise { - const { prefix, data: binAddress } = Bech32.decode(searchAddress); - // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L29-L32 - const accountKey = Uint8Array.from([0x01, ...binAddress]); - const responseData = await this.queryClient.queryVerified("acc", accountKey); + const { prefix } = Bech32.decode(searchAddress); - if (responseData.length === 0) return null; - - const { typeUrl, value } = decodeAny(responseData); - switch (typeUrl) { - case "/cosmos.auth.BaseAccount": { - return decodeBaseAccount(value, prefix); - } - default: - throw new Error(`Unsupported type: '${typeUrl}'`); - } + const account = await this.queryClient.auth.account(searchAddress); + return account ? accountFromProto(account, prefix) : null; } public async getSequence(address: string): Promise { From 7c1c3d6f3a0588b889e90f37b84e56a2f4103c1c Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 15:40:01 +0200 Subject: [PATCH 16/17] Ensure Long is always set correctly --- packages/stargate/package.json | 4 +- packages/stargate/scripts/predefine-proto.sh | 1 + .../src/{ => codec}/generated/codecimpl.d.ts | 176 +++++++++--------- .../src/{ => codec}/generated/codecimpl.js | 0 packages/stargate/src/codec/index.ts | 9 + packages/stargate/src/queries/auth.spec.ts | 1 + packages/stargate/src/queries/auth.ts | 2 +- packages/stargate/src/queries/bank.ts | 2 +- .../src/stargateclient.searchtx.spec.ts | 5 +- packages/stargate/src/stargateclient.spec.ts | 5 +- packages/stargate/src/stargateclient.ts | 2 +- .../{ => codec}/generated/codecimpl.d.ts | 176 +++++++++--------- packages/stargate/types/codec/index.d.ts | 1 + packages/stargate/types/queries/auth.d.ts | 2 +- packages/stargate/types/queries/bank.d.ts | 2 +- 15 files changed, 201 insertions(+), 187 deletions(-) rename packages/stargate/src/{ => codec}/generated/codecimpl.d.ts (98%) rename packages/stargate/src/{ => codec}/generated/codecimpl.js (100%) create mode 100644 packages/stargate/src/codec/index.ts rename packages/stargate/types/{ => codec}/generated/codecimpl.d.ts (98%) create mode 100644 packages/stargate/types/codec/index.d.ts diff --git a/packages/stargate/package.json b/packages/stargate/package.json index 26ed5950..d5ae9cf2 100644 --- a/packages/stargate/package.json +++ b/packages/stargate/package.json @@ -29,8 +29,8 @@ "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", - "build": "tsc && shx mkdir -p build/generated && shx cp ./src/generated/*.js ./build/generated && shx mkdir -p ./build/types/generated && shx cp ./src/generated/*.d.ts ./build/types/generated", - "postbuild": "yarn move-types && yarn format-types", + "build": "tsc && shx mkdir -p build/codec/generated && shx cp ./src/codec/generated/*.js ./build/codec/generated", + "postbuild": "shx mkdir -p ./build/types/codec/generated && shx cp ./src/codec/generated/*.d.ts ./build/types/codec/generated && yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", "test-node": "node jasmine-testrunner.js", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", diff --git a/packages/stargate/scripts/predefine-proto.sh b/packages/stargate/scripts/predefine-proto.sh index 86a1a8de..3bc39794 100755 --- a/packages/stargate/scripts/predefine-proto.sh +++ b/packages/stargate/scripts/predefine-proto.sh @@ -19,6 +19,7 @@ yarn pbjs \ --no-delimited \ --no-verify \ --no-convert \ + --force-long \ "$COSMOS_PROTO_DIR/cosmos.proto" \ "$COSMOS_PROTO_DIR/auth/{auth,query}.proto" \ "$COSMOS_PROTO_DIR/bank/{bank,query}.proto" \ diff --git a/packages/stargate/src/generated/codecimpl.d.ts b/packages/stargate/src/codec/generated/codecimpl.d.ts similarity index 98% rename from packages/stargate/src/generated/codecimpl.d.ts rename to packages/stargate/src/codec/generated/codecimpl.d.ts index 627c179e..43c0b29b 100644 --- a/packages/stargate/src/generated/codecimpl.d.ts +++ b/packages/stargate/src/codec/generated/codecimpl.d.ts @@ -231,10 +231,10 @@ export namespace cosmos { /** Properties of a GasInfo. */ interface IGasInfo { /** GasInfo gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** GasInfo gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; } /** Represents a GasInfo. */ @@ -246,10 +246,10 @@ export namespace cosmos { constructor(p?: cosmos.IGasInfo); /** GasInfo gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** GasInfo gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** * Creates a new GasInfo instance using the specified properties. @@ -476,7 +476,7 @@ export namespace cosmos { /** Properties of a TxResponse. */ interface ITxResponse { /** TxResponse height */ - height?: number | Long | null; + height?: Long | null; /** TxResponse txhash */ txhash?: string | null; @@ -500,10 +500,10 @@ export namespace cosmos { info?: string | null; /** TxResponse gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** TxResponse gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; /** TxResponse tx */ tx?: google.protobuf.IAny | null; @@ -521,7 +521,7 @@ export namespace cosmos { constructor(p?: cosmos.ITxResponse); /** TxResponse height. */ - public height: number | Long; + public height: Long; /** TxResponse txhash. */ public txhash: string; @@ -545,10 +545,10 @@ export namespace cosmos { public info: string; /** TxResponse gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** TxResponse gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** TxResponse tx. */ public tx?: google.protobuf.IAny | null; @@ -746,10 +746,10 @@ export namespace cosmos { pubKey?: Uint8Array | null; /** BaseAccount accountNumber */ - accountNumber?: number | Long | null; + accountNumber?: Long | null; /** BaseAccount sequence */ - sequence?: number | Long | null; + sequence?: Long | null; } /** Represents a BaseAccount. */ @@ -767,10 +767,10 @@ export namespace cosmos { public pubKey: Uint8Array; /** BaseAccount accountNumber. */ - public accountNumber: number | Long; + public accountNumber: Long; /** BaseAccount sequence. */ - public sequence: number | Long; + public sequence: Long; /** * Creates a new BaseAccount instance using the specified properties. @@ -856,19 +856,19 @@ export namespace cosmos { /** Properties of a Params. */ interface IParams { /** Params maxMemoCharacters */ - maxMemoCharacters?: number | Long | null; + maxMemoCharacters?: Long | null; /** Params txSigLimit */ - txSigLimit?: number | Long | null; + txSigLimit?: Long | null; /** Params txSizeCostPerByte */ - txSizeCostPerByte?: number | Long | null; + txSizeCostPerByte?: Long | null; /** Params sigVerifyCostEd25519 */ - sigVerifyCostEd25519?: number | Long | null; + sigVerifyCostEd25519?: Long | null; /** Params sigVerifyCostSecp256k1 */ - sigVerifyCostSecp256k1?: number | Long | null; + sigVerifyCostSecp256k1?: Long | null; } /** Represents a Params. */ @@ -880,19 +880,19 @@ export namespace cosmos { constructor(p?: cosmos.auth.IParams); /** Params maxMemoCharacters. */ - public maxMemoCharacters: number | Long; + public maxMemoCharacters: Long; /** Params txSigLimit. */ - public txSigLimit: number | Long; + public txSigLimit: Long; /** Params txSizeCostPerByte. */ - public txSizeCostPerByte: number | Long; + public txSizeCostPerByte: Long; /** Params sigVerifyCostEd25519. */ - public sigVerifyCostEd25519: number | Long; + public sigVerifyCostEd25519: Long; /** Params sigVerifyCostSecp256k1. */ - public sigVerifyCostSecp256k1: number | Long; + public sigVerifyCostSecp256k1: Long; /** * Creates a new Params instance using the specified properties. @@ -2360,10 +2360,10 @@ export namespace cosmos { key?: Uint8Array | null; /** PageRequest offset */ - offset?: number | Long | null; + offset?: Long | null; /** PageRequest limit */ - limit?: number | Long | null; + limit?: Long | null; /** PageRequest countTotal */ countTotal?: boolean | null; @@ -2381,10 +2381,10 @@ export namespace cosmos { public key: Uint8Array; /** PageRequest offset. */ - public offset: number | Long; + public offset: Long; /** PageRequest limit. */ - public limit: number | Long; + public limit: Long; /** PageRequest countTotal. */ public countTotal: boolean; @@ -2421,7 +2421,7 @@ export namespace cosmos { nextKey?: Uint8Array | null; /** PageResponse total */ - total?: number | Long | null; + total?: Long | null; } /** Represents a PageResponse. */ @@ -2436,7 +2436,7 @@ export namespace cosmos { public nextKey: Uint8Array; /** PageResponse total. */ - public total: number | Long; + public total: Long; /** * Creates a new PageResponse instance using the specified properties. @@ -2589,10 +2589,10 @@ export namespace cosmos { chainId?: string | null; /** SignDoc accountNumber */ - accountNumber?: number | Long | null; + accountNumber?: Long | null; /** SignDoc accountSequence */ - accountSequence?: number | Long | null; + accountSequence?: Long | null; } /** Represents a SignDoc. */ @@ -2613,10 +2613,10 @@ export namespace cosmos { public chainId: string; /** SignDoc accountNumber. */ - public accountNumber: number | Long; + public accountNumber: Long; /** SignDoc accountSequence. */ - public accountSequence: number | Long; + public accountSequence: Long; /** * Creates a new SignDoc instance using the specified properties. @@ -2653,7 +2653,7 @@ export namespace cosmos { memo?: string | null; /** TxBody timeoutHeight */ - timeoutHeight?: number | Long | null; + timeoutHeight?: Long | null; /** TxBody extensionOptions */ extensionOptions?: google.protobuf.IAny[] | null; @@ -2677,7 +2677,7 @@ export namespace cosmos { public memo: string; /** TxBody timeoutHeight. */ - public timeoutHeight: number | Long; + public timeoutHeight: Long; /** TxBody extensionOptions. */ public extensionOptions: google.protobuf.IAny[]; @@ -2961,7 +2961,7 @@ export namespace cosmos { amount?: cosmos.ICoin[] | null; /** Fee gasLimit */ - gasLimit?: number | Long | null; + gasLimit?: Long | null; } /** Represents a Fee. */ @@ -2976,7 +2976,7 @@ export namespace cosmos { public amount: cosmos.ICoin[]; /** Fee gasLimit. */ - public gasLimit: number | Long; + public gasLimit: Long; /** * Creates a new Fee instance using the specified properties. @@ -3519,10 +3519,10 @@ export namespace tendermint { version?: string | null; /** RequestInfo blockVersion */ - blockVersion?: number | Long | null; + blockVersion?: Long | null; /** RequestInfo p2pVersion */ - p2pVersion?: number | Long | null; + p2pVersion?: Long | null; } /** Represents a RequestInfo. */ @@ -3537,10 +3537,10 @@ export namespace tendermint { public version: string; /** RequestInfo blockVersion. */ - public blockVersion: number | Long; + public blockVersion: Long; /** RequestInfo p2pVersion. */ - public p2pVersion: number | Long; + public p2pVersion: Long; /** * Creates a new RequestInfo instance using the specified properties. @@ -3711,7 +3711,7 @@ export namespace tendermint { path?: string | null; /** RequestQuery height */ - height?: number | Long | null; + height?: Long | null; /** RequestQuery prove */ prove?: boolean | null; @@ -3732,7 +3732,7 @@ export namespace tendermint { public path: string; /** RequestQuery height. */ - public height: number | Long; + public height: Long; /** RequestQuery prove. */ public prove: boolean; @@ -3954,7 +3954,7 @@ export namespace tendermint { /** Properties of a RequestEndBlock. */ interface IRequestEndBlock { /** RequestEndBlock height */ - height?: number | Long | null; + height?: Long | null; } /** Represents a RequestEndBlock. */ @@ -3966,7 +3966,7 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IRequestEndBlock); /** RequestEndBlock height. */ - public height: number | Long; + public height: Long; /** * Creates a new RequestEndBlock instance using the specified properties. @@ -4318,10 +4318,10 @@ export namespace tendermint { version?: string | null; /** ResponseInfo appVersion */ - appVersion?: number | Long | null; + appVersion?: Long | null; /** ResponseInfo lastBlockHeight */ - lastBlockHeight?: number | Long | null; + lastBlockHeight?: Long | null; /** ResponseInfo lastBlockAppHash */ lastBlockAppHash?: Uint8Array | null; @@ -4342,10 +4342,10 @@ export namespace tendermint { public version: string; /** ResponseInfo appVersion. */ - public appVersion: number | Long; + public appVersion: Long; /** ResponseInfo lastBlockHeight. */ - public lastBlockHeight: number | Long; + public lastBlockHeight: Long; /** ResponseInfo lastBlockAppHash. */ public lastBlockAppHash: Uint8Array; @@ -4513,7 +4513,7 @@ export namespace tendermint { info?: string | null; /** ResponseQuery index */ - index?: number | Long | null; + index?: Long | null; /** ResponseQuery key */ key?: Uint8Array | null; @@ -4525,7 +4525,7 @@ export namespace tendermint { proof?: tendermint.crypto.merkle.IProof | null; /** ResponseQuery height */ - height?: number | Long | null; + height?: Long | null; /** ResponseQuery codespace */ codespace?: string | null; @@ -4549,7 +4549,7 @@ export namespace tendermint { public info: string; /** ResponseQuery index. */ - public index: number | Long; + public index: Long; /** ResponseQuery key. */ public key: Uint8Array; @@ -4561,7 +4561,7 @@ export namespace tendermint { public proof?: tendermint.crypto.merkle.IProof | null; /** ResponseQuery height. */ - public height: number | Long; + public height: Long; /** ResponseQuery codespace. */ public codespace: string; @@ -4663,10 +4663,10 @@ export namespace tendermint { info?: string | null; /** ResponseCheckTx gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** ResponseCheckTx gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; /** ResponseCheckTx events */ events?: tendermint.abci.types.IEvent[] | null; @@ -4696,10 +4696,10 @@ export namespace tendermint { public info: string; /** ResponseCheckTx gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** ResponseCheckTx gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** ResponseCheckTx events. */ public events: tendermint.abci.types.IEvent[]; @@ -4756,10 +4756,10 @@ export namespace tendermint { info?: string | null; /** ResponseDeliverTx gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** ResponseDeliverTx gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; /** ResponseDeliverTx events */ events?: tendermint.abci.types.IEvent[] | null; @@ -4789,10 +4789,10 @@ export namespace tendermint { public info: string; /** ResponseDeliverTx gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** ResponseDeliverTx gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** ResponseDeliverTx events. */ public events: tendermint.abci.types.IEvent[]; @@ -5014,10 +5014,10 @@ export namespace tendermint { /** Properties of a BlockParams. */ interface IBlockParams { /** BlockParams maxBytes */ - maxBytes?: number | Long | null; + maxBytes?: Long | null; /** BlockParams maxGas */ - maxGas?: number | Long | null; + maxGas?: Long | null; } /** Represents a BlockParams. */ @@ -5029,10 +5029,10 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IBlockParams); /** BlockParams maxBytes. */ - public maxBytes: number | Long; + public maxBytes: Long; /** BlockParams maxGas. */ - public maxGas: number | Long; + public maxGas: Long; /** * Creates a new BlockParams instance using the specified properties. @@ -5065,7 +5065,7 @@ export namespace tendermint { /** Properties of an EvidenceParams. */ interface IEvidenceParams { /** EvidenceParams maxAgeNumBlocks */ - maxAgeNumBlocks?: number | Long | null; + maxAgeNumBlocks?: Long | null; /** EvidenceParams maxAgeDuration */ maxAgeDuration?: google.protobuf.IDuration | null; @@ -5080,7 +5080,7 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IEvidenceParams); /** EvidenceParams maxAgeNumBlocks. */ - public maxAgeNumBlocks: number | Long; + public maxAgeNumBlocks: Long; /** EvidenceParams maxAgeDuration. */ public maxAgeDuration?: google.protobuf.IDuration | null; @@ -5285,7 +5285,7 @@ export namespace tendermint { chainId?: string | null; /** Header height */ - height?: number | Long | null; + height?: Long | null; /** Header time */ time?: google.protobuf.ITimestamp | null; @@ -5336,7 +5336,7 @@ export namespace tendermint { public chainId: string; /** Header height. */ - public height: number | Long; + public height: Long; /** Header time. */ public time?: google.protobuf.ITimestamp | null; @@ -5400,10 +5400,10 @@ export namespace tendermint { /** Properties of a Version. */ interface IVersion { /** Version Block */ - Block?: number | Long | null; + Block?: Long | null; /** Version App */ - App?: number | Long | null; + App?: Long | null; } /** Represents a Version. */ @@ -5415,10 +5415,10 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IVersion); /** Version Block. */ - public Block: number | Long; + public Block: Long; /** Version App. */ - public App: number | Long; + public App: Long; /** * Creates a new Version instance using the specified properties. @@ -5555,7 +5555,7 @@ export namespace tendermint { address?: Uint8Array | null; /** Validator power */ - power?: number | Long | null; + power?: Long | null; } /** Represents a Validator. */ @@ -5570,7 +5570,7 @@ export namespace tendermint { public address: Uint8Array; /** Validator power. */ - public power: number | Long; + public power: Long; /** * Creates a new Validator instance using the specified properties. @@ -5604,7 +5604,7 @@ export namespace tendermint { pubKey?: tendermint.abci.types.IPubKey | null; /** ValidatorUpdate power */ - power?: number | Long | null; + power?: Long | null; } /** Represents a ValidatorUpdate. */ @@ -5619,7 +5619,7 @@ export namespace tendermint { public pubKey?: tendermint.abci.types.IPubKey | null; /** ValidatorUpdate power. */ - public power: number | Long; + public power: Long; /** * Creates a new ValidatorUpdate instance using the specified properties. @@ -5762,13 +5762,13 @@ export namespace tendermint { validator?: tendermint.abci.types.IValidator | null; /** Evidence height */ - height?: number | Long | null; + height?: Long | null; /** Evidence time */ time?: google.protobuf.ITimestamp | null; /** Evidence totalVotingPower */ - totalVotingPower?: number | Long | null; + totalVotingPower?: Long | null; } /** Represents an Evidence. */ @@ -5786,13 +5786,13 @@ export namespace tendermint { public validator?: tendermint.abci.types.IValidator | null; /** Evidence height. */ - public height: number | Long; + public height: Long; /** Evidence time. */ public time?: google.protobuf.ITimestamp | null; /** Evidence totalVotingPower. */ - public totalVotingPower: number | Long; + public totalVotingPower: Long; /** * Creates a new Evidence instance using the specified properties. @@ -6313,7 +6313,7 @@ export namespace tendermint { key?: Uint8Array | null; /** KI64Pair value */ - value?: number | Long | null; + value?: Long | null; } /** Represents a KI64Pair. */ @@ -6328,7 +6328,7 @@ export namespace tendermint { public key: Uint8Array; /** KI64Pair value. */ - public value: number | Long; + public value: Long; /** * Creates a new KI64Pair instance using the specified properties. @@ -6415,7 +6415,7 @@ export namespace google { /** Properties of a Timestamp. */ interface ITimestamp { /** Timestamp seconds */ - seconds?: number | Long | null; + seconds?: Long | null; /** Timestamp nanos */ nanos?: number | null; @@ -6430,7 +6430,7 @@ export namespace google { constructor(p?: google.protobuf.ITimestamp); /** Timestamp seconds. */ - public seconds: number | Long; + public seconds: Long; /** Timestamp nanos. */ public nanos: number; @@ -6464,7 +6464,7 @@ export namespace google { /** Properties of a Duration. */ interface IDuration { /** Duration seconds */ - seconds?: number | Long | null; + seconds?: Long | null; /** Duration nanos */ nanos?: number | null; @@ -6479,7 +6479,7 @@ export namespace google { constructor(p?: google.protobuf.IDuration); /** Duration seconds. */ - public seconds: number | Long; + public seconds: Long; /** Duration nanos. */ public nanos: number; diff --git a/packages/stargate/src/generated/codecimpl.js b/packages/stargate/src/codec/generated/codecimpl.js similarity index 100% rename from packages/stargate/src/generated/codecimpl.js rename to packages/stargate/src/codec/generated/codecimpl.js diff --git a/packages/stargate/src/codec/index.ts b/packages/stargate/src/codec/index.ts new file mode 100644 index 00000000..e27bfc7e --- /dev/null +++ b/packages/stargate/src/codec/index.ts @@ -0,0 +1,9 @@ +import Long from "long"; +import protobuf from "protobufjs/minimal"; + +// Ensure the protobuf module has a Long implementation, which otherwise only works +// in Node.js (see https://github.com/protobufjs/protobuf.js/issues/921#issuecomment-334925145) +protobuf.util.Long = Long; +protobuf.configure(); + +export * from "./generated/codecimpl"; diff --git a/packages/stargate/src/queries/auth.spec.ts b/packages/stargate/src/queries/auth.spec.ts index 4befcb65..bab4270f 100644 --- a/packages/stargate/src/queries/auth.spec.ts +++ b/packages/stargate/src/queries/auth.spec.ts @@ -22,6 +22,7 @@ describe("AuthExtension", () => { const account = await client.auth.account(unused.address); assert(account); + expect(account).toEqual({ address: toAccAddress(unused.address), // pubKey not set diff --git a/packages/stargate/src/queries/auth.ts b/packages/stargate/src/queries/auth.ts index fbc4c470..aeffb54c 100644 --- a/packages/stargate/src/queries/auth.ts +++ b/packages/stargate/src/queries/auth.ts @@ -1,6 +1,6 @@ import { assert } from "@cosmjs/utils"; -import { cosmos, google } from "../generated/codecimpl"; +import { cosmos, google } from "../codec"; import { QueryClient } from "./queryclient"; import { toAccAddress, toObject } from "./utils"; diff --git a/packages/stargate/src/queries/bank.ts b/packages/stargate/src/queries/bank.ts index 6f6c3a93..6b85cb8f 100644 --- a/packages/stargate/src/queries/bank.ts +++ b/packages/stargate/src/queries/bank.ts @@ -1,7 +1,7 @@ import { toAscii } from "@cosmjs/encoding"; import { assert } from "@cosmjs/utils"; -import { cosmos } from "../generated/codecimpl"; +import { cosmos } from "../codec"; import { QueryClient } from "./queryclient"; import { toAccAddress, toObject } from "./utils"; diff --git a/packages/stargate/src/stargateclient.searchtx.spec.ts b/packages/stargate/src/stargateclient.searchtx.spec.ts index 1f10a41b..855fcf73 100644 --- a/packages/stargate/src/stargateclient.searchtx.spec.ts +++ b/packages/stargate/src/stargateclient.searchtx.spec.ts @@ -3,8 +3,9 @@ import { Bech32, fromBase64 } from "@cosmjs/encoding"; import { Coin, coins, Secp256k1Wallet } from "@cosmjs/launchpad"; import { makeSignBytes, omitDefaults, Registry } from "@cosmjs/proto-signing"; import { assert } from "@cosmjs/utils"; +import Long from "long"; -import { cosmos } from "./generated/codecimpl"; +import { cosmos } from "./codec"; import { BroadcastTxResponse, isBroadcastTxFailure, @@ -68,7 +69,7 @@ async function sendTokens( }, ], fee: { - gasLimit: 200000, + gasLimit: Long.fromNumber(200000), }, }; const authInfoBytes = Uint8Array.from(AuthInfo.encode(authInfo).finish()); diff --git a/packages/stargate/src/stargateclient.spec.ts b/packages/stargate/src/stargateclient.spec.ts index a4bf8c4b..130edc2f 100644 --- a/packages/stargate/src/stargateclient.spec.ts +++ b/packages/stargate/src/stargateclient.spec.ts @@ -3,9 +3,10 @@ import { Bech32, fromBase64 } from "@cosmjs/encoding"; import { Secp256k1Wallet } from "@cosmjs/launchpad"; import { makeSignBytes, omitDefaults, Registry } from "@cosmjs/proto-signing"; import { assert, sleep } from "@cosmjs/utils"; +import Long from "long"; import { ReadonlyDate } from "readonly-date"; -import { cosmos } from "./generated/codecimpl"; +import { cosmos } from "./codec"; import { assertIsBroadcastTxSuccess, PrivateStargateClient, StargateClient } from "./stargateclient"; import { faucet, @@ -290,7 +291,7 @@ describe("StargateClient", () => { }, ], fee: { - gasLimit: 200000, + gasLimit: Long.fromNumber(200000), }, }; const authInfoBytes = Uint8Array.from(AuthInfo.encode(authInfo).finish()); diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 03a89048..447a87bf 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -15,7 +15,7 @@ import { broadcastTxCommitSuccess, Client as TendermintClient, QueryString } fro import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; -import { cosmos } from "./generated/codecimpl"; +import { cosmos } from "./codec"; import { AuthExtension, BankExtension, QueryClient, setupAuthExtension, setupBankExtension } from "./queries"; /** A transaction that is indexed as part of the transaction history */ diff --git a/packages/stargate/types/generated/codecimpl.d.ts b/packages/stargate/types/codec/generated/codecimpl.d.ts similarity index 98% rename from packages/stargate/types/generated/codecimpl.d.ts rename to packages/stargate/types/codec/generated/codecimpl.d.ts index 627c179e..43c0b29b 100644 --- a/packages/stargate/types/generated/codecimpl.d.ts +++ b/packages/stargate/types/codec/generated/codecimpl.d.ts @@ -231,10 +231,10 @@ export namespace cosmos { /** Properties of a GasInfo. */ interface IGasInfo { /** GasInfo gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** GasInfo gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; } /** Represents a GasInfo. */ @@ -246,10 +246,10 @@ export namespace cosmos { constructor(p?: cosmos.IGasInfo); /** GasInfo gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** GasInfo gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** * Creates a new GasInfo instance using the specified properties. @@ -476,7 +476,7 @@ export namespace cosmos { /** Properties of a TxResponse. */ interface ITxResponse { /** TxResponse height */ - height?: number | Long | null; + height?: Long | null; /** TxResponse txhash */ txhash?: string | null; @@ -500,10 +500,10 @@ export namespace cosmos { info?: string | null; /** TxResponse gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** TxResponse gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; /** TxResponse tx */ tx?: google.protobuf.IAny | null; @@ -521,7 +521,7 @@ export namespace cosmos { constructor(p?: cosmos.ITxResponse); /** TxResponse height. */ - public height: number | Long; + public height: Long; /** TxResponse txhash. */ public txhash: string; @@ -545,10 +545,10 @@ export namespace cosmos { public info: string; /** TxResponse gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** TxResponse gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** TxResponse tx. */ public tx?: google.protobuf.IAny | null; @@ -746,10 +746,10 @@ export namespace cosmos { pubKey?: Uint8Array | null; /** BaseAccount accountNumber */ - accountNumber?: number | Long | null; + accountNumber?: Long | null; /** BaseAccount sequence */ - sequence?: number | Long | null; + sequence?: Long | null; } /** Represents a BaseAccount. */ @@ -767,10 +767,10 @@ export namespace cosmos { public pubKey: Uint8Array; /** BaseAccount accountNumber. */ - public accountNumber: number | Long; + public accountNumber: Long; /** BaseAccount sequence. */ - public sequence: number | Long; + public sequence: Long; /** * Creates a new BaseAccount instance using the specified properties. @@ -856,19 +856,19 @@ export namespace cosmos { /** Properties of a Params. */ interface IParams { /** Params maxMemoCharacters */ - maxMemoCharacters?: number | Long | null; + maxMemoCharacters?: Long | null; /** Params txSigLimit */ - txSigLimit?: number | Long | null; + txSigLimit?: Long | null; /** Params txSizeCostPerByte */ - txSizeCostPerByte?: number | Long | null; + txSizeCostPerByte?: Long | null; /** Params sigVerifyCostEd25519 */ - sigVerifyCostEd25519?: number | Long | null; + sigVerifyCostEd25519?: Long | null; /** Params sigVerifyCostSecp256k1 */ - sigVerifyCostSecp256k1?: number | Long | null; + sigVerifyCostSecp256k1?: Long | null; } /** Represents a Params. */ @@ -880,19 +880,19 @@ export namespace cosmos { constructor(p?: cosmos.auth.IParams); /** Params maxMemoCharacters. */ - public maxMemoCharacters: number | Long; + public maxMemoCharacters: Long; /** Params txSigLimit. */ - public txSigLimit: number | Long; + public txSigLimit: Long; /** Params txSizeCostPerByte. */ - public txSizeCostPerByte: number | Long; + public txSizeCostPerByte: Long; /** Params sigVerifyCostEd25519. */ - public sigVerifyCostEd25519: number | Long; + public sigVerifyCostEd25519: Long; /** Params sigVerifyCostSecp256k1. */ - public sigVerifyCostSecp256k1: number | Long; + public sigVerifyCostSecp256k1: Long; /** * Creates a new Params instance using the specified properties. @@ -2360,10 +2360,10 @@ export namespace cosmos { key?: Uint8Array | null; /** PageRequest offset */ - offset?: number | Long | null; + offset?: Long | null; /** PageRequest limit */ - limit?: number | Long | null; + limit?: Long | null; /** PageRequest countTotal */ countTotal?: boolean | null; @@ -2381,10 +2381,10 @@ export namespace cosmos { public key: Uint8Array; /** PageRequest offset. */ - public offset: number | Long; + public offset: Long; /** PageRequest limit. */ - public limit: number | Long; + public limit: Long; /** PageRequest countTotal. */ public countTotal: boolean; @@ -2421,7 +2421,7 @@ export namespace cosmos { nextKey?: Uint8Array | null; /** PageResponse total */ - total?: number | Long | null; + total?: Long | null; } /** Represents a PageResponse. */ @@ -2436,7 +2436,7 @@ export namespace cosmos { public nextKey: Uint8Array; /** PageResponse total. */ - public total: number | Long; + public total: Long; /** * Creates a new PageResponse instance using the specified properties. @@ -2589,10 +2589,10 @@ export namespace cosmos { chainId?: string | null; /** SignDoc accountNumber */ - accountNumber?: number | Long | null; + accountNumber?: Long | null; /** SignDoc accountSequence */ - accountSequence?: number | Long | null; + accountSequence?: Long | null; } /** Represents a SignDoc. */ @@ -2613,10 +2613,10 @@ export namespace cosmos { public chainId: string; /** SignDoc accountNumber. */ - public accountNumber: number | Long; + public accountNumber: Long; /** SignDoc accountSequence. */ - public accountSequence: number | Long; + public accountSequence: Long; /** * Creates a new SignDoc instance using the specified properties. @@ -2653,7 +2653,7 @@ export namespace cosmos { memo?: string | null; /** TxBody timeoutHeight */ - timeoutHeight?: number | Long | null; + timeoutHeight?: Long | null; /** TxBody extensionOptions */ extensionOptions?: google.protobuf.IAny[] | null; @@ -2677,7 +2677,7 @@ export namespace cosmos { public memo: string; /** TxBody timeoutHeight. */ - public timeoutHeight: number | Long; + public timeoutHeight: Long; /** TxBody extensionOptions. */ public extensionOptions: google.protobuf.IAny[]; @@ -2961,7 +2961,7 @@ export namespace cosmos { amount?: cosmos.ICoin[] | null; /** Fee gasLimit */ - gasLimit?: number | Long | null; + gasLimit?: Long | null; } /** Represents a Fee. */ @@ -2976,7 +2976,7 @@ export namespace cosmos { public amount: cosmos.ICoin[]; /** Fee gasLimit. */ - public gasLimit: number | Long; + public gasLimit: Long; /** * Creates a new Fee instance using the specified properties. @@ -3519,10 +3519,10 @@ export namespace tendermint { version?: string | null; /** RequestInfo blockVersion */ - blockVersion?: number | Long | null; + blockVersion?: Long | null; /** RequestInfo p2pVersion */ - p2pVersion?: number | Long | null; + p2pVersion?: Long | null; } /** Represents a RequestInfo. */ @@ -3537,10 +3537,10 @@ export namespace tendermint { public version: string; /** RequestInfo blockVersion. */ - public blockVersion: number | Long; + public blockVersion: Long; /** RequestInfo p2pVersion. */ - public p2pVersion: number | Long; + public p2pVersion: Long; /** * Creates a new RequestInfo instance using the specified properties. @@ -3711,7 +3711,7 @@ export namespace tendermint { path?: string | null; /** RequestQuery height */ - height?: number | Long | null; + height?: Long | null; /** RequestQuery prove */ prove?: boolean | null; @@ -3732,7 +3732,7 @@ export namespace tendermint { public path: string; /** RequestQuery height. */ - public height: number | Long; + public height: Long; /** RequestQuery prove. */ public prove: boolean; @@ -3954,7 +3954,7 @@ export namespace tendermint { /** Properties of a RequestEndBlock. */ interface IRequestEndBlock { /** RequestEndBlock height */ - height?: number | Long | null; + height?: Long | null; } /** Represents a RequestEndBlock. */ @@ -3966,7 +3966,7 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IRequestEndBlock); /** RequestEndBlock height. */ - public height: number | Long; + public height: Long; /** * Creates a new RequestEndBlock instance using the specified properties. @@ -4318,10 +4318,10 @@ export namespace tendermint { version?: string | null; /** ResponseInfo appVersion */ - appVersion?: number | Long | null; + appVersion?: Long | null; /** ResponseInfo lastBlockHeight */ - lastBlockHeight?: number | Long | null; + lastBlockHeight?: Long | null; /** ResponseInfo lastBlockAppHash */ lastBlockAppHash?: Uint8Array | null; @@ -4342,10 +4342,10 @@ export namespace tendermint { public version: string; /** ResponseInfo appVersion. */ - public appVersion: number | Long; + public appVersion: Long; /** ResponseInfo lastBlockHeight. */ - public lastBlockHeight: number | Long; + public lastBlockHeight: Long; /** ResponseInfo lastBlockAppHash. */ public lastBlockAppHash: Uint8Array; @@ -4513,7 +4513,7 @@ export namespace tendermint { info?: string | null; /** ResponseQuery index */ - index?: number | Long | null; + index?: Long | null; /** ResponseQuery key */ key?: Uint8Array | null; @@ -4525,7 +4525,7 @@ export namespace tendermint { proof?: tendermint.crypto.merkle.IProof | null; /** ResponseQuery height */ - height?: number | Long | null; + height?: Long | null; /** ResponseQuery codespace */ codespace?: string | null; @@ -4549,7 +4549,7 @@ export namespace tendermint { public info: string; /** ResponseQuery index. */ - public index: number | Long; + public index: Long; /** ResponseQuery key. */ public key: Uint8Array; @@ -4561,7 +4561,7 @@ export namespace tendermint { public proof?: tendermint.crypto.merkle.IProof | null; /** ResponseQuery height. */ - public height: number | Long; + public height: Long; /** ResponseQuery codespace. */ public codespace: string; @@ -4663,10 +4663,10 @@ export namespace tendermint { info?: string | null; /** ResponseCheckTx gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** ResponseCheckTx gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; /** ResponseCheckTx events */ events?: tendermint.abci.types.IEvent[] | null; @@ -4696,10 +4696,10 @@ export namespace tendermint { public info: string; /** ResponseCheckTx gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** ResponseCheckTx gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** ResponseCheckTx events. */ public events: tendermint.abci.types.IEvent[]; @@ -4756,10 +4756,10 @@ export namespace tendermint { info?: string | null; /** ResponseDeliverTx gasWanted */ - gasWanted?: number | Long | null; + gasWanted?: Long | null; /** ResponseDeliverTx gasUsed */ - gasUsed?: number | Long | null; + gasUsed?: Long | null; /** ResponseDeliverTx events */ events?: tendermint.abci.types.IEvent[] | null; @@ -4789,10 +4789,10 @@ export namespace tendermint { public info: string; /** ResponseDeliverTx gasWanted. */ - public gasWanted: number | Long; + public gasWanted: Long; /** ResponseDeliverTx gasUsed. */ - public gasUsed: number | Long; + public gasUsed: Long; /** ResponseDeliverTx events. */ public events: tendermint.abci.types.IEvent[]; @@ -5014,10 +5014,10 @@ export namespace tendermint { /** Properties of a BlockParams. */ interface IBlockParams { /** BlockParams maxBytes */ - maxBytes?: number | Long | null; + maxBytes?: Long | null; /** BlockParams maxGas */ - maxGas?: number | Long | null; + maxGas?: Long | null; } /** Represents a BlockParams. */ @@ -5029,10 +5029,10 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IBlockParams); /** BlockParams maxBytes. */ - public maxBytes: number | Long; + public maxBytes: Long; /** BlockParams maxGas. */ - public maxGas: number | Long; + public maxGas: Long; /** * Creates a new BlockParams instance using the specified properties. @@ -5065,7 +5065,7 @@ export namespace tendermint { /** Properties of an EvidenceParams. */ interface IEvidenceParams { /** EvidenceParams maxAgeNumBlocks */ - maxAgeNumBlocks?: number | Long | null; + maxAgeNumBlocks?: Long | null; /** EvidenceParams maxAgeDuration */ maxAgeDuration?: google.protobuf.IDuration | null; @@ -5080,7 +5080,7 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IEvidenceParams); /** EvidenceParams maxAgeNumBlocks. */ - public maxAgeNumBlocks: number | Long; + public maxAgeNumBlocks: Long; /** EvidenceParams maxAgeDuration. */ public maxAgeDuration?: google.protobuf.IDuration | null; @@ -5285,7 +5285,7 @@ export namespace tendermint { chainId?: string | null; /** Header height */ - height?: number | Long | null; + height?: Long | null; /** Header time */ time?: google.protobuf.ITimestamp | null; @@ -5336,7 +5336,7 @@ export namespace tendermint { public chainId: string; /** Header height. */ - public height: number | Long; + public height: Long; /** Header time. */ public time?: google.protobuf.ITimestamp | null; @@ -5400,10 +5400,10 @@ export namespace tendermint { /** Properties of a Version. */ interface IVersion { /** Version Block */ - Block?: number | Long | null; + Block?: Long | null; /** Version App */ - App?: number | Long | null; + App?: Long | null; } /** Represents a Version. */ @@ -5415,10 +5415,10 @@ export namespace tendermint { constructor(p?: tendermint.abci.types.IVersion); /** Version Block. */ - public Block: number | Long; + public Block: Long; /** Version App. */ - public App: number | Long; + public App: Long; /** * Creates a new Version instance using the specified properties. @@ -5555,7 +5555,7 @@ export namespace tendermint { address?: Uint8Array | null; /** Validator power */ - power?: number | Long | null; + power?: Long | null; } /** Represents a Validator. */ @@ -5570,7 +5570,7 @@ export namespace tendermint { public address: Uint8Array; /** Validator power. */ - public power: number | Long; + public power: Long; /** * Creates a new Validator instance using the specified properties. @@ -5604,7 +5604,7 @@ export namespace tendermint { pubKey?: tendermint.abci.types.IPubKey | null; /** ValidatorUpdate power */ - power?: number | Long | null; + power?: Long | null; } /** Represents a ValidatorUpdate. */ @@ -5619,7 +5619,7 @@ export namespace tendermint { public pubKey?: tendermint.abci.types.IPubKey | null; /** ValidatorUpdate power. */ - public power: number | Long; + public power: Long; /** * Creates a new ValidatorUpdate instance using the specified properties. @@ -5762,13 +5762,13 @@ export namespace tendermint { validator?: tendermint.abci.types.IValidator | null; /** Evidence height */ - height?: number | Long | null; + height?: Long | null; /** Evidence time */ time?: google.protobuf.ITimestamp | null; /** Evidence totalVotingPower */ - totalVotingPower?: number | Long | null; + totalVotingPower?: Long | null; } /** Represents an Evidence. */ @@ -5786,13 +5786,13 @@ export namespace tendermint { public validator?: tendermint.abci.types.IValidator | null; /** Evidence height. */ - public height: number | Long; + public height: Long; /** Evidence time. */ public time?: google.protobuf.ITimestamp | null; /** Evidence totalVotingPower. */ - public totalVotingPower: number | Long; + public totalVotingPower: Long; /** * Creates a new Evidence instance using the specified properties. @@ -6313,7 +6313,7 @@ export namespace tendermint { key?: Uint8Array | null; /** KI64Pair value */ - value?: number | Long | null; + value?: Long | null; } /** Represents a KI64Pair. */ @@ -6328,7 +6328,7 @@ export namespace tendermint { public key: Uint8Array; /** KI64Pair value. */ - public value: number | Long; + public value: Long; /** * Creates a new KI64Pair instance using the specified properties. @@ -6415,7 +6415,7 @@ export namespace google { /** Properties of a Timestamp. */ interface ITimestamp { /** Timestamp seconds */ - seconds?: number | Long | null; + seconds?: Long | null; /** Timestamp nanos */ nanos?: number | null; @@ -6430,7 +6430,7 @@ export namespace google { constructor(p?: google.protobuf.ITimestamp); /** Timestamp seconds. */ - public seconds: number | Long; + public seconds: Long; /** Timestamp nanos. */ public nanos: number; @@ -6464,7 +6464,7 @@ export namespace google { /** Properties of a Duration. */ interface IDuration { /** Duration seconds */ - seconds?: number | Long | null; + seconds?: Long | null; /** Duration nanos */ nanos?: number | null; @@ -6479,7 +6479,7 @@ export namespace google { constructor(p?: google.protobuf.IDuration); /** Duration seconds. */ - public seconds: number | Long; + public seconds: Long; /** Duration nanos. */ public nanos: number; diff --git a/packages/stargate/types/codec/index.d.ts b/packages/stargate/types/codec/index.d.ts new file mode 100644 index 00000000..7cbb5810 --- /dev/null +++ b/packages/stargate/types/codec/index.d.ts @@ -0,0 +1 @@ +export * from "./generated/codecimpl"; diff --git a/packages/stargate/types/queries/auth.d.ts b/packages/stargate/types/queries/auth.d.ts index db6bcb4f..1fd1d65c 100644 --- a/packages/stargate/types/queries/auth.d.ts +++ b/packages/stargate/types/queries/auth.d.ts @@ -1,4 +1,4 @@ -import { cosmos } from "../generated/codecimpl"; +import { cosmos } from "../codec"; import { QueryClient } from "./queryclient"; export interface AuthExtension { readonly auth: { diff --git a/packages/stargate/types/queries/bank.d.ts b/packages/stargate/types/queries/bank.d.ts index 5e02551c..ad67fe12 100644 --- a/packages/stargate/types/queries/bank.d.ts +++ b/packages/stargate/types/queries/bank.d.ts @@ -1,4 +1,4 @@ -import { cosmos } from "../generated/codecimpl"; +import { cosmos } from "../codec"; import { QueryClient } from "./queryclient"; export interface BankExtension { readonly bank: { From 15b4bb04681a0cddd25bbb32dfcc1e634d598eaf Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Aug 2020 15:51:00 +0200 Subject: [PATCH 17/17] Disconnect Tendermint clients properly --- packages/stargate/src/queries/auth.spec.ts | 29 +++++++++---- packages/stargate/src/queries/bank.spec.ts | 49 +++++++++++++++------- 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/packages/stargate/src/queries/auth.spec.ts b/packages/stargate/src/queries/auth.spec.ts index bab4270f..14225043 100644 --- a/packages/stargate/src/queries/auth.spec.ts +++ b/packages/stargate/src/queries/auth.spec.ts @@ -8,17 +8,16 @@ import { AuthExtension, setupAuthExtension } from "./auth"; import { QueryClient } from "./queryclient"; import { toAccAddress } from "./utils"; -async function makeAuthClient(rpcUrl: string): Promise { - // TODO: tmClient is not owned by QueryClient but should be disconnected somehow (once we use WebSockets) +async function makeAuthClient(rpcUrl: string): Promise<[QueryClient & AuthExtension, TendermintClient]> { const tmClient = await TendermintClient.connect(rpcUrl); - return QueryClient.withExtensions(tmClient, setupAuthExtension); + return [QueryClient.withExtensions(tmClient, setupAuthExtension), tmClient]; } describe("AuthExtension", () => { describe("account", () => { it("works for unused account", async () => { pendingWithoutSimapp(); - const client = await makeAuthClient(simapp.tendermintUrl); + const [client, tmClient] = await makeAuthClient(simapp.tendermintUrl); const account = await client.auth.account(unused.address); assert(account); @@ -29,11 +28,13 @@ describe("AuthExtension", () => { accountNumber: Long.fromNumber(unused.accountNumber, true), // sequence not set }); + + tmClient.disconnect(); }); it("works for account with pubkey and non-zero sequence", async () => { pendingWithoutSimapp(); - const client = await makeAuthClient(simapp.tendermintUrl); + const [client, tmClient] = await makeAuthClient(simapp.tendermintUrl); const account = await client.auth.account(validator.address); assert(account); @@ -43,14 +44,18 @@ describe("AuthExtension", () => { // accountNumber not set sequence: Long.fromNumber(validator.sequence, true), }); + + tmClient.disconnect(); }); it("returns null for non-existent address", async () => { pendingWithoutSimapp(); - const client = await makeAuthClient(simapp.tendermintUrl); + const [client, tmClient] = await makeAuthClient(simapp.tendermintUrl); const account = await client.auth.account(nonExistentAddress); expect(account).toBeNull(); + + tmClient.disconnect(); }); }); @@ -58,7 +63,7 @@ describe("AuthExtension", () => { describe("account", () => { it("works for unused account", async () => { pendingWithoutSimapp(); - const client = await makeAuthClient(simapp.tendermintUrl); + const [client, tmClient] = await makeAuthClient(simapp.tendermintUrl); const account = await client.auth.unverified.account(unused.address); assert(account); @@ -68,11 +73,13 @@ describe("AuthExtension", () => { accountNumber: Long.fromNumber(unused.accountNumber, true), // sequence not set }); + + tmClient.disconnect(); }); it("works for account with pubkey and non-zero sequence", async () => { pendingWithoutSimapp(); - const client = await makeAuthClient(simapp.tendermintUrl); + const [client, tmClient] = await makeAuthClient(simapp.tendermintUrl); const account = await client.auth.unverified.account(validator.address); assert(account); @@ -82,15 +89,19 @@ describe("AuthExtension", () => { // accountNumber not set sequence: Long.fromNumber(validator.sequence, true), }); + + tmClient.disconnect(); }); it("returns null for non-existent address", async () => { pending("This fails with Error: Query failed with (1): internal"); pendingWithoutSimapp(); - const client = await makeAuthClient(simapp.tendermintUrl); + const [client, tmClient] = await makeAuthClient(simapp.tendermintUrl); const account = await client.auth.unverified.account(nonExistentAddress); expect(account).toBeNull(); + + tmClient.disconnect(); }); }); }); diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index 7f7d7a11..9d73e4b1 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -10,17 +10,16 @@ import { import { BankExtension, setupBankExtension } from "./bank"; import { QueryClient } from "./queryclient"; -async function makeBankClient(rpcUrl: string): Promise { - // TODO: tmClient is not owned by QueryClient but should be disconnected somehow (once we use WebSockets) +async function makeBankClient(rpcUrl: string): Promise<[QueryClient & BankExtension, TendermintClient]> { const tmClient = await TendermintClient.connect(rpcUrl); - return QueryClient.withExtensions(tmClient, setupBankExtension); + return [QueryClient.withExtensions(tmClient, setupBankExtension), tmClient]; } describe("BankExtension", () => { describe("balance", () => { it("works for different existing balances", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response1 = await client.bank.balance(unused.address, simapp.denomFee); expect(response1).toEqual({ @@ -32,22 +31,28 @@ describe("BankExtension", () => { amount: unused.balanceStaking, denom: simapp.denomStaking, }); + + tmClient.disconnect(); }); it("returns null for non-existent balance", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.balance(unused.address, "gintonic"); expect(response).toBeNull(); + + tmClient.disconnect(); }); it("returns null for non-existent address", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.balance(nonExistentAddress, simapp.denomFee); expect(response).toBeNull(); + + tmClient.disconnect(); }); }); @@ -55,7 +60,7 @@ describe("BankExtension", () => { describe("balance", () => { it("works for different existing balances", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response1 = await client.bank.unverified.balance(unused.address, simapp.denomFee); expect(response1).toEqual({ @@ -67,35 +72,41 @@ describe("BankExtension", () => { amount: unused.balanceStaking, denom: simapp.denomStaking, }); + + tmClient.disconnect(); }); it("returns zero for non-existent balance", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.unverified.balance(unused.address, "gintonic"); expect(response).toEqual({ amount: "0", denom: "gintonic", }); + + tmClient.disconnect(); }); it("returns zero for non-existent address", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.unverified.balance(nonExistentAddress, simapp.denomFee); expect(response).toEqual({ amount: "0", denom: simapp.denomFee, }); + + tmClient.disconnect(); }); }); describe("allBalances", () => { it("returns all balances for unused account", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const balances = await client.bank.unverified.allBalances(unused.address); expect(balances).toEqual([ @@ -108,21 +119,25 @@ describe("BankExtension", () => { denom: simapp.denomStaking, }, ]); + + tmClient.disconnect(); }); it("returns an empty list for non-existent account", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const balances = await client.bank.unverified.allBalances(nonExistentAddress); expect(balances).toEqual([]); + + tmClient.disconnect(); }); }); describe("totalSupply", () => { it("works", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.unverified.totalSupply(); expect(response).toEqual([ @@ -135,30 +150,36 @@ describe("BankExtension", () => { denom: simapp.denomStaking, }, ]); + + tmClient.disconnect(); }); }); describe("supplyOf", () => { it("works for existing denom", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.unverified.supplyOf(simapp.denomFee); expect(response).toEqual({ amount: "18000000000", denom: simapp.denomFee, }); + + tmClient.disconnect(); }); it("returns zero for non-existent denom", async () => { pendingWithoutSimapp(); - const client = await makeBankClient(simapp.tendermintUrl); + const [client, tmClient] = await makeBankClient(simapp.tendermintUrl); const response = await client.bank.unverified.supplyOf("gintonic"); expect(response).toEqual({ amount: "0", denom: "gintonic", }); + + tmClient.disconnect(); }); }); });