diff --git a/.eslintignore b/.eslintignore new file mode 120000 index 0000000..86039ba --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +../../.eslintignore \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..3a1d6b5 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,93 @@ +module.exports = { + env: { + es6: true, + jasmine: true, + node: true, + worker: true, + }, + parser: "@typescript-eslint/parser", + parserOptions: { + ecmaVersion: 2018, + project: "./tsconfig.eslint.json", + tsconfigRootDir: __dirname, + }, + plugins: ["@typescript-eslint", "prettier", "simple-import-sort", "import"], + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier", + "plugin:prettier/recommended", + "plugin:import/typescript", + ], + rules: { + curly: ["warn", "multi-line", "consistent"], + "no-bitwise": "warn", + "no-console": ["warn", { allow: ["error", "info", "table", "warn"] }], + "no-param-reassign": "warn", + "no-shadow": "off", // disabled in favour of @typescript-eslint/no-shadow, see https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-shadow.md + "no-unused-vars": "off", // disabled in favour of @typescript-eslint/no-unused-vars, see https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars.md + "prefer-const": "warn", + radix: ["warn", "always"], + "spaced-comment": ["warn", "always", { line: { markers: ["/ + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4aed37c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/stargate.iml b/.idea/stargate.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/stargate.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.nycrc.yml b/.nycrc.yml new file mode 120000 index 0000000..1f95ac5 --- /dev/null +++ b/.nycrc.yml @@ -0,0 +1 @@ +../../.nycrc.yml \ No newline at end of file diff --git a/CUSTOM_PROTOBUF_CODECS.md b/CUSTOM_PROTOBUF_CODECS.md new file mode 100644 index 0000000..c2ff44f --- /dev/null +++ b/CUSTOM_PROTOBUF_CODECS.md @@ -0,0 +1,232 @@ +# Custom Protocol Buffer Codecs + +As of [v0.40](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0), the +Cosmos SDK uses +[Protocol Buffers](https://developers.google.com/protocol-buffers) (also known +as "protobuf") as its standard serialization format for blockchain state and +wire communication. CosmJS by default supports Protocol Buffer serialization for +many of the standard queries and messages defined by the Cosmos SDK, as well as +[CosmWasm](https://github.com/CosmWasm/wasmd). This document explains how you +can make use of Protocol Buffer serialization for your own custom modules with +CosmJS. + +## Prerequisites + +- You are working on a TypeScript project. (Plain JS is possible but not covered + by this document. It should work if you just strip out the type information.) +- You have installed `@cosmjs/proto-signing`, `@cosmjs/stargate` and + `@cosmjs/tendermint-rpc` as dependencies. In general these dependencies should + all have the same version, and this document is accurate as of version 0.26. + ``` + "dependencies": { + "@cosmjs/proto-signing": "^0.26.4", + "@cosmjs/stargate": "^0.26.4", + "@cosmjs/tendermint-rpc": "^0.26.4", + // ... + } + ``` +- You have installed `ts-proto` as a development dependency. This document is + accurate as of version 1.84. +- You have installed [`protoc`](https://github.com/protocolbuffers/protobuf). + This document is accurate as of version 3.17. +- This document assumes that the Protocol Buffer definitions which you need are + already available somewhere in + [`.proto` files](https://developers.google.com/protocol-buffers/docs/proto). + +## Step 1: Acquire the definition files + +You will need these files locally. There are two ways this is typically done: + +1. **Download copies** from an external source into the project. For example, we + used + [this script](https://github.com/cosmos/cosmjs/blob/v0.25.6/packages/stargate/scripts/get-proto.sh) + to download the definition files from the Cosmos SDK repository. +2. **Git submodules** allow linking external repositories into the current + project's git. This is done in + [the cosmjs-types repo](https://github.com/confio/cosmjs-types). + +If the proto files are not publicly available, the first way should be +preferred. Otherwise permission management can become very complicated. + +## Step 2: Generate codec files + +In CosmJS we use [ts-proto](https://github.com/stephenh/ts-proto) to generate +codec files, and in this document we assume you will follow the same route. Here +is an example usage: + +```sh +protoc \ + --plugin="./node_modules/.bin/protoc-gen-ts_proto" \ + --ts_proto_out="./path/to/output/directory" \ + --proto_path="./path/to/definitions" \ + --ts_proto_opt="esModuleInterop=true,forceLong=long,useOptionals=true" \ + "./path/to/definitions/file.proto" \ + "./path/to/definitions/another.proto" +``` + +Note that the available `ts-proto` options are described +[here](https://github.com/stephenh/ts-proto#supported-options). You can see the +script we used for the `@cosmjs/stargate` package +[here](https://github.com/cosmos/cosmjs/blob/v0.25.6/packages/stargate/scripts/define-proto.sh). + +### Working with Yarn 2+ + +The binary `./node_modules/.bin/protoc-gen-ts_proto` is not easily available +when using Yarn 2 or higher. You also need to execute `node` through `yarn`. In +such cases an executable wrapper script `bin/protoc-gen-ts_proto_yarn_2` with + +``` +#!/usr/bin/env -S yarn node +require('ts-proto/build/plugin') +``` + +helps. The name of the script renames the protoc plugin from `ts_proto` to +`ts_proto_yarn_2` and the `protoc` must now be prefixed accordingly, like +`--ts_proto_yarn_2_opt="…"`. + +A full example is available in the cosmjs-types repo: +[protoc-gen-ts_proto_yarn_2](https://github.com/confio/cosmjs-types/blob/v0.2.1/bin/protoc-gen-ts_proto_yarn_2) +and +[codegen.sh](https://github.com/confio/cosmjs-types/blob/v0.2.1/scripts/codegen.sh). + +### Step 3 + +In Step 2 we saw how the codec is generated (i.e. the TypeScript code +generation). Now we look into using this codec. This section is split in + +- Step 3a: custom messages +- Step 3b: custom queries + +## Step 3a: Instantiate a signing client using your custom message types + +This section assumes that your definition files included `MsgXxx` `message` +definitions for use in submitting transactions to a Cosmos SDK blockchain. You +can instantiate a signing client for Stargate which supports those message types +using a custom registry. We expose a `Registry` class from +`@cosmjs/proto-signing` for you to use, which maps type URLs to codec objects. +For example: + +```ts +import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing"; +import { defaultRegistryTypes, SigningStargateClient } from "@cosmjs/stargate"; +import { MsgXxx } from "./path/to/generated/codec/my/custom/tx"; // Replace with your own Msg import + +const myRegistry = new Registry([ + ...defaultRegistryTypes, + ["/my.custom.MsgXxx", MsgXxx], // Replace with your own type URL and Msg class +]); +const mnemonic = // Replace with your own mnemonic + "economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone"; + +// Inside an async function... +const signer = await DirectSecp256k1HdWallet.fromMnemonic( + mnemonic, + { prefix: "myprefix" }, // Replace with your own Bech32 address prefix +); +const client = await SigningStargateClient.connectWithSigner( + "my.endpoint.com", // Replace with your own RPC endpoint + signer, + { registry: myRegistry }, +); +``` + +Now when you want to sign and broadcast a transaction which contains a message +of your custom type, the client will know how to serialize (and deserialize) it: + +```ts +const myAddress = "wasm1pkptre7fdkl6gfrzlesjjvhxhlc3r4gm32kke3"; +const message = { + typeUrl: "/my.custom.MsgXxx", // Same as above + value: MsgXxx.fromPartial({ + foo: "bar", + }), +}; +const fee = { + amount: [ + { + denom: "udenom", // Use the appropriate fee denom for your chain + amount: "120000", + }, + ], + gas: "10000", +}; + +// Inside an async function... +// This method uses the registry you provided +const response = await client.signAndBroadcast(myAddress, [message], fee); +``` + +You can see a more complete example in Confio’s +[`ts-relayer` repo](https://github.com/confio/ts-relayer/blob/v0.3.1/src/lib/ibcclient.ts). + +### Step 3b: Instantiate a query client using your custom query service + +This section assumes that your definition files included a `Query` `service` +with `rpc` methods. `ts-proto` will generate a `QueryClientImpl` class which +needs to be provided with an RPC client. + +Creating an RPC client with the functionality required by this generated class +currently requires a few layers of abstraction. Here is how you can achieve it +using CosmJS helpers: + +```ts +import { createProtobufRpcClient, QueryClient } from "@cosmjs/stargate"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { QueryClientImpl } from "./path/to/generated/codec/my/custom/query"; + +// Inside an async function... +// The Tendermint client knows how to talk to the Tendermint RPC endpoint +const tendermintClient = await Tendermint34Client.connect("my.endpoint.com"); + +// The generic Stargate query client knows how to use the Tendermint client to submit unverified ABCI queries +const queryClient = new QueryClient(tendermintClient); + +// This helper function wraps the generic Stargate query client for use by the specific generated query client +const rpcClient = createProtobufRpcClient(queryClient); + +// Here we instantiate a specific query client which will have the custom methods defined in the .proto file +const queryService = new QueryClientImpl(rpcClient); + +// Now you can use this service to submit queries +const queryResult = await queryService.MyCustomQuery({ + foo: "bar", +}); +``` + +Additionally, we provide a system for extending `@cosmjs/stargate`’s +`QueryClient` with methods of your own design, wrapping those of the query +service. For this you will need to define your own `setupXxxExtension` functions +and pass them to the `QueryClient.withExtensions` static method like this: + +```ts +// Define your extensions +function setupXxxExtension(base: QueryClient) { + const rpcClient = createProtobufRpcClient(base); + const queryService = new QueryClientImpl(rpcClient); + + return { + mymodule: { + customQuery: async (foo: string) => + queryService.MyCustomQuery({ foo: foo }), + }, + }; +} +function setupYyyExtension(base: QueryClient) { + // ... +} + +// Setup the query client +const queryClient = QueryClient.withExtensions( + tendermintClient, + setupXxxExtension, + setupYyyExtension, + // You can add up to 18 extensions +); + +// Inside an async function... +// Now your query client has been extended +const queryResult = await queryClient.mymodule.customQuery("bar"); +``` + +You can see how CosmJS sets up the `bank` extension for its default query client +[here](https://github.com/cosmos/cosmjs/blob/v0.26.4/packages/stargate/src/queries/bank.ts). diff --git a/README.md b/README.md new file mode 100644 index 0000000..04925c9 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# @cosmjs/stargate + +[![npm version](https://img.shields.io/npm/v/@cosmjs/stargate.svg)](https://www.npmjs.com/package/@cosmjs/stargate) + +A client library for the Cosmos SDK 0.40. + +## Supported Cosmos SDK versions + +| CosmJS version | Supported Cosmos SDK version(s) | +| ------------------------------- | ------------------------------- | +| ^0.26.0 | 0.42.x | +| ^0.25.0 | 0.42.x | +| ^0.24.0 | 0.40.x, 0.41.x, 0.42.x | +| ^0.24.0-alpha.14 | 0.40.0 | +| ^0.24.0-alpha.8 | 0.40.0-rc3 | +| 0.24.0-alpha.2 – 0.24.0-alpha.7 | 0.40.0-rc2 | +| 0.24.0-alpha.1 | 0.40.0-rc1 | + +## License + +This package is part of the cosmjs repository, licensed under the Apache License +2.0 (see [NOTICE](https://github.com/cosmos/cosmjs/blob/main/NOTICE) and +[LICENSE](https://github.com/cosmos/cosmjs/blob/main/LICENSE)). diff --git a/build/accounts.js b/build/accounts.js new file mode 100644 index 0000000..0078e84 --- /dev/null +++ b/build/accounts.js @@ -0,0 +1,65 @@ +"use strict"; +exports.__esModule = true; +exports.accountFromAny = void 0; +var math_1 = require("@cosmjs/math"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var utils_1 = require("@cosmjs/utils"); +var auth_1 = require("cosmjs-types/cosmos/auth/v1beta1/auth"); +var vesting_1 = require("cosmjs-types/cosmos/vesting/v1beta1/vesting"); +function uint64FromProto(input) { + return math_1.Uint64.fromString(input.toString()); +} +function accountFromBaseAccount(input) { + var address = input.address, pubKey = input.pubKey, accountNumber = input.accountNumber, sequence = input.sequence; + var pubkey = (0, proto_signing_1.decodePubkey)(pubKey); + return { + address: address, + pubkey: pubkey, + accountNumber: uint64FromProto(accountNumber).toNumber(), + sequence: uint64FromProto(sequence).toNumber() + }; +} +/** + * Takes an `Any` encoded account from the chain and extracts some common + * `Account` information from it. This is supposed to support the most relevant + * common Cosmos SDK account types. If you need support for exotic account types, + * you'll need to write your own account decoder. + */ +function accountFromAny(input) { + var _a, _b, _c, _d, _e, _f, _g; + var typeUrl = input.typeUrl, value = input.value; + switch (typeUrl) { + // auth + case "/cosmos.auth.v1beta1.BaseAccount": + return accountFromBaseAccount(auth_1.BaseAccount.decode(value)); + case "/cosmos.auth.v1beta1.ModuleAccount": { + var baseAccount = auth_1.ModuleAccount.decode(value).baseAccount; + (0, utils_1.assert)(baseAccount); + return accountFromBaseAccount(baseAccount); + } + // vesting + case "/cosmos.vesting.v1beta1.BaseVestingAccount": { + var baseAccount = (_a = vesting_1.BaseVestingAccount.decode(value)) === null || _a === void 0 ? void 0 : _a.baseAccount; + (0, utils_1.assert)(baseAccount); + return accountFromBaseAccount(baseAccount); + } + case "/cosmos.vesting.v1beta1.ContinuousVestingAccount": { + var baseAccount = (_c = (_b = vesting_1.ContinuousVestingAccount.decode(value)) === null || _b === void 0 ? void 0 : _b.baseVestingAccount) === null || _c === void 0 ? void 0 : _c.baseAccount; + (0, utils_1.assert)(baseAccount); + return accountFromBaseAccount(baseAccount); + } + case "/cosmos.vesting.v1beta1.DelayedVestingAccount": { + var baseAccount = (_e = (_d = vesting_1.DelayedVestingAccount.decode(value)) === null || _d === void 0 ? void 0 : _d.baseVestingAccount) === null || _e === void 0 ? void 0 : _e.baseAccount; + (0, utils_1.assert)(baseAccount); + return accountFromBaseAccount(baseAccount); + } + case "/cosmos.vesting.v1beta1.PeriodicVestingAccount": { + var baseAccount = (_g = (_f = vesting_1.PeriodicVestingAccount.decode(value)) === null || _f === void 0 ? void 0 : _f.baseVestingAccount) === null || _g === void 0 ? void 0 : _g.baseAccount; + (0, utils_1.assert)(baseAccount); + return accountFromBaseAccount(baseAccount); + } + default: + throw new Error("Unsupported type: '" + typeUrl + "'"); + } +} +exports.accountFromAny = accountFromAny; diff --git a/build/accounts.spec.js b/build/accounts.spec.js new file mode 100644 index 0000000..d9be9f6 --- /dev/null +++ b/build/accounts.spec.js @@ -0,0 +1,25 @@ +"use strict"; +exports.__esModule = true; +var any_1 = require("cosmjs-types/google/protobuf/any"); +var accounts_1 = require("./accounts"); +describe("accounts", function () { + describe("accountFromAny", function () { + it("works for PeriodicVestingAccount", function () { + // Queried from chain via `packages/cli/examples/get_akash_vesting_account.ts`. + var any = any_1.Any.fromJSON({ + typeUrl: "/cosmos.vesting.v1beta1.PeriodicVestingAccount", + value: "CsMBCnoKLGFrYXNoMXF5MHZ1cjNmbDJ1Y3p0cHpjcmZlYTdtYzhqd3o4eGptdnE3cXZ5EkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohA/XsdhwSIKU73TltD9STcaS07FNw0szR4a+oDLr6vikaGDggGxIUCgR1YWt0EgwxNjY2NjY2NzAwMDAaEwoEdWFrdBILMzcxOTAzMzAwMDAiFAoEdWFrdBIMMTY2NjY2NjcwMDAwKOC9wZkGEODvt/sFGhoIgOeEDxITCgR1YWt0Egs4MzMzMzMzNTAwMBoaCIC/ugcSEwoEdWFrdBILNDE2NjY2Njc1MDAaGgiAqMoHEhMKBHVha3QSCzQxNjY2NjY3NTAw" + }); + var account = (0, accounts_1.accountFromAny)(any); + expect(account).toEqual({ + address: "akash1qy0vur3fl2ucztpzcrfea7mc8jwz8xjmvq7qvy", + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "A/XsdhwSIKU73TltD9STcaS07FNw0szR4a+oDLr6vika" + }, + accountNumber: 56, + sequence: 27 + }); + }); + }); +}); diff --git a/build/aminomsgs.js b/build/aminomsgs.js new file mode 100644 index 0000000..66a6c58 --- /dev/null +++ b/build/aminomsgs.js @@ -0,0 +1,77 @@ +"use strict"; +exports.__esModule = true; +exports.isAminoMsgTransfer = exports.isAminoMsgUndelegate = exports.isAminoMsgBeginRedelegate = exports.isAminoMsgDelegate = exports.isAminoMsgEditValidator = exports.isAminoMsgCreateValidator = exports.isAminoMsgUnjail = exports.isAminoMsgDeposit = exports.isAminoMsgVote = exports.isAminoMsgSubmitProposal = exports.isAminoMsgSubmitEvidence = exports.isAminoMsgFundCommunityPool = exports.isAminoMsgWithdrawValidatorCommission = exports.isAminoMsgWithdrawDelegatorReward = exports.isAminoMsgSetWithdrawAddress = exports.isAminoMsgVerifyInvariant = exports.isAminoMsgMultiSend = exports.isAminoMsgSend = void 0; +function isAminoMsgSend(msg) { + return msg.type === "cosmos-sdk/MsgSend"; +} +exports.isAminoMsgSend = isAminoMsgSend; +function isAminoMsgMultiSend(msg) { + return msg.type === "cosmos-sdk/MsgMultiSend"; +} +exports.isAminoMsgMultiSend = isAminoMsgMultiSend; +function isAminoMsgVerifyInvariant(msg) { + return msg.type === "cosmos-sdk/MsgVerifyInvariant"; +} +exports.isAminoMsgVerifyInvariant = isAminoMsgVerifyInvariant; +function isAminoMsgSetWithdrawAddress(msg) { + // NOTE: Type string and names diverge here! + return msg.type === "cosmos-sdk/MsgModifyWithdrawAddress"; +} +exports.isAminoMsgSetWithdrawAddress = isAminoMsgSetWithdrawAddress; +function isAminoMsgWithdrawDelegatorReward(msg) { + // NOTE: Type string and names diverge here! + return msg.type === "cosmos-sdk/MsgWithdrawDelegationReward"; +} +exports.isAminoMsgWithdrawDelegatorReward = isAminoMsgWithdrawDelegatorReward; +function isAminoMsgWithdrawValidatorCommission(msg) { + return msg.type === "cosmos-sdk/MsgWithdrawValidatorCommission"; +} +exports.isAminoMsgWithdrawValidatorCommission = isAminoMsgWithdrawValidatorCommission; +function isAminoMsgFundCommunityPool(msg) { + return msg.type === "cosmos-sdk/MsgFundCommunityPool"; +} +exports.isAminoMsgFundCommunityPool = isAminoMsgFundCommunityPool; +function isAminoMsgSubmitEvidence(msg) { + return msg.type === "cosmos-sdk/MsgSubmitEvidence"; +} +exports.isAminoMsgSubmitEvidence = isAminoMsgSubmitEvidence; +function isAminoMsgSubmitProposal(msg) { + return msg.type === "cosmos-sdk/MsgSubmitProposal"; +} +exports.isAminoMsgSubmitProposal = isAminoMsgSubmitProposal; +function isAminoMsgVote(msg) { + return msg.type === "cosmos-sdk/MsgVote"; +} +exports.isAminoMsgVote = isAminoMsgVote; +function isAminoMsgDeposit(msg) { + return msg.type === "cosmos-sdk/MsgDeposit"; +} +exports.isAminoMsgDeposit = isAminoMsgDeposit; +function isAminoMsgUnjail(msg) { + return msg.type === "cosmos-sdk/MsgUnjail"; +} +exports.isAminoMsgUnjail = isAminoMsgUnjail; +function isAminoMsgCreateValidator(msg) { + return msg.type === "cosmos-sdk/MsgCreateValidator"; +} +exports.isAminoMsgCreateValidator = isAminoMsgCreateValidator; +function isAminoMsgEditValidator(msg) { + return msg.type === "cosmos-sdk/MsgEditValidator"; +} +exports.isAminoMsgEditValidator = isAminoMsgEditValidator; +function isAminoMsgDelegate(msg) { + return msg.type === "cosmos-sdk/MsgDelegate"; +} +exports.isAminoMsgDelegate = isAminoMsgDelegate; +function isAminoMsgBeginRedelegate(msg) { + return msg.type === "cosmos-sdk/MsgBeginRedelegate"; +} +exports.isAminoMsgBeginRedelegate = isAminoMsgBeginRedelegate; +function isAminoMsgUndelegate(msg) { + return msg.type === "cosmos-sdk/MsgUndelegate"; +} +exports.isAminoMsgUndelegate = isAminoMsgUndelegate; +function isAminoMsgTransfer(msg) { + return msg.type === "cosmos-sdk/MsgTransfer"; +} +exports.isAminoMsgTransfer = isAminoMsgTransfer; diff --git a/build/aminotypes.js b/build/aminotypes.js new file mode 100644 index 0000000..ba6ccbb --- /dev/null +++ b/build/aminotypes.js @@ -0,0 +1,507 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.AminoTypes = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var amino_1 = require("@cosmjs/amino"); +var encoding_1 = require("@cosmjs/encoding"); +var utils_1 = require("@cosmjs/utils"); +var gov_1 = require("cosmjs-types/cosmos/gov/v1beta1/gov"); +var any_1 = require("cosmjs-types/google/protobuf/any"); +var long_1 = require("long"); +function omitDefault(input) { + if (typeof input === "string") { + return input === "" ? undefined : input; + } + if (typeof input === "number") { + return input === 0 ? undefined : input; + } + if (long_1["default"].isLong(input)) { + return input.isZero() ? undefined : input; + } + throw new Error("Got unsupported type '" + typeof input + "'"); +} +function createDefaultTypes(prefix) { + return { + // bank + "/cosmos.bank.v1beta1.MsgSend": { + aminoType: "cosmos-sdk/MsgSend", + toAmino: function (_a) { + var fromAddress = _a.fromAddress, toAddress = _a.toAddress, amount = _a.amount; + return ({ + from_address: fromAddress, + to_address: toAddress, + amount: __spreadArray([], amount, true) + }); + }, + fromAmino: function (_a) { + var from_address = _a.from_address, to_address = _a.to_address, amount = _a.amount; + return ({ + fromAddress: from_address, + toAddress: to_address, + amount: __spreadArray([], amount, true) + }); + } + }, + "/cosmos.bank.v1beta1.MsgMultiSend": { + aminoType: "cosmos-sdk/MsgMultiSend", + toAmino: function (_a) { + var inputs = _a.inputs, outputs = _a.outputs; + return ({ + inputs: inputs.map(function (input) { return ({ + address: input.address, + coins: __spreadArray([], input.coins, true) + }); }), + outputs: outputs.map(function (output) { return ({ + address: output.address, + coins: __spreadArray([], output.coins, true) + }); }) + }); + }, + fromAmino: function (_a) { + var inputs = _a.inputs, outputs = _a.outputs; + return ({ + inputs: inputs.map(function (input) { return ({ + address: input.address, + coins: __spreadArray([], input.coins, true) + }); }), + outputs: outputs.map(function (output) { return ({ + address: output.address, + coins: __spreadArray([], output.coins, true) + }); }) + }); + } + }, + // distribution + "/cosmos.distribution.v1beta1.MsgFundCommunityPool": { + aminoType: "cosmos-sdk/MsgFundCommunityPool", + toAmino: function (_a) { + var amount = _a.amount, depositor = _a.depositor; + return ({ + amount: __spreadArray([], amount, true), + depositor: depositor + }); + }, + fromAmino: function (_a) { + var amount = _a.amount, depositor = _a.depositor; + return ({ + amount: __spreadArray([], amount, true), + depositor: depositor + }); + } + }, + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress": { + aminoType: "cosmos-sdk/MsgModifyWithdrawAddress", + toAmino: function (_a) { + var delegatorAddress = _a.delegatorAddress, withdrawAddress = _a.withdrawAddress; + return ({ + delegator_address: delegatorAddress, + withdraw_address: withdrawAddress + }); + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, withdraw_address = _a.withdraw_address; + return ({ + delegatorAddress: delegator_address, + withdrawAddress: withdraw_address + }); + } + }, + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward": { + aminoType: "cosmos-sdk/MsgWithdrawDelegationReward", + toAmino: function (_a) { + var delegatorAddress = _a.delegatorAddress, validatorAddress = _a.validatorAddress; + return ({ + delegator_address: delegatorAddress, + validator_address: validatorAddress + }); + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, validator_address = _a.validator_address; + return ({ + delegatorAddress: delegator_address, + validatorAddress: validator_address + }); + } + }, + "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission": { + aminoType: "cosmos-sdk/MsgWithdrawValidatorCommission", + toAmino: function (_a) { + var validatorAddress = _a.validatorAddress; + return ({ + validator_address: validatorAddress + }); + }, + fromAmino: function (_a) { + var validator_address = _a.validator_address; + return ({ + validatorAddress: validator_address + }); + } + }, + // gov + "/cosmos.gov.v1beta1.MsgDeposit": { + aminoType: "cosmos-sdk/MsgDeposit", + toAmino: function (_a) { + var amount = _a.amount, depositor = _a.depositor, proposalId = _a.proposalId; + return { + amount: amount, + depositor: depositor, + proposal_id: proposalId.toString() + }; + }, + fromAmino: function (_a) { + var amount = _a.amount, depositor = _a.depositor, proposal_id = _a.proposal_id; + return { + amount: Array.from(amount), + depositor: depositor, + proposalId: long_1["default"].fromString(proposal_id) + }; + } + }, + "/cosmos.gov.v1beta1.MsgVote": { + aminoType: "cosmos-sdk/MsgVote", + toAmino: function (_a) { + var option = _a.option, proposalId = _a.proposalId, voter = _a.voter; + return { + option: option, + proposal_id: proposalId.toString(), + voter: voter + }; + }, + fromAmino: function (_a) { + var option = _a.option, proposal_id = _a.proposal_id, voter = _a.voter; + return { + option: (0, gov_1.voteOptionFromJSON)(option), + proposalId: long_1["default"].fromString(proposal_id), + voter: voter + }; + } + }, + "/cosmos.gov.v1beta1.MsgSubmitProposal": { + aminoType: "cosmos-sdk/MsgSubmitProposal", + toAmino: function (_a) { + var initialDeposit = _a.initialDeposit, proposer = _a.proposer, content = _a.content; + (0, utils_1.assertDefinedAndNotNull)(content); + var proposal; + switch (content.typeUrl) { + case "/cosmos.gov.v1beta1.TextProposal": { + var textProposal = gov_1.TextProposal.decode(content.value); + proposal = { + type: "cosmos-sdk/TextProposal", + value: { + description: textProposal.description, + title: textProposal.title + } + }; + break; + } + default: + throw new Error("Unsupported proposal type: '" + content.typeUrl + "'"); + } + return { + initial_deposit: initialDeposit, + proposer: proposer, + content: proposal + }; + }, + fromAmino: function (_a) { + var initial_deposit = _a.initial_deposit, proposer = _a.proposer, content = _a.content; + var any_content; + switch (content.type) { + case "cosmos-sdk/TextProposal": { + var value = content.value; + (0, utils_1.assert)((0, utils_1.isNonNullObject)(value)); + var _b = value, title = _b.title, description = _b.description; + (0, utils_1.assert)(typeof title === "string"); + (0, utils_1.assert)(typeof description === "string"); + any_content = any_1.Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: gov_1.TextProposal.encode(gov_1.TextProposal.fromPartial({ + title: title, + description: description + })).finish() + }); + break; + } + default: + throw new Error("Unsupported proposal type: '" + content.type + "'"); + } + return { + initialDeposit: Array.from(initial_deposit), + proposer: proposer, + content: any_content + }; + } + }, + // staking + "/cosmos.staking.v1beta1.MsgBeginRedelegate": { + aminoType: "cosmos-sdk/MsgBeginRedelegate", + toAmino: function (_a) { + var delegatorAddress = _a.delegatorAddress, validatorSrcAddress = _a.validatorSrcAddress, validatorDstAddress = _a.validatorDstAddress, amount = _a.amount; + (0, utils_1.assertDefinedAndNotNull)(amount, "missing amount"); + return { + delegator_address: delegatorAddress, + validator_src_address: validatorSrcAddress, + validator_dst_address: validatorDstAddress, + amount: amount + }; + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, validator_src_address = _a.validator_src_address, validator_dst_address = _a.validator_dst_address, amount = _a.amount; + return ({ + delegatorAddress: delegator_address, + validatorSrcAddress: validator_src_address, + validatorDstAddress: validator_dst_address, + amount: amount + }); + } + }, + "/cosmos.staking.v1beta1.MsgCreateValidator": { + aminoType: "cosmos-sdk/MsgCreateValidator", + toAmino: function (_a) { + var description = _a.description, commission = _a.commission, minSelfDelegation = _a.minSelfDelegation, delegatorAddress = _a.delegatorAddress, validatorAddress = _a.validatorAddress, pubkey = _a.pubkey, value = _a.value; + (0, utils_1.assertDefinedAndNotNull)(description, "missing description"); + (0, utils_1.assertDefinedAndNotNull)(commission, "missing commission"); + (0, utils_1.assertDefinedAndNotNull)(pubkey, "missing pubkey"); + (0, utils_1.assertDefinedAndNotNull)(value, "missing value"); + return { + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + security_contact: description.securityContact, + details: description.details + }, + commission: { + rate: commission.rate, + max_rate: commission.maxRate, + max_change_rate: commission.maxChangeRate + }, + min_self_delegation: minSelfDelegation, + delegator_address: delegatorAddress, + validator_address: validatorAddress, + pubkey: (0, amino_1.encodeBech32Pubkey)({ + type: "tendermint/PubKeySecp256k1", + value: (0, encoding_1.toBase64)(pubkey.value) + }, prefix), + value: value + }; + }, + fromAmino: function (_a) { + var description = _a.description, commission = _a.commission, min_self_delegation = _a.min_self_delegation, delegator_address = _a.delegator_address, validator_address = _a.validator_address, pubkey = _a.pubkey, value = _a.value; + var decodedPubkey = (0, amino_1.decodeBech32Pubkey)(pubkey); + if (decodedPubkey.type !== "tendermint/PubKeySecp256k1") { + throw new Error("Only Secp256k1 public keys are supported"); + } + return { + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + securityContact: description.security_contact, + details: description.details + }, + commission: { + rate: commission.rate, + maxRate: commission.max_rate, + maxChangeRate: commission.max_change_rate + }, + minSelfDelegation: min_self_delegation, + delegatorAddress: delegator_address, + validatorAddress: validator_address, + pubkey: { + typeUrl: "/cosmos.crypto.secp256k1.PubKey", + value: (0, encoding_1.fromBase64)(decodedPubkey.value) + }, + value: value + }; + } + }, + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: function (_a) { + var delegatorAddress = _a.delegatorAddress, validatorAddress = _a.validatorAddress, amount = _a.amount; + (0, utils_1.assertDefinedAndNotNull)(amount, "missing amount"); + return { + delegator_address: delegatorAddress, + validator_address: validatorAddress, + amount: amount + }; + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, validator_address = _a.validator_address, amount = _a.amount; + return ({ + delegatorAddress: delegator_address, + validatorAddress: validator_address, + amount: amount + }); + } + }, + "/cosmos.staking.v1beta1.MsgEditValidator": { + aminoType: "cosmos-sdk/MsgEditValidator", + toAmino: function (_a) { + var description = _a.description, commissionRate = _a.commissionRate, minSelfDelegation = _a.minSelfDelegation, validatorAddress = _a.validatorAddress; + (0, utils_1.assertDefinedAndNotNull)(description, "missing description"); + return { + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + security_contact: description.securityContact, + details: description.details + }, + commission_rate: commissionRate, + min_self_delegation: minSelfDelegation, + validator_address: validatorAddress + }; + }, + fromAmino: function (_a) { + var description = _a.description, commission_rate = _a.commission_rate, min_self_delegation = _a.min_self_delegation, validator_address = _a.validator_address; + return ({ + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + securityContact: description.security_contact, + details: description.details + }, + commissionRate: commission_rate, + minSelfDelegation: min_self_delegation, + validatorAddress: validator_address + }); + } + }, + "/cosmos.staking.v1beta1.MsgUndelegate": { + aminoType: "cosmos-sdk/MsgUndelegate", + toAmino: function (_a) { + var delegatorAddress = _a.delegatorAddress, validatorAddress = _a.validatorAddress, amount = _a.amount; + (0, utils_1.assertDefinedAndNotNull)(amount, "missing amount"); + return { + delegator_address: delegatorAddress, + validator_address: validatorAddress, + amount: amount + }; + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, validator_address = _a.validator_address, amount = _a.amount; + return ({ + delegatorAddress: delegator_address, + validatorAddress: validator_address, + amount: amount + }); + } + }, + // ibc + "/ibc.applications.transfer.v1.MsgTransfer": { + aminoType: "cosmos-sdk/MsgTransfer", + toAmino: function (_a) { + var _b, _c, _d; + var sourcePort = _a.sourcePort, sourceChannel = _a.sourceChannel, token = _a.token, sender = _a.sender, receiver = _a.receiver, timeoutHeight = _a.timeoutHeight, timeoutTimestamp = _a.timeoutTimestamp; + return ({ + source_port: sourcePort, + source_channel: sourceChannel, + token: token, + sender: sender, + receiver: receiver, + timeout_height: timeoutHeight + ? { + revision_height: (_b = omitDefault(timeoutHeight.revisionHeight)) === null || _b === void 0 ? void 0 : _b.toString(), + revision_number: (_c = omitDefault(timeoutHeight.revisionNumber)) === null || _c === void 0 ? void 0 : _c.toString() + } + : {}, + timeout_timestamp: (_d = omitDefault(timeoutTimestamp)) === null || _d === void 0 ? void 0 : _d.toString() + }); + }, + fromAmino: function (_a) { + var source_port = _a.source_port, source_channel = _a.source_channel, token = _a.token, sender = _a.sender, receiver = _a.receiver, timeout_height = _a.timeout_height, timeout_timestamp = _a.timeout_timestamp; + return ({ + sourcePort: source_port, + sourceChannel: source_channel, + token: token, + sender: sender, + receiver: receiver, + timeoutHeight: timeout_height + ? { + revisionHeight: long_1["default"].fromString(timeout_height.revision_height || "0", true), + revisionNumber: long_1["default"].fromString(timeout_height.revision_number || "0", true) + } + : undefined, + timeoutTimestamp: long_1["default"].fromString(timeout_timestamp || "0", true) + }); + } + } + }; +} +/** + * A map from Stargate message types as used in the messages's `Any` type + * to Amino types. + */ +var AminoTypes = /** @class */ (function () { + function AminoTypes(_a) { + var _b = _a === void 0 ? {} : _a, _c = _b.additions, additions = _c === void 0 ? {} : _c, _d = _b.prefix, prefix = _d === void 0 ? "cosmos" : _d; + var additionalAminoTypes = Object.values(additions); + var filteredDefaultTypes = Object.entries(createDefaultTypes(prefix)).reduce(function (acc, _a) { + var _b; + var key = _a[0], value = _a[1]; + return additionalAminoTypes.find(function (_a) { + var aminoType = _a.aminoType; + return value.aminoType === aminoType; + }) + ? acc + : __assign(__assign({}, acc), (_b = {}, _b[key] = value, _b)); + }, {}); + this.register = __assign(__assign({}, filteredDefaultTypes), additions); + } + AminoTypes.prototype.toAmino = function (_a) { + var typeUrl = _a.typeUrl, value = _a.value; + var converter = this.register[typeUrl]; + if (!converter) { + throw new Error("Type URL does not exist in the Amino message type register. " + + "If you need support for this message type, you can pass in additional entries to the AminoTypes constructor. " + + "If you think this message type should be included by default, please open an issue at https://github.com/cosmos/cosmjs/issues."); + } + return { + type: converter.aminoType, + value: converter.toAmino(value) + }; + }; + AminoTypes.prototype.fromAmino = function (_a) { + var type = _a.type, value = _a.value; + var result = Object.entries(this.register).find(function (_a) { + var _typeUrl = _a[0], aminoType = _a[1].aminoType; + return aminoType === type; + }); + if (!result) { + throw new Error("Type does not exist in the Amino message type register. " + + "If you need support for this message type, you can pass in additional entries to the AminoTypes constructor. " + + "If you think this message type should be included by default, please open an issue at https://github.com/cosmos/cosmjs/issues."); + } + var typeUrl = result[0], converter = result[1]; + return { + typeUrl: typeUrl, + value: converter.fromAmino(value) + }; + }; + return AminoTypes; +}()); +exports.AminoTypes = AminoTypes; diff --git a/build/aminotypes.spec.js b/build/aminotypes.spec.js new file mode 100644 index 0000000..ca6a63a --- /dev/null +++ b/build/aminotypes.spec.js @@ -0,0 +1,982 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention */ +var amino_1 = require("@cosmjs/amino"); +var encoding_1 = require("@cosmjs/encoding"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var gov_1 = require("cosmjs-types/cosmos/gov/v1beta1/gov"); +var long_1 = require("long"); +var aminotypes_1 = require("./aminotypes"); +describe("AminoTypes", function () { + describe("toAmino", function () { + // bank + it("works for MsgSend", function () { + var msg = { + fromAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + toAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coins)(1234, "ucosm") + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgSend", + value: { + from_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + to_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coins)(1234, "ucosm") + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgMultiSend", function () { + var msg = { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: (0, proto_signing_1.coins)(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: (0, proto_signing_1.coins)(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: (0, proto_signing_1.coins)(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: (0, proto_signing_1.coins)(912, "ucosm") }, + ] + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.bank.v1beta1.MsgMultiSend", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgMultiSend", + value: { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: (0, proto_signing_1.coins)(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: (0, proto_signing_1.coins)(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: (0, proto_signing_1.coins)(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: (0, proto_signing_1.coins)(912, "ucosm") }, + ] + } + }; + expect(aminoMsg).toEqual(expected); + }); + // gov + it("works for MsgDeposit", function () { + var msg = { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposalId: long_1["default"].fromNumber(5) + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.gov.v1beta1.MsgDeposit", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgDeposit", + value: { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposal_id: "5" + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgSubmitProposal", function () { + var msg = { + initialDeposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: gov_1.TextProposal.encode({ + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal" + }).finish() + } + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgSubmitProposal", + value: { + initial_deposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + type: "cosmos-sdk/TextProposal", + value: { + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal" + } + } + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgVote", function () { + var msg = { + option: gov_1.VoteOption.VOTE_OPTION_NO_WITH_VETO, + proposalId: long_1["default"].fromNumber(5), + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k" + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgVote", + value: { + option: 4, + proposal_id: "5", + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k" + } + }; + expect(aminoMsg).toEqual(expected); + }); + // distribution + it("works for MsgFundCommunityPool", function () { return __awaiter(void 0, void 0, void 0, function () { + var msg, aminoMsg, expected; + return __generator(this, function (_a) { + msg = { + amount: (0, proto_signing_1.coins)(1234, "ucosm"), + depositor: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" + }; + aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + value: msg + }); + expected = { + type: "cosmos-sdk/MsgFundCommunityPool", + value: { + amount: (0, proto_signing_1.coins)(1234, "ucosm"), + depositor: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" + } + }; + expect(aminoMsg).toEqual(expected); + return [2 /*return*/]; + }); + }); }); + it("works for MsgSetWithdrawAddress", function () { return __awaiter(void 0, void 0, void 0, function () { + var msg, aminoMsg, expected; + return __generator(this, function (_a) { + msg = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + withdrawAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + }; + aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + value: msg + }); + expected = { + type: "cosmos-sdk/MsgModifyWithdrawAddress", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + withdraw_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + } + }; + expect(aminoMsg).toEqual(expected); + return [2 /*return*/]; + }); + }); }); + it("works for MsgWithdrawDelegatorReward", function () { return __awaiter(void 0, void 0, void 0, function () { + var msg, aminoMsg, expected; + return __generator(this, function (_a) { + msg = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + }; + aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: msg + }); + expected = { + type: "cosmos-sdk/MsgWithdrawDelegationReward", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + } + }; + expect(aminoMsg).toEqual(expected); + return [2 /*return*/]; + }); + }); }); + it("works for MsgWithdrawValidatorCommission", function () { return __awaiter(void 0, void 0, void 0, function () { + var msg, aminoMsg, expected; + return __generator(this, function (_a) { + msg = { + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + }; + aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", + value: msg + }); + expected = { + type: "cosmos-sdk/MsgWithdrawValidatorCommission", + value: { + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + } + }; + expect(aminoMsg).toEqual(expected); + return [2 /*return*/]; + }); + }); }); + // staking + it("works for MsgBeginRedelegate", function () { + var msg = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorSrcAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validatorDstAddress: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgBeginRedelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_src_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validator_dst_address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgCreateValidator", function () { + var msg = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "..." + }, + commission: { + rate: "0.2", + maxRate: "0.3", + maxChangeRate: "0.1" + }, + minSelfDelegation: "123", + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: { + typeUrl: "/cosmos.crypto.secp256k1.PubKey", + value: (0, encoding_1.fromBase64)("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ") + }, + value: (0, proto_signing_1.coin)(1234, "ucosm") + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgCreateValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "..." + }, + commission: { + rate: "0.2", + max_rate: "0.3", + max_change_rate: "0.1" + }, + min_self_delegation: "123", + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: (0, amino_1.encodeBech32Pubkey)({ type: "tendermint/PubKeySecp256k1", value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" }, "cosmos"), + value: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgDelegate", function () { + var msg = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgEditValidator", function () { + var msg = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "..." + }, + commissionRate: "0.2", + minSelfDelegation: "123", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgEditValidator", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgEditValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "..." + }, + commission_rate: "0.2", + min_self_delegation: "123", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgUndelegate", function () { + var msg = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgUndelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + expect(aminoMsg).toEqual(expected); + }); + // ibc + it("works for MsgTransfer", function () { + var msg = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: long_1["default"].fromString("123", true), + revisionNumber: long_1["default"].fromString("456", true) + }, + timeoutTimestamp: long_1["default"].fromString("789", true) + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: "123", + revision_number: "456" + }, + timeout_timestamp: "789" + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgTransfer with empty values", function () { + var msg = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: long_1["default"].UZERO, + revisionNumber: long_1["default"].UZERO + }, + timeoutTimestamp: long_1["default"].UZERO + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: undefined, + revision_number: undefined + }, + timeout_timestamp: undefined + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("works for MsgTransfer with no height timeout", function () { + var msg = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: undefined, + timeoutTimestamp: long_1["default"].UZERO + }; + var aminoMsg = new aminotypes_1.AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg + }); + var expected = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: {}, + timeout_timestamp: undefined + } + }; + expect(aminoMsg).toEqual(expected); + }); + // other + it("works with custom type url", function () { + var msg = { + foo: "bar" + }; + var aminoMsg = new aminotypes_1.AminoTypes({ + additions: { + "/my.CustomType": { + aminoType: "my-sdk/CustomType", + toAmino: function (_a) { + var foo = _a.foo; + return ({ + foo: "amino-prefix-" + foo, + constant: "something-for-amino" + }); + }, + fromAmino: function () { } + } + } + }).toAmino({ typeUrl: "/my.CustomType", value: msg }); + expect(aminoMsg).toEqual({ + type: "my-sdk/CustomType", + value: { + foo: "amino-prefix-bar", + constant: "something-for-amino" + } + }); + }); + it("works with overridden type url", function () { + var msg = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + var aminoMsg = new aminotypes_1.AminoTypes({ + additions: { + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "my-override/MsgDelegate", + toAmino: function (m) { + var _a; + return ({ + foo: (_a = m.delegatorAddress) !== null && _a !== void 0 ? _a : "" + }); + }, + fromAmino: function () { } + } + } + }).toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }); + var expected = { + type: "my-override/MsgDelegate", + value: { + foo: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" + } + }; + expect(aminoMsg).toEqual(expected); + }); + it("throws for unknown type url", function () { + expect(function () { return new aminotypes_1.AminoTypes().toAmino({ typeUrl: "/xxx.Unknown", value: { foo: "bar" } }); }).toThrowError(/Type URL does not exist in the Amino message type register./i); + }); + }); + describe("fromAmino", function () { + // bank + it("works for MsgSend", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgSend", + value: { + from_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + to_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coins)(1234, "ucosm") + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + fromAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + toAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coins)(1234, "ucosm") + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: expectedValue + }); + }); + it("works for MsgMultiSend", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgMultiSend", + value: { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: (0, proto_signing_1.coins)(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: (0, proto_signing_1.coins)(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: (0, proto_signing_1.coins)(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: (0, proto_signing_1.coins)(912, "ucosm") }, + ] + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: (0, proto_signing_1.coins)(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: (0, proto_signing_1.coins)(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: (0, proto_signing_1.coins)(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: (0, proto_signing_1.coins)(912, "ucosm") }, + ] + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.bank.v1beta1.MsgMultiSend", + value: expectedValue + }); + }); + // gov + it("works for MsgDeposit", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgDeposit", + value: { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposal_id: "5" + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposalId: long_1["default"].fromNumber(5) + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.gov.v1beta1.MsgDeposit", + value: expectedValue + }); + }); + it("works for MsgSubmitProposal", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgSubmitProposal", + value: { + initial_deposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + type: "cosmos-sdk/TextProposal", + value: { + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal" + } + } + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + initialDeposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: gov_1.TextProposal.encode({ + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal" + }).finish() + } + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal", + value: expectedValue + }); + }); + it("works for MsgVote", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgVote", + value: { + option: 4, + proposal_id: "5", + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k" + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + option: gov_1.VoteOption.VOTE_OPTION_NO_WITH_VETO, + proposalId: long_1["default"].fromNumber(5), + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k" + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: expectedValue + }); + }); + // distribution + // TODO: MsgFundCommunityPool + // TODO: MsgSetWithdrawAddress + // TODO: MsgWithdrawDelegatorReward + // TODO: MsgWithdrawValidatorCommission + // staking + it("works for MsgBeginRedelegate", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgBeginRedelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_src_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validator_dst_address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorSrcAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validatorDstAddress: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate", + value: expectedValue + }); + }); + it("works for MsgCreateValidator", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgCreateValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "..." + }, + commission: { + rate: "0.2", + max_rate: "0.3", + max_change_rate: "0.1" + }, + min_self_delegation: "123", + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: (0, amino_1.encodeBech32Pubkey)({ type: "tendermint/PubKeySecp256k1", value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" }, "cosmos"), + value: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "..." + }, + commission: { + rate: "0.2", + maxRate: "0.3", + maxChangeRate: "0.1" + }, + minSelfDelegation: "123", + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: { + typeUrl: "/cosmos.crypto.secp256k1.PubKey", + value: (0, encoding_1.fromBase64)("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ") + }, + value: (0, proto_signing_1.coin)(1234, "ucosm") + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator", + value: expectedValue + }); + }); + it("works for MsgDelegate", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: expectedValue + }); + }); + it("works for MsgEditValidator", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgEditValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "..." + }, + commission_rate: "0.2", + min_self_delegation: "123", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "..." + }, + commissionRate: "0.2", + minSelfDelegation: "123", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5" + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgEditValidator", + value: expectedValue + }); + }); + it("works for MsgUndelegate", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgUndelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: expectedValue + }); + }); + // ibc + it("works for MsgTransfer", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: "123", + revision_number: "456" + }, + timeout_timestamp: "789" + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: long_1["default"].fromString("123", true), + revisionNumber: long_1["default"].fromString("456", true) + }, + timeoutTimestamp: long_1["default"].fromString("789", true) + }; + expect(msg).toEqual({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: expectedValue + }); + }); + it("works for MsgTransfer with default values", function () { + var aminoMsg = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + // revision_height omitted + // revision_number omitted + } + } + }; + var msg = new aminotypes_1.AminoTypes().fromAmino(aminoMsg); + var expectedValue = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: (0, proto_signing_1.coin)(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: long_1["default"].UZERO, + revisionNumber: long_1["default"].UZERO + }, + timeoutTimestamp: long_1["default"].UZERO + }; + expect(msg).toEqual({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: expectedValue + }); + }); + // other + it("works for custom type url", function () { + var aminoMsg = { + type: "my-sdk/CustomType", + value: { + foo: "amino-prefix-bar", + constant: "something-for-amino" + } + }; + var msg = new aminotypes_1.AminoTypes({ + additions: { + "/my.CustomType": { + aminoType: "my-sdk/CustomType", + toAmino: function () { }, + fromAmino: function (_a) { + var foo = _a.foo; + return ({ + foo: foo.slice(13) + }); + } + } + } + }).fromAmino(aminoMsg); + var expectedValue = { + foo: "bar" + }; + expect(msg).toEqual({ + typeUrl: "/my.CustomType", + value: expectedValue + }); + }); + it("works with overridden type url", function () { + var msg = new aminotypes_1.AminoTypes({ + additions: { + "/my.OverrideType": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: function () { }, + fromAmino: function (_a) { + var foo = _a.foo; + return ({ + delegatorAddress: foo, + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + }); + } + } + } + }).fromAmino({ + type: "cosmos-sdk/MsgDelegate", + value: { + foo: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" + } + }); + var expected = { + typeUrl: "/my.OverrideType", + value: { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: (0, proto_signing_1.coin)(1234, "ucosm") + } + }; + expect(msg).toEqual(expected); + }); + it("throws for unknown type url", function () { + expect(function () { + return new aminotypes_1.AminoTypes().fromAmino({ type: "cosmos-sdk/MsgUnknown", value: { foo: "bar" } }); + }).toThrowError(/Type does not exist in the Amino message type register./i); + }); + }); +}); diff --git a/build/encodeobjects.js b/build/encodeobjects.js new file mode 100644 index 0000000..2cc0617 --- /dev/null +++ b/build/encodeobjects.js @@ -0,0 +1,36 @@ +"use strict"; +exports.__esModule = true; +exports.isMsgVoteEncodeObject = exports.isMsgSubmitProposalEncodeObject = exports.isMsgDepositEncodeObject = exports.isMsgTransferEncodeObject = exports.isMsgWithdrawDelegatorRewardEncodeObject = exports.isMsgUndelegateEncodeObject = exports.isMsgDelegateEncodeObject = exports.isMsgSendEncodeObject = void 0; +function isMsgSendEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/cosmos.bank.v1beta1.MsgSend"; +} +exports.isMsgSendEncodeObject = isMsgSendEncodeObject; +function isMsgDelegateEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/cosmos.staking.v1beta1.MsgDelegate"; +} +exports.isMsgDelegateEncodeObject = isMsgDelegateEncodeObject; +function isMsgUndelegateEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/cosmos.staking.v1beta1.MsgUndelegate"; +} +exports.isMsgUndelegateEncodeObject = isMsgUndelegateEncodeObject; +function isMsgWithdrawDelegatorRewardEncodeObject(encodeObject) { + return (encodeObject.typeUrl === + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"); +} +exports.isMsgWithdrawDelegatorRewardEncodeObject = isMsgWithdrawDelegatorRewardEncodeObject; +function isMsgTransferEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/ibc.applications.transfer.v1.MsgTransfer"; +} +exports.isMsgTransferEncodeObject = isMsgTransferEncodeObject; +function isMsgDepositEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/cosmos.gov.v1beta1.MsgDeposit"; +} +exports.isMsgDepositEncodeObject = isMsgDepositEncodeObject; +function isMsgSubmitProposalEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/cosmos.gov.v1beta1.MsgSubmitProposal"; +} +exports.isMsgSubmitProposalEncodeObject = isMsgSubmitProposalEncodeObject; +function isMsgVoteEncodeObject(encodeObject) { + return encodeObject.typeUrl === "/cosmos.gov.v1beta1.MsgVote"; +} +exports.isMsgVoteEncodeObject = isMsgVoteEncodeObject; diff --git a/build/fee.js b/build/fee.js new file mode 100644 index 0000000..5e7bc41 --- /dev/null +++ b/build/fee.js @@ -0,0 +1,60 @@ +"use strict"; +exports.__esModule = true; +exports.calculateFee = exports.GasPrice = void 0; +var math_1 = require("@cosmjs/math"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +/** + * Denom checker for the Cosmos SDK 0.42 denom pattern + * (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601). + * + * This is like a regexp but with helpful error messages. + */ +function checkDenom(denom) { + if (denom.length < 3 || denom.length > 128) { + throw new Error("Denom must be between 3 and 128 characters"); + } +} +/** + * A gas price, i.e. the price of a single unit of gas. This is typically a fraction of + * the smallest fee token unit, such as 0.012utoken. + * + * This is the same as GasPrice from @cosmjs/launchpad but those might diverge in the future. + */ +var GasPrice = /** @class */ (function () { + function GasPrice(amount, denom) { + this.amount = amount; + this.denom = denom; + } + /** + * Parses a gas price formatted as ``, e.g. `GasPrice.fromString("0.012utoken")`. + * + * The denom must match the Cosmos SDK 0.42 pattern (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601). + * See `GasPrice` in @cosmjs/stargate for a more generic matcher. + * + * Separators are not yet supported. + */ + GasPrice.fromString = function (gasPrice) { + // Use Decimal.fromUserInput and checkDenom for detailed checks and helpful error messages + var matchResult = gasPrice.match(/^([0-9.]+)([a-z][a-z0-9]*)$/i); + if (!matchResult) { + throw new Error("Invalid gas price string"); + } + var _ = matchResult[0], amount = matchResult[1], denom = matchResult[2]; + checkDenom(denom); + var fractionalDigits = 18; + var decimalAmount = math_1.Decimal.fromUserInput(amount, fractionalDigits); + return new GasPrice(decimalAmount, denom); + }; + return GasPrice; +}()); +exports.GasPrice = GasPrice; +function calculateFee(gasLimit, gasPrice) { + var processedGasPrice = typeof gasPrice === "string" ? GasPrice.fromString(gasPrice) : gasPrice; + var denom = processedGasPrice.denom, gasPriceAmount = processedGasPrice.amount; + var amount = Math.ceil(gasPriceAmount.multiply(new math_1.Uint53(gasLimit)).toFloatApproximation()); + return { + amount: (0, proto_signing_1.coins)(amount, denom), + gas: gasLimit.toString() + }; +} +exports.calculateFee = calculateFee; diff --git a/build/fee.spec.js b/build/fee.spec.js new file mode 100644 index 0000000..800d9ff --- /dev/null +++ b/build/fee.spec.js @@ -0,0 +1,76 @@ +"use strict"; +exports.__esModule = true; +var math_1 = require("@cosmjs/math"); +var fee_1 = require("./fee"); +describe("GasPrice", function () { + it("can be constructed", function () { + var inputs = ["3.14", "3", "0.14"]; + inputs.forEach(function (input) { + var gasPrice = new fee_1.GasPrice(math_1.Decimal.fromUserInput(input, 18), "utest"); + expect(gasPrice.amount.toString()).toEqual(input); + expect(gasPrice.denom).toEqual("utest"); + }); + }); + describe("fromString", function () { + it("works", function () { + var inputs = { + // Test amounts + "3.14utest": { amount: "3.14", denom: "utest" }, + "3utest": { amount: "3", denom: "utest" }, + "0.14utest": { amount: "0.14", denom: "utest" }, + // Test denoms + "0.14sht": { amount: "0.14", denom: "sht" }, + "0.14testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest": { + amount: "0.14", + denom: "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest" + }, + "0.14ucoin2": { amount: "0.14", denom: "ucoin2" }, + // eslint-disable-next-line @typescript-eslint/naming-convention + "0.14FOOBAR": { amount: "0.14", denom: "FOOBAR" } + }; + for (var _i = 0, _a = Object.entries(inputs); _i < _a.length; _i++) { + var _b = _a[_i], input = _b[0], expected = _b[1]; + var gasPrice = fee_1.GasPrice.fromString(input); + expect(gasPrice.amount.toString()).withContext("Input: " + input).toEqual(expected.amount); + expect(gasPrice.denom).withContext("Input: " + input).toEqual(expected.denom); + } + }); + it("errors for invalid gas price", function () { + // Checks basic format + expect(function () { return fee_1.GasPrice.fromString(""); }).toThrowError(/Invalid gas price string/i); + expect(function () { return fee_1.GasPrice.fromString("utkn"); }).toThrowError(/Invalid gas price string/i); + expect(function () { return fee_1.GasPrice.fromString("@utkn"); }).toThrowError(/Invalid gas price string/i); + expect(function () { return fee_1.GasPrice.fromString("234"); }).toThrowError(/Invalid gas price string/i); + expect(function () { return fee_1.GasPrice.fromString("-234tkn"); }).toThrowError(/Invalid gas price string/i); + // Checks details of + expect(function () { return fee_1.GasPrice.fromString("234t"); }).toThrowError(/denom must be between 3 and 128 characters/i); + expect(function () { return fee_1.GasPrice.fromString("234tt"); }).toThrowError(/denom must be between 3 and 128 characters/i); + expect(function () { + return fee_1.GasPrice.fromString("234ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"); + }).toThrowError(/denom must be between 3 and 128 characters/i); + // Checks details of + expect(function () { return fee_1.GasPrice.fromString("3.utkn"); }).toThrowError(/Fractional part missing/i); + expect(function () { return fee_1.GasPrice.fromString("..utkn"); }).toThrowError(/More than one separator found/i); + }); + }); +}); +describe("calculateFee", function () { + it("multiplies the gas price by the gas limit", function () { + var gasLimit = 80000; + var gasPrice = fee_1.GasPrice.fromString("0.025ucosm"); + var fee = (0, fee_1.calculateFee)(gasLimit, gasPrice); + expect(fee).toEqual({ + amount: [{ amount: "2000", denom: "ucosm" }], + gas: "80000" + }); + }); + it("accepts a string gas price", function () { + var gasLimit = 80000; + var gasPrice = "0.025ucosm"; + var fee = (0, fee_1.calculateFee)(gasLimit, gasPrice); + expect(fee).toEqual({ + amount: [{ amount: "2000", denom: "ucosm" }], + gas: "80000" + }); + }); +}); diff --git a/build/index.js b/build/index.js new file mode 100644 index 0000000..480448d --- /dev/null +++ b/build/index.js @@ -0,0 +1,80 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +exports.__esModule = true; +exports.assertIsDeliverTxSuccess = exports.assertIsDeliverTxFailure = exports.SigningStargateClient = exports.defaultRegistryTypes = exports.isSearchByTagsQuery = exports.isSearchBySentFromOrToQuery = exports.isSearchByHeightQuery = exports.setupTxExtension = exports.setupStakingExtension = exports.setupMintExtension = exports.setupIbcExtension = exports.setupGovExtension = exports.setupDistributionExtension = exports.setupBankExtension = exports.setupAuthExtension = exports.QueryClient = exports.decodeCosmosSdkDecFromProto = exports.createProtobufRpcClient = exports.createPagination = exports.makeMultisignedTx = exports.logs = exports.GasPrice = exports.calculateFee = exports.isMsgWithdrawDelegatorRewardEncodeObject = exports.isMsgVoteEncodeObject = exports.isMsgUndelegateEncodeObject = exports.isMsgTransferEncodeObject = exports.isMsgSubmitProposalEncodeObject = exports.isMsgSendEncodeObject = exports.isMsgDepositEncodeObject = exports.isMsgDelegateEncodeObject = exports.AminoTypes = exports.isAminoMsgWithdrawValidatorCommission = exports.isAminoMsgWithdrawDelegatorReward = exports.isAminoMsgVote = exports.isAminoMsgVerifyInvariant = exports.isAminoMsgUnjail = exports.isAminoMsgUndelegate = exports.isAminoMsgSubmitProposal = exports.isAminoMsgSubmitEvidence = exports.isAminoMsgSetWithdrawAddress = exports.isAminoMsgSend = exports.isAminoMsgMultiSend = exports.isAminoMsgFundCommunityPool = exports.isAminoMsgEditValidator = exports.isAminoMsgDeposit = exports.isAminoMsgDelegate = exports.isAminoMsgCreateValidator = exports.isAminoMsgBeginRedelegate = exports.accountFromAny = void 0; +exports.parseCoins = exports.makeCosmoshubPath = exports.coins = exports.coin = exports.TimeoutError = exports.StargateClient = exports.isDeliverTxSuccess = exports.isDeliverTxFailure = void 0; +var accounts_1 = require("./accounts"); +__createBinding(exports, accounts_1, "accountFromAny"); +var aminomsgs_1 = require("./aminomsgs"); +__createBinding(exports, aminomsgs_1, "isAminoMsgBeginRedelegate"); +__createBinding(exports, aminomsgs_1, "isAminoMsgCreateValidator"); +__createBinding(exports, aminomsgs_1, "isAminoMsgDelegate"); +__createBinding(exports, aminomsgs_1, "isAminoMsgDeposit"); +__createBinding(exports, aminomsgs_1, "isAminoMsgEditValidator"); +__createBinding(exports, aminomsgs_1, "isAminoMsgFundCommunityPool"); +__createBinding(exports, aminomsgs_1, "isAminoMsgMultiSend"); +__createBinding(exports, aminomsgs_1, "isAminoMsgSend"); +__createBinding(exports, aminomsgs_1, "isAminoMsgSetWithdrawAddress"); +__createBinding(exports, aminomsgs_1, "isAminoMsgSubmitEvidence"); +__createBinding(exports, aminomsgs_1, "isAminoMsgSubmitProposal"); +__createBinding(exports, aminomsgs_1, "isAminoMsgUndelegate"); +__createBinding(exports, aminomsgs_1, "isAminoMsgUnjail"); +__createBinding(exports, aminomsgs_1, "isAminoMsgVerifyInvariant"); +__createBinding(exports, aminomsgs_1, "isAminoMsgVote"); +__createBinding(exports, aminomsgs_1, "isAminoMsgWithdrawDelegatorReward"); +__createBinding(exports, aminomsgs_1, "isAminoMsgWithdrawValidatorCommission"); +var aminotypes_1 = require("./aminotypes"); +__createBinding(exports, aminotypes_1, "AminoTypes"); +var encodeobjects_1 = require("./encodeobjects"); +__createBinding(exports, encodeobjects_1, "isMsgDelegateEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgDepositEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgSendEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgSubmitProposalEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgTransferEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgUndelegateEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgVoteEncodeObject"); +__createBinding(exports, encodeobjects_1, "isMsgWithdrawDelegatorRewardEncodeObject"); +var fee_1 = require("./fee"); +__createBinding(exports, fee_1, "calculateFee"); +__createBinding(exports, fee_1, "GasPrice"); +exports.logs = require("./logs"); +var multisignature_1 = require("./multisignature"); +__createBinding(exports, multisignature_1, "makeMultisignedTx"); +var queries_1 = require("./queries"); +__createBinding(exports, queries_1, "createPagination"); +__createBinding(exports, queries_1, "createProtobufRpcClient"); +__createBinding(exports, queries_1, "decodeCosmosSdkDecFromProto"); +__createBinding(exports, queries_1, "QueryClient"); +__createBinding(exports, queries_1, "setupAuthExtension"); +__createBinding(exports, queries_1, "setupBankExtension"); +__createBinding(exports, queries_1, "setupDistributionExtension"); +__createBinding(exports, queries_1, "setupGovExtension"); +__createBinding(exports, queries_1, "setupIbcExtension"); +__createBinding(exports, queries_1, "setupMintExtension"); +__createBinding(exports, queries_1, "setupStakingExtension"); +__createBinding(exports, queries_1, "setupTxExtension"); +var search_1 = require("./search"); +__createBinding(exports, search_1, "isSearchByHeightQuery"); +__createBinding(exports, search_1, "isSearchBySentFromOrToQuery"); +__createBinding(exports, search_1, "isSearchByTagsQuery"); +var signingstargateclient_1 = require("./signingstargateclient"); +__createBinding(exports, signingstargateclient_1, "defaultRegistryTypes"); +__createBinding(exports, signingstargateclient_1, "SigningStargateClient"); +var stargateclient_1 = require("./stargateclient"); +__createBinding(exports, stargateclient_1, "assertIsDeliverTxFailure"); +__createBinding(exports, stargateclient_1, "assertIsDeliverTxSuccess"); +__createBinding(exports, stargateclient_1, "isDeliverTxFailure"); +__createBinding(exports, stargateclient_1, "isDeliverTxSuccess"); +__createBinding(exports, stargateclient_1, "StargateClient"); +__createBinding(exports, stargateclient_1, "TimeoutError"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +__createBinding(exports, proto_signing_1, "coin"); +__createBinding(exports, proto_signing_1, "coins"); +__createBinding(exports, proto_signing_1, "makeCosmoshubPath"); +__createBinding(exports, proto_signing_1, "parseCoins"); diff --git a/build/logs.js b/build/logs.js new file mode 100644 index 0000000..b166551 --- /dev/null +++ b/build/logs.js @@ -0,0 +1,87 @@ +"use strict"; +exports.__esModule = true; +exports.findAttribute = exports.parseRawLog = exports.parseLogs = exports.parseLog = exports.parseEvent = exports.parseAttribute = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var utils_1 = require("@cosmjs/utils"); +function parseAttribute(input) { + if (!(0, utils_1.isNonNullObject)(input)) + throw new Error("Attribute must be a non-null object"); + var _a = input, key = _a.key, value = _a.value; + if (typeof key !== "string" || !key) + throw new Error("Attribute's key must be a non-empty string"); + if (typeof value !== "string" && typeof value !== "undefined") { + throw new Error("Attribute's value must be a string or unset"); + } + return { + key: key, + value: value || "" + }; +} +exports.parseAttribute = parseAttribute; +function parseEvent(input) { + if (!(0, utils_1.isNonNullObject)(input)) + throw new Error("Event must be a non-null object"); + var _a = input, type = _a.type, attributes = _a.attributes; + if (typeof type !== "string" || type === "") { + throw new Error("Event type must be a non-empty string"); + } + if (!Array.isArray(attributes)) + throw new Error("Event's attributes must be an array"); + return { + type: type, + attributes: attributes.map(parseAttribute) + }; +} +exports.parseEvent = parseEvent; +function parseLog(input) { + if (!(0, utils_1.isNonNullObject)(input)) + throw new Error("Log must be a non-null object"); + var _a = input, msg_index = _a.msg_index, log = _a.log, events = _a.events; + if (typeof msg_index !== "number") + throw new Error("Log's msg_index must be a number"); + if (typeof log !== "string") + throw new Error("Log's log must be a string"); + if (!Array.isArray(events)) + throw new Error("Log's events must be an array"); + return { + msg_index: msg_index, + log: log, + events: events.map(parseEvent) + }; +} +exports.parseLog = parseLog; +function parseLogs(input) { + if (!Array.isArray(input)) + throw new Error("Logs must be an array"); + return input.map(parseLog); +} +exports.parseLogs = parseLogs; +function parseRawLog(input) { + if (input === void 0) { input = "[]"; } + var logsToParse = JSON.parse(input).map(function (_a, i) { + var events = _a.events; + return ({ + msg_index: i, + events: events, + log: "" + }); + }); + return parseLogs(logsToParse); +} +exports.parseRawLog = parseRawLog; +/** + * Searches in logs for the first event of the given event type and in that event + * for the first first attribute with the given attribute key. + * + * Throws if the attribute was not found. + */ +function findAttribute(logs, eventType, attrKey) { + var _a; + var firstLogs = logs.find(function () { return true; }); + var out = (_a = firstLogs === null || firstLogs === void 0 ? void 0 : firstLogs.events.find(function (event) { return event.type === eventType; })) === null || _a === void 0 ? void 0 : _a.attributes.find(function (attr) { return attr.key === attrKey; }); + if (!out) { + throw new Error("Could not find attribute '" + attrKey + "' in first event of type '" + eventType + "' in first log."); + } + return out; +} +exports.findAttribute = findAttribute; diff --git a/build/multisignature.js b/build/multisignature.js new file mode 100644 index 0000000..1ef90da --- /dev/null +++ b/build/multisignature.js @@ -0,0 +1,73 @@ +"use strict"; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.makeMultisignedTx = exports.makeCompactBitArray = void 0; +var amino_1 = require("@cosmjs/amino"); +var encoding_1 = require("@cosmjs/encoding"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var multisig_1 = require("cosmjs-types/cosmos/crypto/multisig/v1beta1/multisig"); +var signing_1 = require("cosmjs-types/cosmos/tx/signing/v1beta1/signing"); +var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var tx_2 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var long_1 = require("long"); +function makeCompactBitArray(bits) { + var byteCount = Math.ceil(bits.length / 8); + var extraBits = bits.length - Math.floor(bits.length / 8) * 8; + var bytes = new Uint8Array(byteCount); // zero-filled + bits.forEach(function (value, index) { + var bytePos = Math.floor(index / 8); + var bitPos = index % 8; + // eslint-disable-next-line no-bitwise + if (value) + bytes[bytePos] |= 1 << (8 - 1 - bitPos); + }); + return multisig_1.CompactBitArray.fromPartial({ elems: bytes, extraBitsStored: extraBits }); +} +exports.makeCompactBitArray = makeCompactBitArray; +function makeMultisignedTx(multisigPubkey, sequence, fee, bodyBytes, signatures) { + var addresses = Array.from(signatures.keys()); + var prefix = encoding_1.Bech32.decode(addresses[0]).prefix; + var signers = Array(multisigPubkey.value.pubkeys.length).fill(false); + var signaturesList = new Array(); + for (var i = 0; i < multisigPubkey.value.pubkeys.length; i++) { + var signerAddress = (0, amino_1.pubkeyToAddress)(multisigPubkey.value.pubkeys[i], prefix); + var signature = signatures.get(signerAddress); + if (signature) { + signers[i] = true; + signaturesList.push(signature); + } + } + var signerInfo = { + publicKey: (0, proto_signing_1.encodePubkey)(multisigPubkey), + modeInfo: { + multi: { + bitarray: makeCompactBitArray(signers), + modeInfos: signaturesList.map(function (_) { return ({ single: { mode: signing_1.SignMode.SIGN_MODE_LEGACY_AMINO_JSON } }); }) + } + }, + sequence: long_1["default"].fromNumber(sequence) + }; + var authInfo = tx_1.AuthInfo.fromPartial({ + signerInfos: [signerInfo], + fee: { + amount: __spreadArray([], fee.amount, true), + gasLimit: long_1["default"].fromString(fee.gas) + } + }); + var authInfoBytes = tx_1.AuthInfo.encode(authInfo).finish(); + var signedTx = tx_2.TxRaw.fromPartial({ + bodyBytes: bodyBytes, + authInfoBytes: authInfoBytes, + signatures: [multisig_1.MultiSignature.encode(multisig_1.MultiSignature.fromPartial({ signatures: signaturesList })).finish()] + }); + return signedTx; +} +exports.makeMultisignedTx = makeMultisignedTx; diff --git a/build/multisignature.spec.js b/build/multisignature.spec.js new file mode 100644 index 0000000..6b681b5 --- /dev/null +++ b/build/multisignature.spec.js @@ -0,0 +1,283 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var amino_1 = require("@cosmjs/amino"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var utils_1 = require("@cosmjs/utils"); +var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var multisignature_1 = require("./multisignature"); +var signingstargateclient_1 = require("./signingstargateclient"); +var stargateclient_1 = require("./stargateclient"); +var testutils_spec_1 = require("./testutils.spec"); +describe("multisignature", function () { + describe("makeCompactBitArray", function () { + it("works for 0 bits of different lengths", function () { + expect((0, multisignature_1.makeCompactBitArray)([])).toEqual({ elems: new Uint8Array([]), extraBitsStored: 0 }); + expect((0, multisignature_1.makeCompactBitArray)([false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 1 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 3 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 4 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 5 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 6 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 7 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0]), + extraBitsStored: 0 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0, 0]), + extraBitsStored: 1 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false, false, false, false])).toEqual({ elems: new Uint8Array([0, 0]), extraBitsStored: 2 }); + }); + it("works for 1 bits of different lengths", function () { + expect((0, multisignature_1.makeCompactBitArray)([])).toEqual({ elems: new Uint8Array([]), extraBitsStored: 0 }); + expect((0, multisignature_1.makeCompactBitArray)([true])).toEqual({ + elems: new Uint8Array([128]), + extraBitsStored: 1 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true])).toEqual({ + elems: new Uint8Array([192]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true])).toEqual({ + elems: new Uint8Array([224]), + extraBitsStored: 3 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true])).toEqual({ + elems: new Uint8Array([240]), + extraBitsStored: 4 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true, true])).toEqual({ + elems: new Uint8Array([248]), + extraBitsStored: 5 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([252]), + extraBitsStored: 6 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([254]), + extraBitsStored: 7 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([255]), + extraBitsStored: 0 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([255, 128]), + extraBitsStored: 1 + }); + expect((0, multisignature_1.makeCompactBitArray)([true, true, true, true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([255, 192]), + extraBitsStored: 2 + }); + }); + it("works for 1 bit in different places", function () { + expect((0, multisignature_1.makeCompactBitArray)([true, false, false, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([128, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, true, false, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([64, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, true, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([32, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, true, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([16, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, true, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([8, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, true, false, false, false, false])).toEqual({ + elems: new Uint8Array([4, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, true, false, false, false])).toEqual({ + elems: new Uint8Array([2, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false, true, false, false])).toEqual({ + elems: new Uint8Array([1, 0]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false, false, true, false])).toEqual({ + elems: new Uint8Array([0, 128]), + extraBitsStored: 2 + }); + expect((0, multisignature_1.makeCompactBitArray)([false, false, false, false, false, false, false, false, false, true])).toEqual({ + elems: new Uint8Array([0, 64]), + extraBitsStored: 2 + }); + }); + }); + describe("makeMultisignedTx", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var multisigAccountAddress, signingInstruction, _a, _b, pubkey0, signature0, bodyBytes, _c, pubkey1, signature1, _d, pubkey2, signature2, _e, pubkey3, signature3, _f, pubkey4, signature4, multisigPubkey, address0, address1, address2, address3, address4, broadcaster, signedTx, result; + return __generator(this, function (_g) { + switch (_g.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + multisigAccountAddress = "cosmos1h90ml36rcu7yegwduzgzderj2jmq49hcpfclw9"; + return [4 /*yield*/, (function () { return __awaiter(void 0, void 0, void 0, function () { + var client, accountOnChain, msgSend, msg, gasLimit, fee; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _b.sent(); + return [4 /*yield*/, client.getAccount(multisigAccountAddress)]; + case 2: + accountOnChain = _b.sent(); + (0, utils_1.assert)(accountOnChain, "Account does not exist on chain"); + msgSend = { + fromAddress: multisigAccountAddress, + toAddress: "cosmos19rvl6ja9h0erq9dc2xxfdzypc739ej8k5esnhg", + amount: (0, proto_signing_1.coins)(1234, "ucosm") + }; + msg = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msgSend + }; + gasLimit = 200000; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: gasLimit.toString() + }; + _a = { + accountNumber: accountOnChain.accountNumber, + sequence: accountOnChain.sequence + }; + return [4 /*yield*/, client.getChainId()]; + case 3: return [2 /*return*/, (_a.chainId = _b.sent(), + _a.msgs = [msg], + _a.fee = fee, + _a.memo = "Use your tokens wisely", + _a)]; + } + }); + }); })()]; + case 1: + signingInstruction = _g.sent(); + return [4 /*yield*/, Promise.all([0, 1, 2, 3, 4].map(function (i) { return __awaiter(void 0, void 0, void 0, function () { + var wallet, pubkey, _a, address, signingClient, signerData, _b, bb, signatures; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic, { + hdPaths: [(0, amino_1.makeCosmoshubPath)(i)] + })]; + case 1: + wallet = _c.sent(); + _a = amino_1.encodeSecp256k1Pubkey; + return [4 /*yield*/, wallet.getAccounts()]; + case 2: + pubkey = _a.apply(void 0, [(_c.sent())[0].pubkey]); + return [4 /*yield*/, wallet.getAccounts()]; + case 3: + address = (_c.sent())[0].address; + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.offline(wallet)]; + case 4: + signingClient = _c.sent(); + signerData = { + accountNumber: signingInstruction.accountNumber, + sequence: signingInstruction.sequence, + chainId: signingInstruction.chainId + }; + return [4 /*yield*/, signingClient.sign(address, signingInstruction.msgs, signingInstruction.fee, signingInstruction.memo, signerData)]; + case 5: + _b = _c.sent(), bb = _b.bodyBytes, signatures = _b.signatures; + return [2 /*return*/, [pubkey, signatures[0], bb]]; + } + }); + }); }))]; + case 2: + _a = _g.sent(), _b = _a[0], pubkey0 = _b[0], signature0 = _b[1], bodyBytes = _b[2], _c = _a[1], pubkey1 = _c[0], signature1 = _c[1], _d = _a[2], pubkey2 = _d[0], signature2 = _d[1], _e = _a[3], pubkey3 = _e[0], signature3 = _e[1], _f = _a[4], pubkey4 = _f[0], signature4 = _f[1]; + multisigPubkey = (0, amino_1.createMultisigThresholdPubkey)([pubkey0, pubkey1, pubkey2, pubkey3, pubkey4], 2); + expect((0, amino_1.pubkeyToAddress)(multisigPubkey, "cosmos")).toEqual(multisigAccountAddress); + address0 = (0, amino_1.pubkeyToAddress)(pubkey0, "cosmos"); + address1 = (0, amino_1.pubkeyToAddress)(pubkey1, "cosmos"); + address2 = (0, amino_1.pubkeyToAddress)(pubkey2, "cosmos"); + address3 = (0, amino_1.pubkeyToAddress)(pubkey3, "cosmos"); + address4 = (0, amino_1.pubkeyToAddress)(pubkey4, "cosmos"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 3: + broadcaster = _g.sent(); + signedTx = (0, multisignature_1.makeMultisignedTx)(multisigPubkey, signingInstruction.sequence, signingInstruction.fee, bodyBytes, new Map([ + [address0, signature0], + [address1, signature1], + [address2, signature2], + [address3, signature3], + [address4, signature4], + ])); + return [4 /*yield*/, broadcaster.broadcastTx(Uint8Array.from(tx_1.TxRaw.encode(signedTx).finish()))]; + case 4: + result = _g.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/auth.js b/build/queries/auth.js new file mode 100644 index 0000000..c256c9a --- /dev/null +++ b/build/queries/auth.js @@ -0,0 +1,64 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupAuthExtension = void 0; +var query_1 = require("cosmjs-types/cosmos/auth/v1beta1/query"); +var utils_1 = require("./utils"); +function setupAuthExtension(base) { + var _this = this; + var rpc = (0, utils_1.createProtobufRpcClient)(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var queryService = new query_1.QueryClientImpl(rpc); + return { + auth: { + account: function (address) { return __awaiter(_this, void 0, void 0, function () { + var account; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Account({ address: address })]; + case 1: + account = (_a.sent()).account; + return [2 /*return*/, account !== null && account !== void 0 ? account : null]; + } + }); + }); } + } + }; +} +exports.setupAuthExtension = setupAuthExtension; diff --git a/build/queries/auth.spec.js b/build/queries/auth.spec.js new file mode 100644 index 0000000..26124b9 --- /dev/null +++ b/build/queries/auth.spec.js @@ -0,0 +1,132 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention */ +var proto_signing_1 = require("@cosmjs/proto-signing"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var auth_1 = require("cosmjs-types/cosmos/auth/v1beta1/auth"); +var any_1 = require("cosmjs-types/google/protobuf/any"); +var long_1 = require("long"); +var testutils_spec_1 = require("../testutils.spec"); +var auth_2 = require("./auth"); +var queryclient_1 = require("./queryclient"); +function makeClientWithAuth(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, auth_2.setupAuthExtension), tmClient]]; + } + }); + }); +} +describe("AuthExtension", function () { + describe("account", function () { + it("works for unused account", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, account; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithAuth(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.auth.account(testutils_spec_1.unused.address)]; + case 2: + account = _b.sent(); + (0, utils_1.assert)(account); + expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount"); + expect(auth_1.BaseAccount.decode(account.value)).toEqual({ + address: testutils_spec_1.unused.address, + // pubKey not set + accountNumber: long_1["default"].fromNumber(testutils_spec_1.unused.accountNumber, true), + sequence: long_1["default"].fromNumber(0, true) + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works for account with pubkey and non-zero sequence", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, account; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithAuth(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.auth.account(testutils_spec_1.validator.delegatorAddress)]; + case 2: + account = _b.sent(); + (0, utils_1.assert)(account); + expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount"); + expect(auth_1.BaseAccount.decode(account.value)).toEqual({ + address: testutils_spec_1.validator.delegatorAddress, + pubKey: any_1.Any.fromPartial((0, proto_signing_1.encodePubkey)(testutils_spec_1.validator.pubkey)), + accountNumber: long_1["default"].fromNumber(0, true), + sequence: long_1["default"].fromNumber(testutils_spec_1.validator.sequence, true) + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("rejects for non-existent address", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithAuth(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, expectAsync(client.auth.account(testutils_spec_1.nonExistentAddress)).toBeRejectedWithError(/account cosmos1p79apjaufyphcmsn4g07cynqf0wyjuezqu84hd not found/i)]; + case 2: + _b.sent(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/bank.js b/build/queries/bank.js new file mode 100644 index 0000000..c967e3b --- /dev/null +++ b/build/queries/bank.js @@ -0,0 +1,126 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupBankExtension = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var utils_1 = require("@cosmjs/utils"); +var query_1 = require("cosmjs-types/cosmos/bank/v1beta1/query"); +var utils_2 = require("./utils"); +function setupBankExtension(base) { + var _this = this; + var rpc = (0, utils_2.createProtobufRpcClient)(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var queryService = new query_1.QueryClientImpl(rpc); + return { + bank: { + balance: function (address, denom) { return __awaiter(_this, void 0, void 0, function () { + var balance; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Balance({ address: address, denom: denom })]; + case 1: + balance = (_a.sent()).balance; + (0, utils_1.assert)(balance); + return [2 /*return*/, balance]; + } + }); + }); }, + allBalances: function (address) { return __awaiter(_this, void 0, void 0, function () { + var balances; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.AllBalances({ address: address })]; + case 1: + balances = (_a.sent()).balances; + return [2 /*return*/, balances]; + } + }); + }); }, + totalSupply: function () { return __awaiter(_this, void 0, void 0, function () { + var supply; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.TotalSupply({})]; + case 1: + supply = (_a.sent()).supply; + return [2 /*return*/, supply]; + } + }); + }); }, + supplyOf: function (denom) { return __awaiter(_this, void 0, void 0, function () { + var amount; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.SupplyOf({ denom: denom })]; + case 1: + amount = (_a.sent()).amount; + (0, utils_1.assert)(amount); + return [2 /*return*/, amount]; + } + }); + }); }, + denomMetadata: function (denom) { return __awaiter(_this, void 0, void 0, function () { + var metadata; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DenomMetadata({ denom: denom })]; + case 1: + metadata = (_a.sent()).metadata; + (0, utils_1.assert)(metadata); + return [2 /*return*/, metadata]; + } + }); + }); }, + denomsMetadata: function () { return __awaiter(_this, void 0, void 0, function () { + var metadatas; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DenomsMetadata({ + pagination: undefined + })]; + case 1: + metadatas = (_a.sent()).metadatas; + return [2 /*return*/, metadatas]; + } + }); + }); } + } + }; +} +exports.setupBankExtension = setupBankExtension; diff --git a/build/queries/bank.spec.js b/build/queries/bank.spec.js new file mode 100644 index 0000000..e2264cb --- /dev/null +++ b/build/queries/bank.spec.js @@ -0,0 +1,343 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var testutils_spec_1 = require("../testutils.spec"); +var bank_1 = require("./bank"); +var queryclient_1 = require("./queryclient"); +function makeClientWithBank(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, bank_1.setupBankExtension), tmClient]]; + } + }); + }); +} +describe("BankExtension", function () { + describe("balance", function () { + it("works for different existing balances", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response1, response2; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.balance(testutils_spec_1.unused.address, testutils_spec_1.simapp.denomFee)]; + case 2: + response1 = _b.sent(); + expect(response1).toEqual({ + amount: testutils_spec_1.unused.balanceFee, + denom: testutils_spec_1.simapp.denomFee + }); + return [4 /*yield*/, client.bank.balance(testutils_spec_1.unused.address, testutils_spec_1.simapp.denomStaking)]; + case 3: + response2 = _b.sent(); + expect(response2).toEqual({ + amount: testutils_spec_1.unused.balanceStaking, + denom: testutils_spec_1.simapp.denomStaking + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns zero for non-existent balance", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.balance(testutils_spec_1.unused.address, "gintonic")]; + case 2: + response = _b.sent(); + expect(response).toEqual({ + amount: "0", + denom: "gintonic" + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns zero for non-existent address", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.balance(testutils_spec_1.nonExistentAddress, testutils_spec_1.simapp.denomFee)]; + case 2: + response = _b.sent(); + expect(response).toEqual({ + amount: "0", + denom: testutils_spec_1.simapp.denomFee + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allBalances", function () { + it("returns all balances for unused account", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, balances; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.allBalances(testutils_spec_1.unused.address)]; + case 2: + balances = _b.sent(); + expect(balances).toEqual([ + { + amount: testutils_spec_1.unused.balanceFee, + denom: testutils_spec_1.simapp.denomFee + }, + { + amount: testutils_spec_1.unused.balanceStaking, + denom: testutils_spec_1.simapp.denomStaking + }, + ]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns an empty list for non-existent account", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, balances; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.allBalances(testutils_spec_1.nonExistentAddress)]; + case 2: + balances = _b.sent(); + expect(balances).toEqual([]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("totalSupply", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.totalSupply()]; + case 2: + response = _b.sent(); + expect(response).toEqual([ + { + amount: testutils_spec_1.simapp.totalSupply.toString(), + denom: testutils_spec_1.simapp.denomFee + }, + { + amount: jasmine.stringMatching(testutils_spec_1.nonNegativeIntegerMatcher), + denom: testutils_spec_1.simapp.denomStaking + }, + ]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("supplyOf", function () { + it("works for existing denom", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.supplyOf(testutils_spec_1.simapp.denomFee)]; + case 2: + response = _b.sent(); + expect(response).toEqual({ + amount: testutils_spec_1.simapp.totalSupply.toString(), + denom: testutils_spec_1.simapp.denomFee + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns zero for non-existent denom", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.supplyOf("gintonic")]; + case 2: + response = _b.sent(); + expect(response).toEqual({ + amount: "0", + denom: "gintonic" + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("denomMetadata", function () { + it("works for existent denom", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, metadata; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.denomMetadata("ucosm")]; + case 2: + metadata = _b.sent(); + expect(metadata).toEqual({ + description: "The fee token of this test chain", + denomUnits: [ + { + denom: "ucosm", + exponent: 0, + aliases: [] + }, + { + denom: "COSM", + exponent: 6, + aliases: [] + }, + ], + base: "ucosm", + display: "COSM", + name: "", + symbol: "" + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works for non-existent denom", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, expectAsync(client.bank.denomMetadata("nothere")).toBeRejectedWithError(/code = NotFound/i)]; + case 2: + _b.sent(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("denomsMetadata", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, metadatas; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithBank(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.bank.denomsMetadata()]; + case 2: + metadatas = _b.sent(); + expect(metadatas.length).toEqual(1); + expect(metadatas[0]).toEqual({ + description: "The fee token of this test chain", + denomUnits: [ + { + denom: "ucosm", + exponent: 0, + aliases: [] + }, + { + denom: "COSM", + exponent: 6, + aliases: [] + }, + ], + base: "ucosm", + display: "COSM", + name: "", + symbol: "" + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/distribution.js b/build/queries/distribution.js new file mode 100644 index 0000000..50a36cc --- /dev/null +++ b/build/queries/distribution.js @@ -0,0 +1,172 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupDistributionExtension = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var query_1 = require("cosmjs-types/cosmos/distribution/v1beta1/query"); +var long_1 = require("long"); +var utils_1 = require("./utils"); +function setupDistributionExtension(base) { + var _this = this; + var rpc = (0, utils_1.createProtobufRpcClient)(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var queryService = new query_1.QueryClientImpl(rpc); + return { + distribution: { + communityPool: function () { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.CommunityPool({})]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegationRewards: function (delegatorAddress, validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegationRewards({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegationTotalRewards: function (delegatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegationTotalRewards({ + delegatorAddress: delegatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegatorValidators: function (delegatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegatorValidators({ + delegatorAddress: delegatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegatorWithdrawAddress: function (delegatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegatorWithdrawAddress({ + delegatorAddress: delegatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + params: function () { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Params({})]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validatorCommission: function (validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.ValidatorCommission({ + validatorAddress: validatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validatorOutstandingRewards: function (validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.ValidatorOutstandingRewards({ + validatorAddress: validatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validatorSlashes: function (validatorAddress, startingHeight, endingHeight, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.ValidatorSlashes({ + validatorAddress: validatorAddress, + startingHeight: long_1["default"].fromNumber(startingHeight, true), + endingHeight: long_1["default"].fromNumber(endingHeight, true), + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); } + } + }; +} +exports.setupDistributionExtension = setupDistributionExtension; diff --git a/build/queries/distribution.spec.js b/build/queries/distribution.spec.js new file mode 100644 index 0000000..634dae2 --- /dev/null +++ b/build/queries/distribution.spec.js @@ -0,0 +1,289 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention */ +var proto_signing_1 = require("@cosmjs/proto-signing"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var signingstargateclient_1 = require("../signingstargateclient"); +var stargateclient_1 = require("../stargateclient"); +var testutils_spec_1 = require("../testutils.spec"); +var distribution_1 = require("./distribution"); +var queryclient_1 = require("./queryclient"); +function makeClientWithDistribution(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, distribution_1.setupDistributionExtension), tmClient]]; + } + }); + }); +} +describe("DistributionExtension", function () { + var defaultFee = { + amount: (0, proto_signing_1.coins)(25000, "ucosm"), + gas: "1500000" + }; + beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, memo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!(0, testutils_spec_1.simappEnabled)()) return [3 /*break*/, 5]; + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(25000, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + memo = "Test delegation for Stargate"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], defaultFee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [4 /*yield*/, (0, utils_1.sleep)(75)]; + case 4: + _a.sent(); // wait until transactions are indexed + _a.label = 5; + case 5: return [2 /*return*/]; + } + }); + }); }); + describe("communityPool", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.communityPool()]; + case 2: + response = _b.sent(); + expect(response.pool).toBeDefined(); + expect(response.pool).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegationRewards", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.delegationRewards(testutils_spec_1.faucet.address0, testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.rewards).toBeDefined(); + expect(response.rewards).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegationTotalRewards", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.delegationTotalRewards(testutils_spec_1.faucet.address0)]; + case 2: + response = _b.sent(); + expect(response.rewards).toBeDefined(); + expect(response.rewards).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegatorValidators", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.delegatorValidators(testutils_spec_1.faucet.address0)]; + case 2: + response = _b.sent(); + expect(response.validators).toBeDefined(); + expect(response.validators).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegatorWithdrawAddress", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.delegatorWithdrawAddress(testutils_spec_1.faucet.address0)]; + case 2: + response = _b.sent(); + expect(response.withdrawAddress).toBeDefined(); + expect(response.withdrawAddress).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("params", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.params()]; + case 2: + response = _b.sent(); + expect(response.params).toBeDefined(); + expect(response.params).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validatorCommission", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.validatorCommission(testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.commission).toBeDefined(); + expect(response.commission).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validatorOutstandingRewards", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.validatorOutstandingRewards(testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.rewards).toBeDefined(); + expect(response.rewards).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validatorSlashes", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithDistribution(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.distribution.validatorSlashes(testutils_spec_1.validator.validatorAddress, 1, 5)]; + case 2: + response = _b.sent(); + expect(response.slashes).toBeDefined(); + expect(response.slashes).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/gov.js b/build/queries/gov.js new file mode 100644 index 0000000..8bcd0de --- /dev/null +++ b/build/queries/gov.js @@ -0,0 +1,160 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupGovExtension = void 0; +var query_1 = require("cosmjs-types/cosmos/gov/v1beta1/query"); +var utils_1 = require("./utils"); +function setupGovExtension(base) { + var _this = this; + var rpc = (0, utils_1.createProtobufRpcClient)(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var queryService = new query_1.QueryClientImpl(rpc); + return { + gov: { + params: function (parametersType) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Params({ paramsType: parametersType })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + proposals: function (proposalStatus, depositorAddress, voterAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Proposals({ + proposalStatus: proposalStatus, + depositor: depositorAddress, + voter: voterAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + proposal: function (proposalId) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Proposal({ proposalId: (0, utils_1.longify)(proposalId) })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + deposits: function (proposalId, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Deposits({ + proposalId: (0, utils_1.longify)(proposalId), + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + deposit: function (proposalId, depositorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Deposit({ + proposalId: (0, utils_1.longify)(proposalId), + depositor: depositorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + tally: function (proposalId) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.TallyResult({ + proposalId: (0, utils_1.longify)(proposalId) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + votes: function (proposalId, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Votes({ + proposalId: (0, utils_1.longify)(proposalId), + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + vote: function (proposalId, voterAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Vote({ + proposalId: (0, utils_1.longify)(proposalId), + voter: voterAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); } + } + }; +} +exports.setupGovExtension = setupGovExtension; diff --git a/build/queries/gov.spec.js b/build/queries/gov.spec.js new file mode 100644 index 0000000..d8a7c5d --- /dev/null +++ b/build/queries/gov.spec.js @@ -0,0 +1,518 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var amino_1 = require("@cosmjs/amino"); +var encoding_1 = require("@cosmjs/encoding"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var gov_1 = require("cosmjs-types/cosmos/gov/v1beta1/gov"); +var any_1 = require("cosmjs-types/google/protobuf/any"); +var long_1 = require("long"); +var signingstargateclient_1 = require("../signingstargateclient"); +var stargateclient_1 = require("../stargateclient"); +var testutils_spec_1 = require("../testutils.spec"); +var gov_2 = require("./gov"); +var queryclient_1 = require("./queryclient"); +var utils_2 = require("./utils"); +function makeClientWithGov(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, gov_2.setupGovExtension), tmClient]]; + } + }); + }); +} +describe("GovExtension", function () { + var defaultFee = { + amount: (0, amino_1.coins)(25000, "ucosm"), + gas: "1500000" + }; + var textProposal = gov_1.TextProposal.fromPartial({ + title: "Test Proposal", + description: "This proposal proposes to test whether this proposal passes" + }); + var initialDeposit = (0, amino_1.coins)(12300000, "ustake"); + var delegationVoter1 = (0, amino_1.coin)(424242, "ustake"); + var delegationVoter2 = (0, amino_1.coin)(777, "ustake"); + var voter1Address = testutils_spec_1.faucet.address1; + var voter2Address = testutils_spec_1.faucet.address2; + var proposalId; + beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, proposalMsg, proposalResult, logs, msgDelegate, result, voteMsg, voteResult, msgDelegate, result, voteMsg, voteResult; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!(0, testutils_spec_1.simappEnabled)()) return [3 /*break*/, 13]; + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic, { + // Use address 1 and 2 instead of 0 to avoid conflicts with other delegation tests + // This must match `voterAddress` above. + hdPaths: [(0, amino_1.makeCosmoshubPath)(1), (0, amino_1.makeCosmoshubPath)(2)] + })]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + proposalMsg = { + typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal", + value: { + content: any_1.Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: Uint8Array.from(gov_1.TextProposal.encode(textProposal).finish()) + }), + proposer: voter1Address, + initialDeposit: initialDeposit + } + }; + return [4 /*yield*/, client.signAndBroadcast(voter1Address, [proposalMsg], defaultFee, "Test proposal for simd")]; + case 3: + proposalResult = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(proposalResult); + logs = JSON.parse(proposalResult.rawLog || ""); + proposalId = logs[0].events + .find(function (_a) { + var type = _a.type; + return type === "submit_proposal"; + }) + .attributes.find(function (_a) { + var key = _a.key; + return key === "proposal_id"; + }).value; + (0, utils_1.assert)(proposalId, "Proposal ID not found in events"); + (0, utils_1.assert)(proposalId.match(testutils_spec_1.nonNegativeIntegerMatcher)); + return [4 /*yield*/, client.getDelegation(voter1Address, testutils_spec_1.validator.validatorAddress)]; + case 4: + if (!!(_a.sent())) return [3 /*break*/, 6]; + msgDelegate = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: { + delegatorAddress: voter1Address, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: delegationVoter1 + } + }; + return [4 /*yield*/, client.signAndBroadcast(voter1Address, [msgDelegate], defaultFee)]; + case 5: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + _a.label = 6; + case 6: + voteMsg = { + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: { + proposalId: (0, utils_2.longify)(proposalId), + voter: voter1Address, + option: gov_1.VoteOption.VOTE_OPTION_YES + } + }; + return [4 /*yield*/, client.signAndBroadcast(voter1Address, [voteMsg], defaultFee)]; + case 7: + voteResult = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(voteResult); + return [4 /*yield*/, client.getDelegation(voter2Address, testutils_spec_1.validator.validatorAddress)]; + case 8: + if (!!(_a.sent())) return [3 /*break*/, 10]; + msgDelegate = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: { + delegatorAddress: voter2Address, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: delegationVoter2 + } + }; + return [4 /*yield*/, client.signAndBroadcast(voter2Address, [msgDelegate], defaultFee)]; + case 9: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + _a.label = 10; + case 10: + voteMsg = { + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: { + proposalId: (0, utils_2.longify)(proposalId), + voter: voter2Address, + option: gov_1.VoteOption.VOTE_OPTION_NO_WITH_VETO + } + }; + return [4 /*yield*/, client.signAndBroadcast(voter2Address, [voteMsg], defaultFee)]; + case 11: + voteResult = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(voteResult); + return [4 /*yield*/, (0, utils_1.sleep)(75)]; + case 12: + _a.sent(); // wait until transactions are indexed + client.disconnect(); + _a.label = 13; + case 13: return [2 /*return*/]; + } + }); + }); }); + describe("params", function () { + it("works for deposit", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.params("deposit")]; + case 2: + response = _b.sent(); + expect(response).toEqual(jasmine.objectContaining({ + depositParams: { + minDeposit: testutils_spec_1.simapp.govMinDeposit, + maxDepositPeriod: { + seconds: long_1["default"].fromNumber(172800, false), + nanos: 0 + } + } + })); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works for tallying", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.params("tallying")]; + case 2: + response = _b.sent(); + expect(response).toEqual(jasmine.objectContaining({ + tallyParams: { + // Why the f*** are we getting binary values here? + quorum: (0, encoding_1.toAscii)("334000000000000000"), + threshold: (0, encoding_1.toAscii)("500000000000000000"), + vetoThreshold: (0, encoding_1.toAscii)("334000000000000000") + } + })); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works for voting", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.params("voting")]; + case 2: + response = _b.sent(); + expect(response).toEqual(jasmine.objectContaining({ + votingParams: { + votingPeriod: { + seconds: long_1["default"].fromNumber(172800, false), + nanos: 0 + } + } + })); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("proposals", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.proposals(gov_1.ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD, voter1Address, voter1Address)]; + case 2: + response = _b.sent(); + expect(response.proposals.length).toBeGreaterThanOrEqual(1); + expect(response.proposals[response.proposals.length - 1]).toEqual({ + content: any_1.Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: Uint8Array.from(gov_1.TextProposal.encode(textProposal).finish()) + }), + proposalId: (0, utils_2.longify)(proposalId), + status: gov_1.ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD, + finalTallyResult: { yes: "0", abstain: "0", no: "0", noWithVeto: "0" }, + submitTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) }, + depositEndTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) }, + totalDeposit: initialDeposit, + votingStartTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) }, + votingEndTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) } + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("proposal", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.proposal(proposalId)]; + case 2: + response = _b.sent(); + expect(response.proposal).toEqual({ + content: any_1.Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: Uint8Array.from(gov_1.TextProposal.encode(textProposal).finish()) + }), + proposalId: (0, utils_2.longify)(proposalId), + status: gov_1.ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD, + finalTallyResult: { yes: "0", abstain: "0", no: "0", noWithVeto: "0" }, + submitTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) }, + depositEndTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) }, + totalDeposit: initialDeposit, + votingStartTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) }, + votingEndTime: { seconds: jasmine.any(long_1["default"]), nanos: jasmine.any(Number) } + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("deposits", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.deposits(proposalId)]; + case 2: + response = _b.sent(); + expect(response.deposits).toEqual([ + { + proposalId: (0, utils_2.longify)(proposalId), + depositor: voter1Address, + amount: initialDeposit + }, + ]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("deposit", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.deposit(proposalId, voter1Address)]; + case 2: + response = _b.sent(); + expect(response.deposit).toEqual({ + proposalId: (0, utils_2.longify)(proposalId), + depositor: voter1Address, + amount: initialDeposit + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("tally", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.tally(proposalId)]; + case 2: + response = _b.sent(); + expect(response.tally).toEqual({ + yes: delegationVoter1.amount, + abstain: "0", + no: "0", + noWithVeto: delegationVoter2.amount + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("votes", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.votes(proposalId)]; + case 2: + response = _b.sent(); + if ((0, testutils_spec_1.simapp42Enabled)()) { + expect(response.votes).toEqual([ + // why is vote 2 first? + gov_1.Vote.fromPartial({ + proposalId: (0, utils_2.longify)(proposalId), + voter: voter2Address, + option: gov_1.VoteOption.VOTE_OPTION_NO_WITH_VETO + }), + gov_1.Vote.fromPartial({ + proposalId: (0, utils_2.longify)(proposalId), + voter: voter1Address, + option: gov_1.VoteOption.VOTE_OPTION_YES + }), + ]); + } + else { + expect(response.votes).toEqual([ + // why is vote 2 first? + gov_1.Vote.fromPartial({ + proposalId: (0, utils_2.longify)(proposalId), + voter: voter2Address, + option: gov_1.VoteOption.VOTE_OPTION_NO_WITH_VETO, + options: [ + gov_1.WeightedVoteOption.fromPartial({ + option: gov_1.VoteOption.VOTE_OPTION_NO_WITH_VETO, + weight: "1000000000000000000" + }), + ] + }), + gov_1.Vote.fromPartial({ + proposalId: (0, utils_2.longify)(proposalId), + voter: voter1Address, + option: gov_1.VoteOption.VOTE_OPTION_YES, + options: [ + gov_1.WeightedVoteOption.fromPartial({ + option: gov_1.VoteOption.VOTE_OPTION_YES, + weight: "1000000000000000000" + }), + ] + }), + ]); + } + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("vote", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(proposalId, "Missing proposal ID"); + return [4 /*yield*/, makeClientWithGov(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.gov.vote(proposalId, voter1Address)]; + case 2: + response = _b.sent(); + if ((0, testutils_spec_1.simapp42Enabled)()) { + expect(response.vote).toEqual(gov_1.Vote.fromPartial({ + voter: voter1Address, + proposalId: (0, utils_2.longify)(proposalId), + option: gov_1.VoteOption.VOTE_OPTION_YES + })); + } + else { + expect(response.vote).toEqual(gov_1.Vote.fromPartial({ + voter: voter1Address, + proposalId: (0, utils_2.longify)(proposalId), + option: gov_1.VoteOption.VOTE_OPTION_YES, + options: [ + gov_1.WeightedVoteOption.fromPartial({ + option: gov_1.VoteOption.VOTE_OPTION_YES, + weight: "1000000000000000000" + }), + ] + })); + } + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/ibc.js b/build/queries/ibc.js new file mode 100644 index 0000000..6ed43d4 --- /dev/null +++ b/build/queries/ibc.js @@ -0,0 +1,614 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupIbcExtension = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var encoding_1 = require("@cosmjs/encoding"); +var math_1 = require("@cosmjs/math"); +var query_1 = require("cosmjs-types/ibc/applications/transfer/v1/query"); +var channel_1 = require("cosmjs-types/ibc/core/channel/v1/channel"); +var query_2 = require("cosmjs-types/ibc/core/channel/v1/query"); +var query_3 = require("cosmjs-types/ibc/core/client/v1/query"); +var query_4 = require("cosmjs-types/ibc/core/connection/v1/query"); +var tendermint_1 = require("cosmjs-types/ibc/lightclients/tendermint/v1/tendermint"); +var long_1 = require("long"); +var utils_1 = require("./utils"); +function decodeTendermintClientStateAny(clientState) { + if ((clientState === null || clientState === void 0 ? void 0 : clientState.typeUrl) !== "/ibc.lightclients.tendermint.v1.ClientState") { + throw new Error("Unexpected client state type: " + (clientState === null || clientState === void 0 ? void 0 : clientState.typeUrl)); + } + return tendermint_1.ClientState.decode(clientState.value); +} +function decodeTendermintConsensusStateAny(clientState) { + if ((clientState === null || clientState === void 0 ? void 0 : clientState.typeUrl) !== "/ibc.lightclients.tendermint.v1.ConsensusState") { + throw new Error("Unexpected client state type: " + (clientState === null || clientState === void 0 ? void 0 : clientState.typeUrl)); + } + return tendermint_1.ConsensusState.decode(clientState.value); +} +function setupIbcExtension(base) { + var _this = this; + var rpc = (0, utils_1.createProtobufRpcClient)(base); + // Use these services to get easy typed access to query methods + // These cannot be used for proof verification + var channelQueryService = new query_2.QueryClientImpl(rpc); + var clientQueryService = new query_3.QueryClientImpl(rpc); + var connectionQueryService = new query_4.QueryClientImpl(rpc); + var transferQueryService = new query_1.QueryClientImpl(rpc); + return { + ibc: { + channel: { + channel: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.Channel({ + portId: portId, + channelId: channelId + })]; + }); + }); }, + channels: function (paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.Channels({ + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allChannels: function () { return __awaiter(_this, void 0, void 0, function () { + var channels, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + channels = []; + _b.label = 1; + case 1: return [4 /*yield*/, channelQueryService.Channels({ + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + channels.push.apply(channels, response.channels); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + channels: channels, + height: response.height + }]; + } + }); + }); }, + connectionChannels: function (connection, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.ConnectionChannels({ + connection: connection, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allConnectionChannels: function (connection) { return __awaiter(_this, void 0, void 0, function () { + var channels, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + channels = []; + _b.label = 1; + case 1: return [4 /*yield*/, channelQueryService.ConnectionChannels({ + connection: connection, + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + channels.push.apply(channels, response.channels); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + channels: channels, + height: response.height + }]; + } + }); + }); }, + clientState: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.ChannelClientState({ + portId: portId, + channelId: channelId + })]; + }); + }); }, + consensusState: function (portId, channelId, revisionNumber, revisionHeight) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.ChannelConsensusState({ + portId: portId, + channelId: channelId, + revisionNumber: long_1["default"].fromNumber(revisionNumber, true), + revisionHeight: long_1["default"].fromNumber(revisionHeight, true) + })]; + }); + }); }, + packetCommitment: function (portId, channelId, sequence) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.PacketCommitment({ + portId: portId, + channelId: channelId, + sequence: sequence + })]; + }); + }); }, + packetCommitments: function (portId, channelId, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.PacketCommitments({ + channelId: channelId, + portId: portId, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allPacketCommitments: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + var commitments, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + commitments = []; + _b.label = 1; + case 1: return [4 /*yield*/, channelQueryService.PacketCommitments({ + channelId: channelId, + portId: portId, + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + commitments.push.apply(commitments, response.commitments); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + commitments: commitments, + height: response.height + }]; + } + }); + }); }, + packetReceipt: function (portId, channelId, sequence) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.PacketReceipt({ + portId: portId, + channelId: channelId, + sequence: long_1["default"].fromNumber(sequence, true) + })]; + }); + }); }, + packetAcknowledgement: function (portId, channelId, sequence) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.PacketAcknowledgement({ + portId: portId, + channelId: channelId, + sequence: long_1["default"].fromNumber(sequence, true) + })]; + }); + }); }, + packetAcknowledgements: function (portId, channelId, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.PacketAcknowledgements({ + portId: portId, + channelId: channelId, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allPacketAcknowledgements: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + var acknowledgements, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + acknowledgements = []; + _b.label = 1; + case 1: return [4 /*yield*/, channelQueryService.PacketAcknowledgements({ + channelId: channelId, + portId: portId, + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + acknowledgements.push.apply(acknowledgements, response.acknowledgements); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + acknowledgements: acknowledgements, + height: response.height + }]; + } + }); + }); }, + unreceivedPackets: function (portId, channelId, packetCommitmentSequences) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.UnreceivedPackets({ + portId: portId, + channelId: channelId, + packetCommitmentSequences: packetCommitmentSequences.map(function (s) { return long_1["default"].fromNumber(s, true); }) + })]; + }); + }); }, + unreceivedAcks: function (portId, channelId, packetAckSequences) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.UnreceivedAcks({ + portId: portId, + channelId: channelId, + packetAckSequences: packetAckSequences.map(function (s) { return long_1["default"].fromNumber(s, true); }) + })]; + }); + }); }, + nextSequenceReceive: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, channelQueryService.NextSequenceReceive({ + portId: portId, + channelId: channelId + })]; + }); + }); } + }, + client: { + state: function (clientId) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, clientQueryService.ClientState({ clientId: clientId })]; + }); }); }, + states: function (paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, clientQueryService.ClientStates({ + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allStates: function () { return __awaiter(_this, void 0, void 0, function () { + var clientStates, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + clientStates = []; + _b.label = 1; + case 1: return [4 /*yield*/, clientQueryService.ClientStates({ + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + clientStates.push.apply(clientStates, response.clientStates); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + clientStates: clientStates + }]; + } + }); + }); }, + consensusState: function (clientId, consensusHeight) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, clientQueryService.ConsensusState(query_3.QueryConsensusStateRequest.fromPartial({ + clientId: clientId, + revisionHeight: consensusHeight !== undefined ? long_1["default"].fromNumber(consensusHeight, true) : undefined, + latestHeight: consensusHeight === undefined + }))]; + }); + }); }, + consensusStates: function (clientId, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, clientQueryService.ConsensusStates({ + clientId: clientId, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allConsensusStates: function (clientId) { return __awaiter(_this, void 0, void 0, function () { + var consensusStates, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + consensusStates = []; + _b.label = 1; + case 1: return [4 /*yield*/, clientQueryService.ConsensusStates({ + clientId: clientId, + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + consensusStates.push.apply(consensusStates, response.consensusStates); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + consensusStates: consensusStates + }]; + } + }); + }); }, + params: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, clientQueryService.ClientParams({})]; + }); }); }, + stateTm: function (clientId) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, clientQueryService.ClientState({ clientId: clientId })]; + case 1: + response = _a.sent(); + return [2 /*return*/, decodeTendermintClientStateAny(response.clientState)]; + } + }); + }); }, + statesTm: function (paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var clientStates; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, clientQueryService.ClientStates({ + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + clientStates = (_a.sent()).clientStates; + return [2 /*return*/, clientStates.map(function (_a) { + var clientState = _a.clientState; + return decodeTendermintClientStateAny(clientState); + })]; + } + }); + }); }, + allStatesTm: function () { return __awaiter(_this, void 0, void 0, function () { + var clientStates, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + clientStates = []; + _b.label = 1; + case 1: return [4 /*yield*/, clientQueryService.ClientStates({ + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + clientStates.push.apply(clientStates, response.clientStates); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, clientStates.map(function (_a) { + var clientState = _a.clientState; + return decodeTendermintClientStateAny(clientState); + })]; + } + }); + }); }, + consensusStateTm: function (clientId, consensusHeight) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, clientQueryService.ConsensusState(query_3.QueryConsensusStateRequest.fromPartial({ + clientId: clientId, + revisionHeight: consensusHeight === null || consensusHeight === void 0 ? void 0 : consensusHeight.revisionHeight, + revisionNumber: consensusHeight === null || consensusHeight === void 0 ? void 0 : consensusHeight.revisionNumber, + latestHeight: consensusHeight === undefined + }))]; + case 1: + response = _a.sent(); + return [2 /*return*/, decodeTendermintConsensusStateAny(response.consensusState)]; + } + }); + }); } + }, + connection: { + connection: function (connectionId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, connectionQueryService.Connection({ + connectionId: connectionId + })]; + }); + }); }, + connections: function (paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, connectionQueryService.Connections({ + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allConnections: function () { return __awaiter(_this, void 0, void 0, function () { + var connections, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + connections = []; + _b.label = 1; + case 1: return [4 /*yield*/, connectionQueryService.Connections({ + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + connections.push.apply(connections, response.connections); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + connections: connections, + height: response.height + }]; + } + }); + }); }, + clientConnections: function (clientId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, connectionQueryService.ClientConnections({ + clientId: clientId + })]; + }); + }); }, + clientState: function (connectionId) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, connectionQueryService.ConnectionClientState({ + connectionId: connectionId + })]; + }); + }); }, + consensusState: function (connectionId, revisionHeight) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, connectionQueryService.ConnectionConsensusState(query_4.QueryConnectionConsensusStateRequest.fromPartial({ + connectionId: connectionId, + revisionHeight: long_1["default"].fromNumber(revisionHeight, true) + }))]; + }); + }); } + }, + transfer: { + denomTrace: function (hash) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, transferQueryService.DenomTrace({ hash: hash })]; + }); }); }, + denomTraces: function (paginationKey) { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, transferQueryService.DenomTraces({ + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + }); + }); }, + allDenomTraces: function () { return __awaiter(_this, void 0, void 0, function () { + var denomTraces, response, key; + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + denomTraces = []; + _b.label = 1; + case 1: return [4 /*yield*/, transferQueryService.DenomTraces({ + pagination: (0, utils_1.createPagination)(key) + })]; + case 2: + response = _b.sent(); + denomTraces.push.apply(denomTraces, response.denomTraces); + key = (_a = response.pagination) === null || _a === void 0 ? void 0 : _a.nextKey; + _b.label = 3; + case 3: + if (key && key.length) return [3 /*break*/, 1]; + _b.label = 4; + case 4: return [2 /*return*/, { + denomTraces: denomTraces + }]; + } + }); + }); }, + params: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, transferQueryService.Params({})]; + }); }); } + }, + verified: { + channel: { + channel: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + var key, responseData; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + key = (0, encoding_1.toAscii)("channelEnds/ports/" + portId + "/channels/" + channelId); + return [4 /*yield*/, base.queryVerified("ibc", key)]; + case 1: + responseData = _a.sent(); + return [2 /*return*/, responseData.length ? channel_1.Channel.decode(responseData) : null]; + } + }); + }); }, + packetCommitment: function (portId, channelId, sequence) { return __awaiter(_this, void 0, void 0, function () { + var key, responseData; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + key = (0, encoding_1.toAscii)("commitments/ports/" + portId + "/channels/" + channelId + "/packets/" + sequence); + return [4 /*yield*/, base.queryVerified("ibc", key)]; + case 1: + responseData = _a.sent(); + // keeper code doesn't parse, but returns raw + return [2 /*return*/, responseData]; + } + }); + }); }, + packetAcknowledgement: function (portId, channelId, sequence) { return __awaiter(_this, void 0, void 0, function () { + var key, responseData; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + key = (0, encoding_1.toAscii)("acks/ports/" + portId + "/channels/" + channelId + "/acknowledgements/" + sequence); + return [4 /*yield*/, base.queryVerified("ibc", key)]; + case 1: + responseData = _a.sent(); + // keeper code doesn't parse, but returns raw + return [2 /*return*/, responseData]; + } + }); + }); }, + nextSequenceReceive: function (portId, channelId) { return __awaiter(_this, void 0, void 0, function () { + var key, responseData; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + key = (0, encoding_1.toAscii)("seqAcks/ports/" + portId + "/channels/" + channelId + "/nextSequenceAck"); + return [4 /*yield*/, base.queryVerified("ibc", key)]; + case 1: + responseData = _a.sent(); + return [2 /*return*/, responseData.length ? math_1.Uint64.fromBytes(responseData).toNumber() : null]; + } + }); + }); } + } + } + } + }; +} +exports.setupIbcExtension = setupIbcExtension; diff --git a/build/queries/ibc.spec.js b/build/queries/ibc.spec.js new file mode 100644 index 0000000..6f715b7 --- /dev/null +++ b/build/queries/ibc.spec.js @@ -0,0 +1,843 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var long_1 = require("long"); +var testutils_spec_1 = require("../testutils.spec"); +var ibc_1 = require("./ibc"); +var ibcTest = require("./ibctestdata.spec"); +var queryclient_1 = require("./queryclient"); +function makeClientWithIbc(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, ibc_1.setupIbcExtension), tmClient]]; + } + }); + }); +} +describe("IbcExtension", function () { + describe("channel", function () { + describe("channel", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.channel(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.channel).toEqual(ibcTest.channel); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("channels", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.channels()]; + case 2: + response = _b.sent(); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allChannels", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.allChannels()]; + case 2: + response = _b.sent(); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("connectionChannels", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.connectionChannels(ibcTest.connectionId)]; + case 2: + response = _b.sent(); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allConnectionChannels", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.allConnectionChannels(ibcTest.connectionId)]; + case 2: + response = _b.sent(); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("clientState", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.clientState(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.identifiedClientState).toEqual({ + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array) + } + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("consensusState", function () { + xit("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.consensusState(ibcTest.portId, ibcTest.channelId, + // TODO: Find valid values + 0, 0)]; + case 2: + response = _b.sent(); + expect(response.consensusState).toEqual({ + typeUrl: "/haha", + value: jasmine.any(Uint8Array) + }); + expect(response.clientId).toEqual(ibcTest.clientId); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("packetCommitment", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.packetCommitment(ibcTest.portId, ibcTest.channelId, long_1["default"].fromInt(ibcTest.commitment.sequence, true))]; + case 2: + response = _b.sent(); + expect(response.commitment).toEqual(ibcTest.commitment.data); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("packetCommitments", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.packetCommitments(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.commitments).toEqual([ibcTest.packetState]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allPacketCommitments", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.allPacketCommitments(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.commitments).toEqual([ibcTest.packetState]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("packetReceipt", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.packetReceipt(ibcTest.portId, ibcTest.channelId, 1)]; + case 2: + response = _b.sent(); + expect(response.received).toEqual(false); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("packetAcknowledgement", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + pending("We don't have an acknowledgement for testing at the moment"); + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.packetAcknowledgement(ibcTest.portId, ibcTest.channelId, ibcTest.commitment.sequence)]; + case 2: + response = _b.sent(); + expect(response.acknowledgement).toEqual(ibcTest.packetAcknowledgements[0].data); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("packetAcknowledgements", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.packetAcknowledgements(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.acknowledgements).toEqual(ibcTest.packetAcknowledgements); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allPacketAcknowledgements", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.allPacketAcknowledgements(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.acknowledgements).toEqual(ibcTest.packetAcknowledgements); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("unreceivedPackets", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.unreceivedPackets(ibcTest.portId, ibcTest.channelId, [1, 2, 3])]; + case 2: + response = _b.sent(); + expect(response.sequences).toEqual([1, 2, 3].map(function (n) { return long_1["default"].fromInt(n, true); })); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("unreceivedAcks", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.unreceivedAcks(ibcTest.portId, ibcTest.channelId, [1, 2, 3, 4, 5, 6, 7])]; + case 2: + response = _b.sent(); + expect(response.sequences).toEqual([long_1["default"].fromInt(ibcTest.commitment.sequence, true)]); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("nextSequenceReceive", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.channel.nextSequenceReceive(ibcTest.portId, ibcTest.channelId)]; + case 2: + response = _b.sent(); + expect(response.nextSequenceReceive).toEqual(long_1["default"].fromInt(1, true)); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + }); + describe("client", function () { + describe("state", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.state(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.clientState).toEqual({ + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array) + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("states", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.states()]; + case 2: + response = _b.sent(); + expect(response.clientStates).toEqual([ + { + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array) + } + }, + ]); + expect(response.pagination).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allStates", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.allStates()]; + case 2: + response = _b.sent(); + expect(response.clientStates).toEqual([ + { + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array) + } + }, + ]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("consensusState", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.consensusState(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.consensusState).toEqual({ + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array) + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("consensusStates", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.consensusStates(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.consensusStates).toEqual(jasmine.arrayContaining([ + { + height: jasmine.anything(), + consensusState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array) + } + }, + ])); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allConsensusStates", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.allConsensusStates(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.consensusStates).toEqual(jasmine.arrayContaining([ + { + height: jasmine.anything(), + consensusState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array) + } + }, + ])); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("params", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.params()]; + case 2: + response = _b.sent(); + expect(response.params).toEqual({ + allowedClients: ["06-solomachine", "07-tendermint"] + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("stateTm", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.stateTm(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.chainId).toEqual("ibc-1"); + // TODO: Fill these expectations out + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("statesTm", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.statesTm()]; + case 2: + response = _b.sent(); + expect(response).toEqual(jasmine.arrayContaining([ + jasmine.objectContaining({ + chainId: "ibc-1" + }), + ])); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allStatesTm", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.allStatesTm()]; + case 2: + response = _b.sent(); + expect(response).toEqual(jasmine.arrayContaining([ + jasmine.objectContaining({ + chainId: "ibc-1" + }), + ])); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("consensusStateTm", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.client.consensusStateTm(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.nextValidatorsHash).toEqual(jasmine.any(Uint8Array)); + // TODO: Fill out these expectations + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + }); + describe("connection", function () { + describe("connection", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.connection.connection(ibcTest.connectionId)]; + case 2: + response = _b.sent(); + expect(response.connection).toEqual(ibcTest.connection); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("connections", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.connection.connections()]; + case 2: + response = _b.sent(); + expect(response.connections).toEqual([ibcTest.identifiedConnection]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("allConnections", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.connection.allConnections()]; + case 2: + response = _b.sent(); + expect(response.connections).toEqual([ibcTest.identifiedConnection]); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("clientConnections", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.connection.clientConnections(ibcTest.clientId)]; + case 2: + response = _b.sent(); + expect(response.connectionPaths).toEqual([ibcTest.connectionId]); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("clientState", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.connection.clientState(ibcTest.connectionId)]; + case 2: + response = _b.sent(); + expect(response.identifiedClientState).toEqual({ + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array) + } + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("consensusState", function () { + xit("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, makeClientWithIbc(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.ibc.connection.consensusState(ibcTest.connectionId, 1, 1)]; + case 2: + response = _b.sent(); + expect(response.clientId).toEqual(ibcTest.clientId); + expect(response.consensusState).toEqual({ + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array) + }); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + }); +}); diff --git a/build/queries/ibctestdata.spec.js b/build/queries/ibctestdata.spec.js new file mode 100644 index 0000000..4f617ed --- /dev/null +++ b/build/queries/ibctestdata.spec.js @@ -0,0 +1,93 @@ +"use strict"; +exports.__esModule = true; +exports.identifiedConnection = exports.connection = exports.packetAcknowledgements = exports.packetState = exports.commitment = exports.identifiedChannel = exports.channel = exports.clientId = exports.connectionId = exports.channelId = exports.portId = void 0; +var encoding_1 = require("@cosmjs/encoding"); +var channel_1 = require("cosmjs-types/ibc/core/channel/v1/channel"); +var commitment_1 = require("cosmjs-types/ibc/core/commitment/v1/commitment"); +var connection_1 = require("cosmjs-types/ibc/core/connection/v1/connection"); +var long_1 = require("long"); +// From scripts/simapp42/genesis-ibc.json +exports.portId = "transfer"; +exports.channelId = "channel-0"; +exports.connectionId = "connection-0"; +exports.clientId = "07-tendermint-0"; +exports.channel = channel_1.Channel.fromPartial({ + state: channel_1.State.STATE_OPEN, + ordering: channel_1.Order.ORDER_UNORDERED, + counterparty: channel_1.Counterparty.fromPartial({ + portId: exports.portId, + channelId: exports.channelId + }), + connectionHops: [exports.connectionId], + version: "ics20-1" +}); +exports.identifiedChannel = channel_1.IdentifiedChannel.fromPartial({ + state: channel_1.State.STATE_OPEN, + ordering: channel_1.Order.ORDER_UNORDERED, + counterparty: channel_1.Counterparty.fromPartial({ + portId: exports.portId, + channelId: "channel-0" + }), + connectionHops: [exports.connectionId], + version: "ics20-1", + portId: exports.portId, + channelId: exports.channelId +}); +/** + * ``` + * jq ".channel_genesis.commitments[0]" scripts/simapp42/genesis-ibc.json + * ``` + */ +exports.commitment = { + sequence: 1, + data: (0, encoding_1.fromBase64)("hYz5Dx6o09DcSEWZR6xlJYwLgYUnLithsXMGtujic4I=") +}; +exports.packetState = channel_1.PacketState.fromPartial({ + portId: exports.portId, + channelId: exports.channelId, + sequence: long_1["default"].fromInt(exports.commitment.sequence, true), + data: exports.commitment.data +}); +/** + * Unfortunatly empty right now + * + * ``` + * jq ".channel_genesis.acknowledgements" scripts/simapp42/genesis-ibc.json + * ``` + */ +exports.packetAcknowledgements = []; +exports.connection = connection_1.ConnectionEnd.fromPartial({ + clientId: exports.clientId, + versions: [ + connection_1.Version.fromPartial({ + identifier: "1", + features: ["ORDER_ORDERED", "ORDER_UNORDERED"] + }), + ], + state: connection_1.State.STATE_OPEN, + counterparty: connection_1.Counterparty.fromPartial({ + clientId: "07-tendermint-0", + connectionId: "connection-0", + prefix: commitment_1.MerklePrefix.fromPartial({ + keyPrefix: (0, encoding_1.fromBase64)("aWJj") + }) + }) +}); +exports.identifiedConnection = connection_1.IdentifiedConnection.fromPartial({ + id: exports.connectionId, + clientId: exports.clientId, + versions: [ + connection_1.Version.fromPartial({ + identifier: "1", + features: ["ORDER_ORDERED", "ORDER_UNORDERED"] + }), + ], + state: connection_1.State.STATE_OPEN, + counterparty: connection_1.Counterparty.fromPartial({ + clientId: "07-tendermint-0", + connectionId: "connection-0", + prefix: commitment_1.MerklePrefix.fromPartial({ + keyPrefix: (0, encoding_1.fromBase64)("aWJj") + }) + }) +}); diff --git a/build/queries/index.js b/build/queries/index.js new file mode 100644 index 0000000..528a232 --- /dev/null +++ b/build/queries/index.js @@ -0,0 +1,34 @@ +"use strict"; +// Base symbols +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +exports.__esModule = true; +exports.decodeCosmosSdkDecFromProto = exports.createProtobufRpcClient = exports.createPagination = exports.setupTxExtension = exports.setupStakingExtension = exports.setupMintExtension = exports.setupIbcExtension = exports.setupGovExtension = exports.setupDistributionExtension = exports.setupBankExtension = exports.setupAuthExtension = exports.QueryClient = void 0; +var queryclient_1 = require("./queryclient"); +__createBinding(exports, queryclient_1, "QueryClient"); +// Extensions +var auth_1 = require("./auth"); +__createBinding(exports, auth_1, "setupAuthExtension"); +var bank_1 = require("./bank"); +__createBinding(exports, bank_1, "setupBankExtension"); +var distribution_1 = require("./distribution"); +__createBinding(exports, distribution_1, "setupDistributionExtension"); +var gov_1 = require("./gov"); +__createBinding(exports, gov_1, "setupGovExtension"); +var ibc_1 = require("./ibc"); +__createBinding(exports, ibc_1, "setupIbcExtension"); +var mint_1 = require("./mint"); +__createBinding(exports, mint_1, "setupMintExtension"); +var staking_1 = require("./staking"); +__createBinding(exports, staking_1, "setupStakingExtension"); +var tx_1 = require("./tx"); +__createBinding(exports, tx_1, "setupTxExtension"); +var utils_1 = require("./utils"); +__createBinding(exports, utils_1, "createPagination"); +__createBinding(exports, utils_1, "createProtobufRpcClient"); +__createBinding(exports, utils_1, "decodeCosmosSdkDecFromProto"); diff --git a/build/queries/mint.js b/build/queries/mint.js new file mode 100644 index 0000000..8301465 --- /dev/null +++ b/build/queries/mint.js @@ -0,0 +1,96 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupMintExtension = void 0; +var utils_1 = require("@cosmjs/utils"); +var query_1 = require("cosmjs-types/cosmos/mint/v1beta1/query"); +var __1 = require("../"); +var utils_2 = require("./utils"); +function setupMintExtension(base) { + var _this = this; + var rpc = (0, __1.createProtobufRpcClient)(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var queryService = new query_1.QueryClientImpl(rpc); + return { + mint: { + params: function () { return __awaiter(_this, void 0, void 0, function () { + var params; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Params({})]; + case 1: + params = (_a.sent()).params; + (0, utils_1.assert)(params); + return [2 /*return*/, { + blocksPerYear: params.blocksPerYear, + goalBonded: (0, utils_2.decodeCosmosSdkDecFromProto)(params.goalBonded), + inflationMin: (0, utils_2.decodeCosmosSdkDecFromProto)(params.inflationMin), + inflationMax: (0, utils_2.decodeCosmosSdkDecFromProto)(params.inflationMax), + inflationRateChange: (0, utils_2.decodeCosmosSdkDecFromProto)(params.inflationRateChange), + mintDenom: params.mintDenom + }]; + } + }); + }); }, + inflation: function () { return __awaiter(_this, void 0, void 0, function () { + var inflation; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Inflation({})]; + case 1: + inflation = (_a.sent()).inflation; + return [2 /*return*/, (0, utils_2.decodeCosmosSdkDecFromProto)(inflation)]; + } + }); + }); }, + annualProvisions: function () { return __awaiter(_this, void 0, void 0, function () { + var annualProvisions; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.AnnualProvisions({})]; + case 1: + annualProvisions = (_a.sent()).annualProvisions; + return [2 /*return*/, (0, utils_2.decodeCosmosSdkDecFromProto)(annualProvisions)]; + } + }); + }); } + } + }; +} +exports.setupMintExtension = setupMintExtension; diff --git a/build/queries/mint.spec.js b/build/queries/mint.spec.js new file mode 100644 index 0000000..17394b0 --- /dev/null +++ b/build/queries/mint.spec.js @@ -0,0 +1,125 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var __1 = require("../"); +var testutils_spec_1 = require("../testutils.spec"); +var mint_1 = require("./mint"); +function makeClientWithMint(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [__1.QueryClient.withExtensions(tmClient, mint_1.setupMintExtension), tmClient]]; + } + }); + }); +} +describe("MintExtension", function () { + describe("params", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, params; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithMint(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.mint.params()]; + case 2: + params = _b.sent(); + expect(params.blocksPerYear.toNumber()).toBeGreaterThan(100000); + expect(params.blocksPerYear.toNumber()).toBeLessThan(100000000); + expect(params.goalBonded.toString()).toEqual("0.67"); + expect(params.inflationMin.toString()).toEqual("0.07"); + expect(params.inflationMax.toString()).toEqual("0.2"); + expect(params.inflationRateChange.toString()).toEqual("0.13"); + expect(params.mintDenom).toEqual(testutils_spec_1.simapp.denomStaking); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("inflation", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, inflation; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithMint(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.mint.inflation()]; + case 2: + inflation = _b.sent(); + expect(inflation.toFloatApproximation()).toBeGreaterThan(0.13); + expect(inflation.toFloatApproximation()).toBeLessThan(0.1301); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("annualProvisions", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, annualProvisions; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithMint(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.mint.annualProvisions()]; + case 2: + annualProvisions = _b.sent(); + expect(annualProvisions.toFloatApproximation()).toBeGreaterThan(5400000000); + expect(annualProvisions.toFloatApproximation()).toBeLessThan(5500000000); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/queryclient.js b/build/queries/queryclient.js new file mode 100644 index 0000000..7ff7784 --- /dev/null +++ b/build/queries/queryclient.js @@ -0,0 +1,249 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.QueryClient = void 0; +/* eslint-disable no-dupe-class-members, @typescript-eslint/ban-types, @typescript-eslint/naming-convention */ +var ics23_1 = require("@confio/ics23"); +var encoding_1 = require("@cosmjs/encoding"); +var stream_1 = require("@cosmjs/stream"); +var utils_1 = require("@cosmjs/utils"); +function checkAndParseOp(op, kind, key) { + if (op.type !== kind) { + throw new Error("Op expected to be " + kind + ", got \"" + op.type); + } + if (!(0, utils_1.arrayContentEquals)(key, op.key)) { + throw new Error("Proven key different than queried key.\nQuery: " + (0, encoding_1.toHex)(key) + "\nProven: " + (0, encoding_1.toHex)(op.key)); + } + return ics23_1.ics23.CommitmentProof.decode(op.data); +} +var QueryClient = /** @class */ (function () { + function QueryClient(tmClient) { + this.tmClient = tmClient; + } + QueryClient.withExtensions = function (tmClient) { + var extensionSetups = []; + for (var _i = 1; _i < arguments.length; _i++) { + extensionSetups[_i - 1] = arguments[_i]; + } + var client = new QueryClient(tmClient); + var extensions = extensionSetups.map(function (setupExtension) { return setupExtension(client); }); + for (var _a = 0, extensions_1 = extensions; _a < extensions_1.length; _a++) { + var extension = extensions_1[_a]; + (0, utils_1.assert)((0, utils_1.isNonNullObject)(extension), "Extension must be a non-null object"); + for (var _b = 0, _c = Object.entries(extension); _b < _c.length; _b++) { + var _d = _c[_b], moduleKey = _d[0], moduleValue = _d[1]; + (0, utils_1.assert)((0, utils_1.isNonNullObject)(moduleValue), "Module must be a non-null object. Found type " + typeof moduleValue + " for module \"" + moduleKey + "\"."); + var current = client[moduleKey] || {}; + client[moduleKey] = __assign(__assign({}, current), moduleValue); + } + } + return client; + }; + QueryClient.prototype.queryVerified = function (store, key, desiredHeight) { + return __awaiter(this, void 0, void 0, function () { + var _a, height, proof, value, subProof, storeProof, header; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: return [4 /*yield*/, this.queryRawProof(store, key, desiredHeight)]; + case 1: + _a = _b.sent(), height = _a.height, proof = _a.proof, value = _a.value; + subProof = checkAndParseOp(proof.ops[0], "ics23:iavl", key); + storeProof = checkAndParseOp(proof.ops[1], "ics23:simple", (0, encoding_1.toAscii)(store)); + // this must always be existence, if the store is not a typo + (0, utils_1.assert)(storeProof.exist); + (0, utils_1.assert)(storeProof.exist.value); + // this may be exist or non-exist, depends on response + if (!value || value.length === 0) { + // non-existence check + (0, utils_1.assert)(subProof.nonexist); + // the subproof must map the desired key to the "value" of the storeProof + (0, ics23_1.verifyNonExistence)(subProof.nonexist, ics23_1.iavlSpec, storeProof.exist.value, key); + } + else { + // existence check + (0, utils_1.assert)(subProof.exist); + (0, utils_1.assert)(subProof.exist.value); + // the subproof must map the desired key to the "value" of the storeProof + (0, ics23_1.verifyExistence)(subProof.exist, ics23_1.iavlSpec, storeProof.exist.value, key, value); + } + return [4 /*yield*/, this.getNextHeader(height)]; + case 2: + header = _b.sent(); + (0, ics23_1.verifyExistence)(storeProof.exist, ics23_1.tendermintSpec, header.appHash, (0, encoding_1.toAscii)(store), storeProof.exist.value); + return [2 /*return*/, value]; + } + }); + }); + }; + QueryClient.prototype.queryRawProof = function (store, queryKey, desiredHeight) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var _b, key, value, height, proof, code, log; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: return [4 /*yield*/, 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: queryKey, + prove: true, + height: desiredHeight + })]; + case 1: + _b = _c.sent(), key = _b.key, value = _b.value, height = _b.height, proof = _b.proof, code = _b.code, log = _b.log; + if (code) { + throw new Error("Query failed with (" + code + "): " + log); + } + if (!(0, utils_1.arrayContentEquals)(queryKey, key)) { + throw new Error("Response key " + (0, encoding_1.toHex)(key) + " doesn't match query key " + (0, encoding_1.toHex)(queryKey)); + } + if (!height) { + throw new Error("No query height returned"); + } + if (!proof || proof.ops.length !== 2) { + throw new Error("Expected 2 proof ops, got " + ((_a = proof === null || proof === void 0 ? void 0 : proof.ops.length) !== null && _a !== void 0 ? _a : 0) + ". Are you using stargate?"); + } + // we don't need the results, but we can ensure the data is the proper format + checkAndParseOp(proof.ops[0], "ics23:iavl", key); + checkAndParseOp(proof.ops[1], "ics23:simple", (0, encoding_1.toAscii)(store)); + return [2 /*return*/, { + key: key, + value: value, + height: height, + // need to clone this: readonly input / writeable output + proof: { + ops: __spreadArray([], proof.ops, true) + } + }]; + } + }); + }); + }; + QueryClient.prototype.queryUnverified = function (path, request) { + return __awaiter(this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.tmClient.abciQuery({ + path: path, + data: request, + prove: false + })]; + case 1: + response = _a.sent(); + if (response.code) { + throw new Error("Query failed with (" + response.code + "): " + response.log); + } + return [2 /*return*/, response.value]; + } + }); + }); + }; + // this must return the header for height+1 + // throws an error if height is 0 or undefined + QueryClient.prototype.getNextHeader = function (height) { + return __awaiter(this, void 0, void 0, function () { + var searchHeight, nextHeader, headersSubscription, firstHeader, correctHeader; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, utils_1.assertDefined)(height); + if (height === 0) { + throw new Error("Query returned height 0, cannot prove it"); + } + searchHeight = height + 1; + try { + headersSubscription = this.tmClient.subscribeNewBlockHeader(); + } + catch (_b) { + // Ignore exception caused by non-WebSocket Tendermint clients + } + if (!headersSubscription) return [3 /*break*/, 2]; + return [4 /*yield*/, (0, stream_1.firstEvent)(headersSubscription)]; + case 1: + firstHeader = _a.sent(); + // The first header we get might not be n+1 but n+2 or even higher. In such cases we fall back on a query. + if (firstHeader.height === searchHeight) { + nextHeader = firstHeader; + } + _a.label = 2; + case 2: + if (!!nextHeader) return [3 /*break*/, 7]; + return [4 /*yield*/, this.tmClient.blockchain(height, searchHeight)]; + case 3: + correctHeader = (_a.sent()).blockMetas + .map(function (meta) { return meta.header; }) + .find(function (h) { return h.height === searchHeight; }); + if (!correctHeader) return [3 /*break*/, 4]; + nextHeader = correctHeader; + return [3 /*break*/, 6]; + case 4: return [4 /*yield*/, (0, utils_1.sleep)(1000)]; + case 5: + _a.sent(); + _a.label = 6; + case 6: return [3 /*break*/, 2]; + case 7: + (0, utils_1.assert)(nextHeader.height === searchHeight, "Got wrong header. This is a bug in the logic above."); + return [2 /*return*/, nextHeader]; + } + }); + }); + }; + return QueryClient; +}()); +exports.QueryClient = QueryClient; diff --git a/build/queries/queryclient.spec.js b/build/queries/queryclient.spec.js new file mode 100644 index 0000000..d741636 --- /dev/null +++ b/build/queries/queryclient.spec.js @@ -0,0 +1,161 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention */ +var encoding_1 = require("@cosmjs/encoding"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var bank_1 = require("cosmjs-types/cosmos/bank/v1beta1/bank"); +var query_1 = require("cosmjs-types/cosmos/bank/v1beta1/query"); +var testutils_spec_1 = require("../testutils.spec"); +var queryclient_1 = require("./queryclient"); +function makeClient(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient), tmClient]]; + } + }); + }); +} +/** + * See + * - https://github.com/cosmos/cosmos-sdk/blob/v0.42.10/x/bank/types/key.go#L27 + * - https://github.com/cosmos/cosmos-sdk/blob/v0.44.2/x/bank/types/key.go#L28 + */ +var denomMetadataPrefix = new Uint8Array([0x01]); +describe("QueryClient", function () { + describe("queryVerified", function () { + it("works via WebSockets", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, key, data, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClient(testutils_spec_1.simapp.tendermintUrlWs)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + key = Uint8Array.from(__spreadArray(__spreadArray(__spreadArray([], denomMetadataPrefix, true), (0, encoding_1.toAscii)(testutils_spec_1.simapp.denomFee), true), (0, encoding_1.toAscii)(testutils_spec_1.simapp.denomFee), true)); + return [4 /*yield*/, client.queryVerified("bank", key)]; + case 2: + data = _b.sent(); + response = bank_1.Metadata.decode(data); + expect(response.base).toEqual(testutils_spec_1.simapp.denomFee); + expect(response.description).toEqual("The fee token of this test chain"); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works via http", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, key, data, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClient(testutils_spec_1.simapp.tendermintUrlHttp)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + key = Uint8Array.from(__spreadArray(__spreadArray(__spreadArray([], denomMetadataPrefix, true), (0, encoding_1.toAscii)(testutils_spec_1.simapp.denomFee), true), (0, encoding_1.toAscii)(testutils_spec_1.simapp.denomFee), true)); + return [4 /*yield*/, client.queryVerified("bank", key)]; + case 2: + data = _b.sent(); + response = bank_1.Metadata.decode(data); + expect(response.base).toEqual(testutils_spec_1.simapp.denomFee); + expect(response.description).toEqual("The fee token of this test chain"); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("queryUnverified", function () { + it("works via WebSockets", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, requestData, data, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClient(testutils_spec_1.simapp.tendermintUrlWs)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + requestData = Uint8Array.from(query_1.QueryAllBalancesRequest.encode({ address: testutils_spec_1.unused.address }).finish()); + return [4 /*yield*/, client.queryUnverified("/cosmos.bank.v1beta1.Query/AllBalances", requestData)]; + case 2: + data = _b.sent(); + response = query_1.QueryAllBalancesResponse.decode(data); + expect(response.balances.length).toEqual(2); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works via http", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, requestData, data, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClient(testutils_spec_1.simapp.tendermintUrlHttp)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + requestData = Uint8Array.from(query_1.QueryAllBalancesRequest.encode({ address: testutils_spec_1.unused.address }).finish()); + return [4 /*yield*/, client.queryUnverified("/cosmos.bank.v1beta1.Query/AllBalances", requestData)]; + case 2: + data = _b.sent(); + response = query_1.QueryAllBalancesResponse.decode(data); + expect(response.balances.length).toEqual(2); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/staking.js b/build/queries/staking.js new file mode 100644 index 0000000..0ac77ce --- /dev/null +++ b/build/queries/staking.js @@ -0,0 +1,243 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupStakingExtension = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var query_1 = require("cosmjs-types/cosmos/staking/v1beta1/query"); +var long_1 = require("long"); +var utils_1 = require("./utils"); +function setupStakingExtension(base) { + var _this = this; + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var rpc = (0, utils_1.createProtobufRpcClient)(base); + var queryService = new query_1.QueryClientImpl(rpc); + return { + staking: { + delegation: function (delegatorAddress, validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Delegation({ + delegatorAddr: delegatorAddress, + validatorAddr: validatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegatorDelegations: function (delegatorAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegatorDelegations({ + delegatorAddr: delegatorAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegatorUnbondingDelegations: function (delegatorAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegatorUnbondingDelegations({ + delegatorAddr: delegatorAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegatorValidator: function (delegatorAddress, validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegatorValidator({ + delegatorAddr: delegatorAddress, + validatorAddr: validatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + delegatorValidators: function (delegatorAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.DelegatorValidators({ + delegatorAddr: delegatorAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + historicalInfo: function (height) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.HistoricalInfo({ + height: long_1["default"].fromNumber(height, true) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + params: function () { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Params({})]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + pool: function () { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Pool({})]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + redelegations: function (delegatorAddress, sourceValidatorAddress, destinationValidatorAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Redelegations({ + delegatorAddr: delegatorAddress, + srcValidatorAddr: sourceValidatorAddress, + dstValidatorAddr: destinationValidatorAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + unbondingDelegation: function (delegatorAddress, validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.UnbondingDelegation({ + delegatorAddr: delegatorAddress, + validatorAddr: validatorAddress + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validator: function (validatorAddress) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Validator({ validatorAddr: validatorAddress })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validatorDelegations: function (validatorAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.ValidatorDelegations({ + validatorAddr: validatorAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validators: function (status, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.Validators({ + status: status, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + validatorUnbondingDelegations: function (validatorAddress, paginationKey) { return __awaiter(_this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, queryService.ValidatorUnbondingDelegations({ + validatorAddr: validatorAddress, + pagination: (0, utils_1.createPagination)(paginationKey) + })]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); } + } + }; +} +exports.setupStakingExtension = setupStakingExtension; diff --git a/build/queries/staking.spec.js b/build/queries/staking.spec.js new file mode 100644 index 0000000..1a3b033 --- /dev/null +++ b/build/queries/staking.spec.js @@ -0,0 +1,407 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention */ +var proto_signing_1 = require("@cosmjs/proto-signing"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var signingstargateclient_1 = require("../signingstargateclient"); +var stargateclient_1 = require("../stargateclient"); +var testutils_spec_1 = require("../testutils.spec"); +var queryclient_1 = require("./queryclient"); +var staking_1 = require("./staking"); +function makeClientWithStaking(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, staking_1.setupStakingExtension), tmClient]]; + } + }); + }); +} +describe("StakingExtension", function () { + var defaultFee = { + amount: (0, proto_signing_1.coins)(25000, "ucosm"), + gas: "1500000" + }; + beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, memo, result, msg, msgAny, memo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!(0, testutils_spec_1.simappEnabled)()) return [3 /*break*/, 6]; + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(25000, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + memo = "Test delegation for Stargate"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], defaultFee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + msg = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(100, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: msg + }; + memo = "Test undelegation for Stargate"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], defaultFee, memo)]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [4 /*yield*/, (0, utils_1.sleep)(75)]; + case 5: + _a.sent(); // wait until transactions are indexed + _a.label = 6; + case 6: return [2 /*return*/]; + } + }); + }); }); + describe("delegation", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.delegation(testutils_spec_1.faucet.address0, testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.delegationResponse).toBeDefined(); + expect(response.delegationResponse).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegatorDelegations", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.delegatorDelegations(testutils_spec_1.faucet.address0)]; + case 2: + response = _b.sent(); + expect(response.delegationResponses).toBeDefined(); + expect(response.delegationResponses).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegatorUnbondingDelegations", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.delegatorUnbondingDelegations(testutils_spec_1.faucet.address0)]; + case 2: + response = _b.sent(); + expect(response.unbondingResponses).toBeDefined(); + expect(response.unbondingResponses).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegatorValidator", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.delegatorValidator(testutils_spec_1.faucet.address0, testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.validator).toBeDefined(); + expect(response.validator).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("delegatorValidators", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.delegatorValidators(testutils_spec_1.faucet.address0)]; + case 2: + response = _b.sent(); + expect(response.validators).toBeDefined(); + expect(response.validators).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("historicalInfo", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.historicalInfo(5)]; + case 2: + response = _b.sent(); + expect(response.hist).toBeDefined(); + expect(response.hist).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("params", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.params()]; + case 2: + response = _b.sent(); + expect(response.params).toBeDefined(); + expect(response.params).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("pool", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.pool()]; + case 2: + response = _b.sent(); + expect(response.pool).toBeDefined(); + expect(response.pool).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("redelegations", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + // TODO: Set up a result for this test + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, expectAsync(client.staking.redelegations(testutils_spec_1.faucet.address0, testutils_spec_1.validator.validatorAddress, testutils_spec_1.validator.validatorAddress)).toBeRejectedWithError(/redelegation not found/i)]; + case 2: + _b.sent(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("unbondingDelegation", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.unbondingDelegation(testutils_spec_1.faucet.address0, testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.unbond).toBeDefined(); + expect(response.unbond).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validator", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.validator(testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.validator).toBeDefined(); + expect(response.validator).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validatorDelegations", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.validatorDelegations(testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.delegationResponses).toBeDefined(); + expect(response.delegationResponses).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validators", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.validators("BOND_STATUS_BONDED")]; + case 2: + response = _b.sent(); + expect(response.validators).toBeDefined(); + expect(response.validators).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("validatorUnbondingDelegations", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, makeClientWithStaking(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _b.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.staking.validatorUnbondingDelegations(testutils_spec_1.validator.validatorAddress)]; + case 2: + response = _b.sent(); + expect(response.unbondingResponses).toBeDefined(); + expect(response.unbondingResponses).not.toBeNull(); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/tx.js b/build/queries/tx.js new file mode 100644 index 0000000..b55f904 --- /dev/null +++ b/build/queries/tx.js @@ -0,0 +1,106 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.setupTxExtension = void 0; +var proto_signing_1 = require("@cosmjs/proto-signing"); +var signing_1 = require("cosmjs-types/cosmos/tx/signing/v1beta1/signing"); +var service_1 = require("cosmjs-types/cosmos/tx/v1beta1/service"); +var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var long_1 = require("long"); +var utils_1 = require("./utils"); +function setupTxExtension(base) { + var _this = this; + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + var rpc = (0, utils_1.createProtobufRpcClient)(base); + var queryService = new service_1.ServiceClientImpl(rpc); + return { + tx: { + getTx: function (txId) { return __awaiter(_this, void 0, void 0, function () { + var request, response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + request = { + hash: txId + }; + return [4 /*yield*/, queryService.GetTx(request)]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); }, + simulate: function (messages, memo, signer, sequence) { return __awaiter(_this, void 0, void 0, function () { + var request, response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + request = service_1.SimulateRequest.fromPartial({ + tx: tx_1.Tx.fromPartial({ + authInfo: tx_1.AuthInfo.fromPartial({ + fee: tx_1.Fee.fromPartial({}), + signerInfos: [ + { + publicKey: (0, proto_signing_1.encodePubkey)(signer), + sequence: long_1["default"].fromNumber(sequence, true), + modeInfo: { single: { mode: signing_1.SignMode.SIGN_MODE_UNSPECIFIED } } + }, + ] + }), + body: tx_1.TxBody.fromPartial({ + messages: Array.from(messages), + memo: memo + }), + signatures: [new Uint8Array()] + }), + // Sending serialized `txBytes` is the future. But + // this is not available in Comsos SDK 0.42. + txBytes: undefined + }); + return [4 /*yield*/, queryService.Simulate(request)]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); } + } + }; +} +exports.setupTxExtension = setupTxExtension; diff --git a/build/queries/tx.spec.js b/build/queries/tx.spec.js new file mode 100644 index 0000000..87aa394 --- /dev/null +++ b/build/queries/tx.spec.js @@ -0,0 +1,160 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var proto_signing_1 = require("@cosmjs/proto-signing"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var long_1 = require("long"); +var signingstargateclient_1 = require("../signingstargateclient"); +var stargateclient_1 = require("../stargateclient"); +var testutils_spec_1 = require("../testutils.spec"); +var queryclient_1 = require("./queryclient"); +var tx_1 = require("./tx"); +var utils_2 = require("./utils"); +function makeClientWithTx(rpcUrl) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(rpcUrl)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, [queryclient_1.QueryClient.withExtensions(tmClient, tx_1.setupTxExtension), tmClient]]; + } + }); + }); +} +describe("TxExtension", function () { + var defaultFee = { + amount: (0, proto_signing_1.coins)(25000, "ucosm"), + gas: "1500000" + }; + var txHash; + var memo; + beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, recipient, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!(0, testutils_spec_1.simappEnabled)()) return [3 /*break*/, 5]; + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + recipient = (0, testutils_spec_1.makeRandomAddress)(); + memo = "Test tx " + Date.now(); + return [4 /*yield*/, client.sendTokens(testutils_spec_1.faucet.address0, recipient, (0, proto_signing_1.coins)(25000, "ucosm"), defaultFee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + txHash = result.transactionHash; + return [4 /*yield*/, (0, utils_1.sleep)(75)]; + case 4: + _a.sent(); // wait until transactions are indexed + _a.label = 5; + case 5: return [2 /*return*/]; + } + }); + }); }); + describe("getTx", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, response; + var _b, _c; + return __generator(this, function (_d) { + switch (_d.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assertDefined)(txHash); + (0, utils_1.assertDefined)(memo); + return [4 /*yield*/, makeClientWithTx(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _d.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, client.tx.getTx(txHash)]; + case 2: + response = _d.sent(); + expect((_c = (_b = response.tx) === null || _b === void 0 ? void 0 : _b.body) === null || _c === void 0 ? void 0 : _c.memo).toEqual(memo); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("simulate", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var _a, client, tmClient, sequenceClient, registry, msg, msgAny, sequence, response; + var _b, _c, _d; + return __generator(this, function (_e) { + switch (_e.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assertDefined)(txHash); + (0, utils_1.assertDefined)(memo); + return [4 /*yield*/, makeClientWithTx(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + _a = _e.sent(), client = _a[0], tmClient = _a[1]; + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 2: + sequenceClient = _e.sent(); + registry = new proto_signing_1.Registry(signingstargateclient_1.defaultRegistryTypes); + msg = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(25000, "ustake") + }; + msgAny = registry.encodeAsAny({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }); + return [4 /*yield*/, sequenceClient.getSequence(testutils_spec_1.faucet.address0)]; + case 3: + sequence = (_e.sent()).sequence; + return [4 /*yield*/, client.tx.simulate([msgAny], "foo", testutils_spec_1.faucet.pubkey0, sequence)]; + case 4: + response = _e.sent(); + expect((_b = response.gasInfo) === null || _b === void 0 ? void 0 : _b.gasUsed.toNumber()).toBeGreaterThanOrEqual(101000); + expect((_c = response.gasInfo) === null || _c === void 0 ? void 0 : _c.gasUsed.toNumber()).toBeLessThanOrEqual(150000); + expect((_d = response.gasInfo) === null || _d === void 0 ? void 0 : _d.gasWanted).toEqual((0, utils_2.longify)(long_1["default"].UZERO)); + tmClient.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/queries/utils.js b/build/queries/utils.js new file mode 100644 index 0000000..6299f79 --- /dev/null +++ b/build/queries/utils.js @@ -0,0 +1,72 @@ +"use strict"; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.decodeCosmosSdkDecFromProto = exports.longify = exports.createProtobufRpcClient = exports.createPagination = exports.toAccAddress = void 0; +var encoding_1 = require("@cosmjs/encoding"); +var math_1 = require("@cosmjs/math"); +var pagination_1 = require("cosmjs-types/cosmos/base/query/v1beta1/pagination"); +var long_1 = require("long"); +/** + * 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. + */ +function toAccAddress(address) { + return encoding_1.Bech32.decode(address).data; +} +exports.toAccAddress = toAccAddress; +/** + * If paginationKey is set, return a `PageRequest` with the given key. + * If paginationKey is unset, return `undefined`. + * + * Use this with a query response's pagination next key to + * request the next page. + */ +function createPagination(paginationKey) { + return paginationKey + ? pagination_1.PageRequest.fromPartial({ + key: paginationKey, + offset: long_1["default"].fromNumber(0, true), + limit: long_1["default"].fromNumber(0, true), + countTotal: false + }) + : undefined; +} +exports.createPagination = createPagination; +function createProtobufRpcClient(base) { + return { + request: function (service, method, data) { + var path = "/" + service + "/" + method; + return base.queryUnverified(path, data); + } + }; +} +exports.createProtobufRpcClient = createProtobufRpcClient; +/** + * Takes a uint64 value as string, number, Long or Uint64 and returns an unsigned Long instance + * of it. + */ +function longify(value) { + var checkedValue = math_1.Uint64.fromString(value.toString()); + return long_1["default"].fromBytesBE(__spreadArray([], checkedValue.toBytesBigEndian(), true), true); +} +exports.longify = longify; +/** + * Takes a string or binary encoded `github.com/cosmos/cosmos-sdk/types.Dec` from the + * protobuf API and converts it into a `Decimal` with 18 fractional digits. + * + * See https://github.com/cosmos/cosmos-sdk/issues/10863 for more context why this is needed. + */ +function decodeCosmosSdkDecFromProto(input) { + var asString = typeof input === "string" ? input : (0, encoding_1.fromAscii)(input); + return math_1.Decimal.fromAtomics(asString, 18); +} +exports.decodeCosmosSdkDecFromProto = decodeCosmosSdkDecFromProto; diff --git a/build/queries/utils.spec.js b/build/queries/utils.spec.js new file mode 100644 index 0000000..b91f8ba --- /dev/null +++ b/build/queries/utils.spec.js @@ -0,0 +1,18 @@ +"use strict"; +exports.__esModule = true; +var encoding_1 = require("@cosmjs/encoding"); +var utils_1 = require("./utils"); +describe("utils", function () { + describe("decodeCosmosSdkDecFromProto", function () { + it("works for string inputs", function () { + expect((0, utils_1.decodeCosmosSdkDecFromProto)("0").toString()).toEqual("0"); + expect((0, utils_1.decodeCosmosSdkDecFromProto)("1").toString()).toEqual("0.000000000000000001"); + expect((0, utils_1.decodeCosmosSdkDecFromProto)("3000000").toString()).toEqual("0.000000000003"); + expect((0, utils_1.decodeCosmosSdkDecFromProto)("123456789123456789").toString()).toEqual("0.123456789123456789"); + expect((0, utils_1.decodeCosmosSdkDecFromProto)("1234567891234567890").toString()).toEqual("1.23456789123456789"); + }); + it("works for byte inputs", function () { + expect((0, utils_1.decodeCosmosSdkDecFromProto)((0, encoding_1.fromHex)("313330303033343138373830313631333938")).toString()).toEqual("0.130003418780161398"); + }); + }); +}); diff --git a/build/search.js b/build/search.js new file mode 100644 index 0000000..bffa9a1 --- /dev/null +++ b/build/search.js @@ -0,0 +1,15 @@ +"use strict"; +exports.__esModule = true; +exports.isSearchByTagsQuery = exports.isSearchBySentFromOrToQuery = exports.isSearchByHeightQuery = void 0; +function isSearchByHeightQuery(query) { + return query.height !== undefined; +} +exports.isSearchByHeightQuery = isSearchByHeightQuery; +function isSearchBySentFromOrToQuery(query) { + return query.sentFromOrTo !== undefined; +} +exports.isSearchBySentFromOrToQuery = isSearchBySentFromOrToQuery; +function isSearchByTagsQuery(query) { + return query.tags !== undefined; +} +exports.isSearchByTagsQuery = isSearchByTagsQuery; diff --git a/build/signingstargateclient.js b/build/signingstargateclient.js new file mode 100644 index 0000000..3189d66 --- /dev/null +++ b/build/signingstargateclient.js @@ -0,0 +1,433 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.SigningStargateClient = exports.defaultRegistryTypes = void 0; +var amino_1 = require("@cosmjs/amino"); +var encoding_1 = require("@cosmjs/encoding"); +var math_1 = require("@cosmjs/math"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var tx_1 = require("cosmjs-types/cosmos/bank/v1beta1/tx"); +var tx_2 = require("cosmjs-types/cosmos/distribution/v1beta1/tx"); +var tx_3 = require("cosmjs-types/cosmos/gov/v1beta1/tx"); +var tx_4 = require("cosmjs-types/cosmos/staking/v1beta1/tx"); +var signing_1 = require("cosmjs-types/cosmos/tx/signing/v1beta1/signing"); +var tx_5 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var tx_6 = require("cosmjs-types/ibc/applications/transfer/v1/tx"); +var tx_7 = require("cosmjs-types/ibc/core/channel/v1/tx"); +var tx_8 = require("cosmjs-types/ibc/core/client/v1/tx"); +var tx_9 = require("cosmjs-types/ibc/core/connection/v1/tx"); +var long_1 = require("long"); +var aminotypes_1 = require("./aminotypes"); +var fee_1 = require("./fee"); +var stargateclient_1 = require("./stargateclient"); +exports.defaultRegistryTypes = [ + ["/cosmos.bank.v1beta1.MsgMultiSend", tx_1.MsgMultiSend], + ["/cosmos.distribution.v1beta1.MsgFundCommunityPool", tx_2.MsgFundCommunityPool], + ["/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", tx_2.MsgSetWithdrawAddress], + ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", tx_2.MsgWithdrawDelegatorReward], + ["/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", tx_2.MsgWithdrawValidatorCommission], + ["/cosmos.gov.v1beta1.MsgDeposit", tx_3.MsgDeposit], + ["/cosmos.gov.v1beta1.MsgSubmitProposal", tx_3.MsgSubmitProposal], + ["/cosmos.gov.v1beta1.MsgVote", tx_3.MsgVote], + ["/cosmos.staking.v1beta1.MsgBeginRedelegate", tx_4.MsgBeginRedelegate], + ["/cosmos.staking.v1beta1.MsgCreateValidator", tx_4.MsgCreateValidator], + ["/cosmos.staking.v1beta1.MsgDelegate", tx_4.MsgDelegate], + ["/cosmos.staking.v1beta1.MsgEditValidator", tx_4.MsgEditValidator], + ["/cosmos.staking.v1beta1.MsgUndelegate", tx_4.MsgUndelegate], + ["/ibc.core.channel.v1.MsgChannelOpenInit", tx_7.MsgChannelOpenInit], + ["/ibc.core.channel.v1.MsgChannelOpenTry", tx_7.MsgChannelOpenTry], + ["/ibc.core.channel.v1.MsgChannelOpenAck", tx_7.MsgChannelOpenAck], + ["/ibc.core.channel.v1.MsgChannelOpenConfirm", tx_7.MsgChannelOpenConfirm], + ["/ibc.core.channel.v1.MsgChannelCloseInit", tx_7.MsgChannelCloseInit], + ["/ibc.core.channel.v1.MsgChannelCloseConfirm", tx_7.MsgChannelCloseConfirm], + ["/ibc.core.channel.v1.MsgRecvPacket", tx_7.MsgRecvPacket], + ["/ibc.core.channel.v1.MsgTimeout", tx_7.MsgTimeout], + ["/ibc.core.channel.v1.MsgTimeoutOnClose", tx_7.MsgTimeoutOnClose], + ["/ibc.core.channel.v1.MsgAcknowledgement", tx_7.MsgAcknowledgement], + ["/ibc.core.client.v1.MsgCreateClient", tx_8.MsgCreateClient], + ["/ibc.core.client.v1.MsgUpdateClient", tx_8.MsgUpdateClient], + ["/ibc.core.client.v1.MsgUpgradeClient", tx_8.MsgUpgradeClient], + ["/ibc.core.client.v1.MsgSubmitMisbehaviour", tx_8.MsgSubmitMisbehaviour], + ["/ibc.core.connection.v1.MsgConnectionOpenInit", tx_9.MsgConnectionOpenInit], + ["/ibc.core.connection.v1.MsgConnectionOpenTry", tx_9.MsgConnectionOpenTry], + ["/ibc.core.connection.v1.MsgConnectionOpenAck", tx_9.MsgConnectionOpenAck], + ["/ibc.core.connection.v1.MsgConnectionOpenConfirm", tx_9.MsgConnectionOpenConfirm], + ["/ibc.applications.transfer.v1.MsgTransfer", tx_6.MsgTransfer], +]; +function createDefaultRegistry() { + return new proto_signing_1.Registry(exports.defaultRegistryTypes); +} +var SigningStargateClient = /** @class */ (function (_super) { + __extends(SigningStargateClient, _super); + function SigningStargateClient(tmClient, signer, options) { + var _this = _super.call(this, tmClient) || this; + var _a = options.registry, registry = _a === void 0 ? createDefaultRegistry() : _a, _b = options.aminoTypes, aminoTypes = _b === void 0 ? new aminotypes_1.AminoTypes({ prefix: options.prefix }) : _b; + _this.registry = registry; + _this.aminoTypes = aminoTypes; + _this.signer = signer; + _this.broadcastTimeoutMs = options.broadcastTimeoutMs; + _this.broadcastPollIntervalMs = options.broadcastPollIntervalMs; + _this.gasPrice = options.gasPrice; + return _this; + } + SigningStargateClient.connectWithSigner = function (endpoint, signer, options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(endpoint)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, new SigningStargateClient(tmClient, signer, options)]; + } + }); + }); + }; + /** + * Creates a client in offline mode. + * + * This should only be used in niche cases where you know exactly what you're doing, + * e.g. when building an offline signing application. + * + * When you try to use online functionality with such a signer, an + * exception will be raised. + */ + SigningStargateClient.offline = function (signer, options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, new SigningStargateClient(undefined, signer, options)]; + }); + }); + }; + SigningStargateClient.prototype.simulate = function (signerAddress, messages, memo) { + return __awaiter(this, void 0, void 0, function () { + var anyMsgs, accountFromSigner, pubkey, sequence, gasInfo; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + anyMsgs = messages.map(function (m) { return _this.registry.encodeAsAny(m); }); + return [4 /*yield*/, this.signer.getAccounts()]; + case 1: + accountFromSigner = (_a.sent()).find(function (account) { return account.address === signerAddress; }); + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer"); + } + pubkey = (0, amino_1.encodeSecp256k1Pubkey)(accountFromSigner.pubkey); + return [4 /*yield*/, this.getSequence(signerAddress)]; + case 2: + sequence = (_a.sent()).sequence; + return [4 /*yield*/, this.forceGetQueryClient().tx.simulate(anyMsgs, memo, pubkey, sequence)]; + case 3: + gasInfo = (_a.sent()).gasInfo; + (0, utils_1.assertDefined)(gasInfo); + return [2 /*return*/, math_1.Uint53.fromString(gasInfo.gasUsed.toString()).toNumber()]; + } + }); + }); + }; + SigningStargateClient.prototype.sendTokens = function (senderAddress, recipientAddress, amount, fee, memo) { + if (memo === void 0) { memo = ""; } + return __awaiter(this, void 0, void 0, function () { + var sendMsg; + return __generator(this, function (_a) { + sendMsg = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: senderAddress, + toAddress: recipientAddress, + amount: __spreadArray([], amount, true) + } + }; + return [2 /*return*/, this.signAndBroadcast(senderAddress, [sendMsg], fee, memo)]; + }); + }); + }; + SigningStargateClient.prototype.delegateTokens = function (delegatorAddress, validatorAddress, amount, fee, memo) { + if (memo === void 0) { memo = ""; } + return __awaiter(this, void 0, void 0, function () { + var delegateMsg; + return __generator(this, function (_a) { + delegateMsg = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: tx_4.MsgDelegate.fromPartial({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress, + amount: amount + }) + }; + return [2 /*return*/, this.signAndBroadcast(delegatorAddress, [delegateMsg], fee, memo)]; + }); + }); + }; + SigningStargateClient.prototype.undelegateTokens = function (delegatorAddress, validatorAddress, amount, fee, memo) { + if (memo === void 0) { memo = ""; } + return __awaiter(this, void 0, void 0, function () { + var undelegateMsg; + return __generator(this, function (_a) { + undelegateMsg = { + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: tx_4.MsgUndelegate.fromPartial({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress, + amount: amount + }) + }; + return [2 /*return*/, this.signAndBroadcast(delegatorAddress, [undelegateMsg], fee, memo)]; + }); + }); + }; + SigningStargateClient.prototype.withdrawRewards = function (delegatorAddress, validatorAddress, fee, memo) { + if (memo === void 0) { memo = ""; } + return __awaiter(this, void 0, void 0, function () { + var withdrawMsg; + return __generator(this, function (_a) { + withdrawMsg = { + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: tx_2.MsgWithdrawDelegatorReward.fromPartial({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress + }) + }; + return [2 /*return*/, this.signAndBroadcast(delegatorAddress, [withdrawMsg], fee, memo)]; + }); + }); + }; + SigningStargateClient.prototype.sendIbcTokens = function (senderAddress, recipientAddress, transferAmount, sourcePort, sourceChannel, timeoutHeight, + /** timeout in seconds */ + timeoutTimestamp, fee, memo) { + if (memo === void 0) { memo = ""; } + return __awaiter(this, void 0, void 0, function () { + var timeoutTimestampNanoseconds, transferMsg; + return __generator(this, function (_a) { + timeoutTimestampNanoseconds = timeoutTimestamp + ? long_1["default"].fromNumber(timeoutTimestamp).multiply(1000000000) + : undefined; + transferMsg = { + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: tx_6.MsgTransfer.fromPartial({ + sourcePort: sourcePort, + sourceChannel: sourceChannel, + sender: senderAddress, + receiver: recipientAddress, + token: transferAmount, + timeoutHeight: timeoutHeight, + timeoutTimestamp: timeoutTimestampNanoseconds + }) + }; + return [2 /*return*/, this.signAndBroadcast(senderAddress, [transferMsg], fee, memo)]; + }); + }); + }; + SigningStargateClient.prototype.signAndBroadcast = function (signerAddress, messages, fee, memo) { + if (memo === void 0) { memo = ""; } + return __awaiter(this, void 0, void 0, function () { + var usedFee, gasEstimation, muliplier, txRaw, txBytes; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!(fee == "auto" || typeof fee === "number")) return [3 /*break*/, 2]; + (0, utils_1.assertDefined)(this.gasPrice, "Gas price must be set in the client options when auto gas is used."); + return [4 /*yield*/, this.simulate(signerAddress, messages, memo)]; + case 1: + gasEstimation = _a.sent(); + muliplier = typeof fee === "number" ? fee : 1.3; + usedFee = (0, fee_1.calculateFee)(Math.round(gasEstimation * muliplier), this.gasPrice); + return [3 /*break*/, 3]; + case 2: + usedFee = fee; + _a.label = 3; + case 3: return [4 /*yield*/, this.sign(signerAddress, messages, usedFee, memo)]; + case 4: + txRaw = _a.sent(); + txBytes = tx_5.TxRaw.encode(txRaw).finish(); + return [2 /*return*/, this.broadcastTx(txBytes, this.broadcastTimeoutMs, this.broadcastPollIntervalMs)]; + } + }); + }); + }; + /** + * Gets account number and sequence from the API, creates a sign doc, + * creates a single signature and assembles the signed transaction. + * + * The sign mode (SIGN_MODE_DIRECT or SIGN_MODE_LEGACY_AMINO_JSON) is determined by this client's signer. + * + * You can pass signer data (account number, sequence and chain ID) explicitly instead of querying them + * from the chain. This is needed when signing for a multisig account, but it also allows for offline signing + * (See the SigningStargateClient.offline constructor). + */ + SigningStargateClient.prototype.sign = function (signerAddress, messages, fee, memo, explicitSignerData) { + return __awaiter(this, void 0, void 0, function () { + var signerData, _a, accountNumber, sequence, chainId; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + if (!explicitSignerData) return [3 /*break*/, 1]; + signerData = explicitSignerData; + return [3 /*break*/, 4]; + case 1: return [4 /*yield*/, this.getSequence(signerAddress)]; + case 2: + _a = _b.sent(), accountNumber = _a.accountNumber, sequence = _a.sequence; + return [4 /*yield*/, this.getChainId()]; + case 3: + chainId = _b.sent(); + signerData = { + accountNumber: accountNumber, + sequence: sequence, + chainId: chainId + }; + _b.label = 4; + case 4: return [2 /*return*/, (0, proto_signing_1.isOfflineDirectSigner)(this.signer) + ? this.signDirect(signerAddress, messages, fee, memo, signerData) + : this.signAmino(signerAddress, messages, fee, memo, signerData)]; + } + }); + }); + }; + SigningStargateClient.prototype.signAmino = function (signerAddress, messages, fee, memo, _a) { + var accountNumber = _a.accountNumber, sequence = _a.sequence, chainId = _a.chainId; + return __awaiter(this, void 0, void 0, function () { + var accountFromSigner, pubkey, signMode, msgs, signDoc, _b, signature, signed, signedTxBody, signedTxBodyEncodeObject, signedTxBodyBytes, signedGasLimit, signedSequence, signedAuthInfoBytes; + var _this = this; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + (0, utils_1.assert)(!(0, proto_signing_1.isOfflineDirectSigner)(this.signer)); + return [4 /*yield*/, this.signer.getAccounts()]; + case 1: + accountFromSigner = (_c.sent()).find(function (account) { return account.address === signerAddress; }); + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer"); + } + pubkey = (0, proto_signing_1.encodePubkey)((0, amino_1.encodeSecp256k1Pubkey)(accountFromSigner.pubkey)); + signMode = signing_1.SignMode.SIGN_MODE_LEGACY_AMINO_JSON; + msgs = messages.map(function (msg) { return _this.aminoTypes.toAmino(msg); }); + signDoc = (0, amino_1.makeSignDoc)(msgs, fee, chainId, memo, accountNumber, sequence); + return [4 /*yield*/, this.signer.signAmino(signerAddress, signDoc)]; + case 2: + _b = _c.sent(), signature = _b.signature, signed = _b.signed; + signedTxBody = { + messages: signed.msgs.map(function (msg) { return _this.aminoTypes.fromAmino(msg); }), + memo: signed.memo + }; + signedTxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: signedTxBody + }; + signedTxBodyBytes = this.registry.encode(signedTxBodyEncodeObject); + signedGasLimit = math_1.Int53.fromString(signed.fee.gas).toNumber(); + signedSequence = math_1.Int53.fromString(signed.sequence).toNumber(); + signedAuthInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: signedSequence }], signed.fee.amount, signedGasLimit, signMode); + return [2 /*return*/, tx_5.TxRaw.fromPartial({ + bodyBytes: signedTxBodyBytes, + authInfoBytes: signedAuthInfoBytes, + signatures: [(0, encoding_1.fromBase64)(signature.signature)] + })]; + } + }); + }); + }; + SigningStargateClient.prototype.signDirect = function (signerAddress, messages, fee, memo, _a) { + var accountNumber = _a.accountNumber, sequence = _a.sequence, chainId = _a.chainId; + return __awaiter(this, void 0, void 0, function () { + var accountFromSigner, pubkey, txBodyEncodeObject, txBodyBytes, gasLimit, authInfoBytes, signDoc, _b, signature, signed; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + (0, utils_1.assert)((0, proto_signing_1.isOfflineDirectSigner)(this.signer)); + return [4 /*yield*/, this.signer.getAccounts()]; + case 1: + accountFromSigner = (_c.sent()).find(function (account) { return account.address === signerAddress; }); + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer"); + } + pubkey = (0, proto_signing_1.encodePubkey)((0, amino_1.encodeSecp256k1Pubkey)(accountFromSigner.pubkey)); + txBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: messages, + memo: memo + } + }; + txBodyBytes = this.registry.encode(txBodyEncodeObject); + gasLimit = math_1.Int53.fromString(fee.gas).toNumber(); + authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: sequence }], fee.amount, gasLimit); + signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, accountNumber); + return [4 /*yield*/, this.signer.signDirect(signerAddress, signDoc)]; + case 2: + _b = _c.sent(), signature = _b.signature, signed = _b.signed; + return [2 /*return*/, tx_5.TxRaw.fromPartial({ + bodyBytes: signed.bodyBytes, + authInfoBytes: signed.authInfoBytes, + signatures: [(0, encoding_1.fromBase64)(signature.signature)] + })]; + } + }); + }); + }; + return SigningStargateClient; +}(stargateclient_1.StargateClient)); +exports.SigningStargateClient = SigningStargateClient; diff --git a/build/signingstargateclient.spec.js b/build/signingstargateclient.spec.js new file mode 100644 index 0000000..770c8f3 --- /dev/null +++ b/build/signingstargateclient.spec.js @@ -0,0 +1,964 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention,no-bitwise */ +var amino_1 = require("@cosmjs/amino"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var utils_1 = require("@cosmjs/utils"); +var tx_1 = require("cosmjs-types/cosmos/bank/v1beta1/tx"); +var coin_1 = require("cosmjs-types/cosmos/base/v1beta1/coin"); +var tx_2 = require("cosmjs-types/cosmos/staking/v1beta1/tx"); +var tx_3 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var long_1 = require("long"); +var minimal_1 = require("protobufjs/minimal"); +var aminotypes_1 = require("./aminotypes"); +var signingstargateclient_1 = require("./signingstargateclient"); +var stargateclient_1 = require("./stargateclient"); +var testutils_spec_1 = require("./testutils.spec"); +describe("SigningStargateClient", function () { + describe("constructor", function () { + it("can be constructed with custom registry", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, registry, options, client, openedClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + registry = new proto_signing_1.Registry(); + registry.register("/custom.MsgCustom", tx_1.MsgSend); + options = __assign(__assign({}, testutils_spec_1.defaultSigningClientOptions), { registry: registry }); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, options)]; + case 2: + client = _a.sent(); + openedClient = client; + expect(openedClient.registry.lookupType("/custom.MsgCustom")).toEqual(tx_1.MsgSend); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("simulate", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, memo, gasUsed; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = tx_2.MsgDelegate.fromPartial({ + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.simulate(testutils_spec_1.faucet.address0, [msgAny], memo)]; + case 3: + gasUsed = _a.sent(); + expect(gasUsed).toBeGreaterThanOrEqual(101000); + expect(gasUsed).toBeLessThanOrEqual(150000); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("sendTokens", function () { + it("works with direct signer", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, amount, beneficiaryAddress, memo, before, result, after; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + amount = (0, proto_signing_1.coins)(7890, "ucosm"); + beneficiaryAddress = (0, testutils_spec_1.makeRandomAddress)(); + memo = "for dinner"; + return [4 /*yield*/, client.getBalance(beneficiaryAddress, "ucosm")]; + case 3: + before = _a.sent(); + expect(before).toEqual({ + denom: "ucosm", + amount: "0" + }); + return [4 /*yield*/, client.sendTokens(testutils_spec_1.faucet.address0, beneficiaryAddress, amount, testutils_spec_1.defaultSendFee, memo)]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + expect(result.rawLog).toBeTruthy(); + return [4 /*yield*/, client.getBalance(beneficiaryAddress, "ucosm")]; + case 5: + after = _a.sent(); + expect(after).toEqual(amount[0]); + return [2 /*return*/]; + } + }); + }); }); + it("works with legacy Amino signer", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, amount, beneficiaryAddress, memo, before, result, after; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + amount = (0, proto_signing_1.coins)(7890, "ucosm"); + beneficiaryAddress = (0, testutils_spec_1.makeRandomAddress)(); + memo = "for dinner"; + return [4 /*yield*/, client.getBalance(beneficiaryAddress, "ucosm")]; + case 3: + before = _a.sent(); + expect(before).toEqual({ + denom: "ucosm", + amount: "0" + }); + return [4 /*yield*/, client.sendTokens(testutils_spec_1.faucet.address0, beneficiaryAddress, amount, testutils_spec_1.defaultSendFee, memo)]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + expect(result.rawLog).toBeTruthy(); + return [4 /*yield*/, client.getBalance(beneficiaryAddress, "ucosm")]; + case 5: + after = _a.sent(); + expect(after).toEqual(amount[0]); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("sendIbcTokens", function () { + it("works with direct signing", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, memo, fee, result, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + memo = "Cross-chain fun"; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "180000" + }; + return [4 /*yield*/, client.sendIbcTokens(testutils_spec_1.faucet.address0, testutils_spec_1.faucet.address1, (0, proto_signing_1.coin)(1234, "ucosm"), "fooPort", "fooChannel", { revisionHeight: long_1["default"].fromNumber(123), revisionNumber: long_1["default"].fromNumber(456) }, Math.floor(Date.now() / 1000) + 60, fee, memo)]; + case 3: + result = _a.sent(); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect((0, stargateclient_1.isDeliverTxFailure)(result)).toEqual(true); + return [4 /*yield*/, client.sendIbcTokens(testutils_spec_1.faucet.address0, testutils_spec_1.faucet.address1, (0, proto_signing_1.coin)(1234, "ucosm"), "fooPort", "fooChannel", undefined, Math.floor(Date.now() / 1000) + 60, fee, memo)]; + case 4: + result = _a.sent(); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect((0, stargateclient_1.isDeliverTxFailure)(result)).toEqual(true); + return [2 /*return*/]; + } + }); + }); }); + it("works with Amino signing", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, memo, fee, result, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp42)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + memo = "Cross-chain fun"; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "180000" + }; + return [4 /*yield*/, client.sendIbcTokens(testutils_spec_1.faucet.address0, testutils_spec_1.faucet.address1, (0, proto_signing_1.coin)(1234, "ucosm"), "fooPort", "fooChannel", { revisionHeight: long_1["default"].fromNumber(123), revisionNumber: long_1["default"].fromNumber(456) }, Math.floor(Date.now() / 1000) + 60, fee, memo)]; + case 3: + result = _a.sent(); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect((0, stargateclient_1.isDeliverTxFailure)(result)).toEqual(true); + return [4 /*yield*/, client.sendIbcTokens(testutils_spec_1.faucet.address0, testutils_spec_1.faucet.address1, (0, proto_signing_1.coin)(1234, "ucosm"), "fooPort", "fooChannel", undefined, Math.floor(Date.now() / 1000) + 60, fee, memo)]; + case 4: + result = _a.sent(); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect((0, stargateclient_1.isDeliverTxFailure)(result)).toEqual(true); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("signAndBroadcast", function () { + describe("direct mode", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, memo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = tx_2.MsgDelegate.fromPartial({ + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "180000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + expect(result.code).toEqual(0); + expect(result.gasWanted).toEqual(180000); + expect(result.gasUsed).toBeLessThanOrEqual(180000); + expect(result.gasUsed).toBeGreaterThan(100000); + return [2 /*return*/]; + } + }); + }); }); + it("returns DeliverTxFailure on DeliverTx failure", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = tx_1.MsgSend.fromPartial({ + fromAddress: testutils_spec_1.faucet.address0, + toAddress: (0, testutils_spec_1.makeRandomAddress)(), + amount: (0, proto_signing_1.coins)(Number.MAX_SAFE_INTEGER, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "99000" + }; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxFailure)(result); + expect(result.code).toBeGreaterThan(0); + expect(result.gasWanted).toEqual(99000); + expect(result.gasUsed).toBeLessThanOrEqual(99000); + expect(result.gasUsed).toBeGreaterThan(40000); + return [2 /*return*/]; + } + }); + }); }); + it("works with auto gas", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, __assign(__assign({}, testutils_spec_1.defaultSigningClientOptions), { gasPrice: testutils_spec_1.defaultGasPrice }))]; + case 2: + client = _a.sent(); + msg = tx_2.MsgDelegate.fromPartial({ + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], "auto")]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with a modifying signer", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, memo, result, searchResult, tx; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, testutils_spec_1.ModifyingDirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = tx_2.MsgDelegate.fromPartial({ + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "180000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [4 /*yield*/, (0, utils_1.sleep)(1000)]; + case 4: + _a.sent(); + return [4 /*yield*/, client.getTx(result.transactionHash)]; + case 5: + searchResult = _a.sent(); + (0, utils_1.assert)(searchResult, "Must find transaction"); + tx = (0, proto_signing_1.decodeTxRaw)(searchResult.tx); + // From ModifyingDirectSecp256k1HdWallet + expect(tx.body.memo).toEqual("This was modified"); + expect(__assign({}, tx.authInfo.fee.amount[0])).toEqual((0, proto_signing_1.coin)(3000, "ucosm")); + expect(tx.authInfo.fee.gasLimit.toNumber()).toEqual(333333); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("legacy Amino mode", function () { + it("works with bank MsgSend", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msgSend, msgAny, fee, memo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msgSend = { + fromAddress: testutils_spec_1.faucet.address0, + toAddress: (0, testutils_spec_1.makeRandomAddress)(), + amount: (0, proto_signing_1.coins)(1234, "ucosm") + }; + msgAny = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msgSend + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "200000" + }; + memo = "Use your tokens wisely"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with staking MsgDelegate", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msgDelegate, msgAny, fee, memo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msgDelegate = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msgDelegate + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ustake"), + gas: "200000" + }; + memo = "Use your tokens wisely"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with a custom registry and custom message", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, customRegistry, msgDelegateTypeUrl, baseCustomMsgDelegate, CustomMsgDelegate, customAminoTypes, options, client, msg, msgAny, fee, memo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + customRegistry = new proto_signing_1.Registry(); + msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate"; + baseCustomMsgDelegate = { + customDelegatorAddress: "", + customValidatorAddress: "" + }; + CustomMsgDelegate = { + // Adapted from autogenerated MsgDelegate implementation + encode: function (message, writer) { + var _a, _b; + if (writer === void 0) { writer = minimal_1["default"].Writer.create(); } + writer.uint32(10).string((_a = message.customDelegatorAddress) !== null && _a !== void 0 ? _a : ""); + writer.uint32(18).string((_b = message.customValidatorAddress) !== null && _b !== void 0 ? _b : ""); + if (message.customAmount !== undefined && message.customAmount !== undefined) { + coin_1.Coin.encode(message.customAmount, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + decode: function () { + throw new Error("decode method should not be required"); + }, + fromJSON: function () { + throw new Error("fromJSON method should not be required"); + }, + fromPartial: function (object) { + var message = __assign({}, baseCustomMsgDelegate); + if (object.customDelegatorAddress !== undefined && object.customDelegatorAddress !== null) { + message.customDelegatorAddress = object.customDelegatorAddress; + } + else { + message.customDelegatorAddress = ""; + } + if (object.customValidatorAddress !== undefined && object.customValidatorAddress !== null) { + message.customValidatorAddress = object.customValidatorAddress; + } + else { + message.customValidatorAddress = ""; + } + if (object.customAmount !== undefined && object.customAmount !== null) { + message.customAmount = coin_1.Coin.fromPartial(object.customAmount); + } + else { + message.customAmount = undefined; + } + return message; + }, + toJSON: function () { + throw new Error("toJSON method should not be required"); + } + }; + customRegistry.register(msgDelegateTypeUrl, CustomMsgDelegate); + customAminoTypes = new aminotypes_1.AminoTypes({ + additions: { + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: function (_a) { + var customDelegatorAddress = _a.customDelegatorAddress, customValidatorAddress = _a.customValidatorAddress, customAmount = _a.customAmount; + (0, utils_1.assert)(customDelegatorAddress, "missing customDelegatorAddress"); + (0, utils_1.assert)(customValidatorAddress, "missing validatorAddress"); + (0, utils_1.assert)(customAmount, "missing amount"); + return { + delegator_address: customDelegatorAddress, + validator_address: customValidatorAddress, + amount: { + amount: customAmount.amount, + denom: customAmount.denom + } + }; + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, validator_address = _a.validator_address, amount = _a.amount; + return ({ + customDelegatorAddress: delegator_address, + customValidatorAddress: validator_address, + customAmount: coin_1.Coin.fromPartial(amount) + }); + } + } + } + }); + options = __assign(__assign({}, testutils_spec_1.defaultSigningClientOptions), { registry: customRegistry, aminoTypes: customAminoTypes }); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, options)]; + case 2: + client = _a.sent(); + msg = { + customDelegatorAddress: testutils_spec_1.faucet.address0, + customValidatorAddress: testutils_spec_1.validator.validatorAddress, + customAmount: (0, proto_signing_1.coin)(1234, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "200000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with a modifying signer", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, memo, result, searchResult, tx; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, testutils_spec_1.ModifyingSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "200000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.signAndBroadcast(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [4 /*yield*/, (0, utils_1.sleep)(1000)]; + case 4: + _a.sent(); + return [4 /*yield*/, client.getTx(result.transactionHash)]; + case 5: + searchResult = _a.sent(); + (0, utils_1.assert)(searchResult, "Must find transaction"); + tx = (0, proto_signing_1.decodeTxRaw)(searchResult.tx); + // From ModifyingSecp256k1HdWallet + expect(tx.body.memo).toEqual("This was modified"); + expect(__assign({}, tx.authInfo.fee.amount[0])).toEqual((0, proto_signing_1.coin)(3000, "ucosm")); + expect(tx.authInfo.fee.gasLimit.toNumber()).toEqual(333333); + return [2 /*return*/]; + } + }); + }); }); + }); + }); + describe("sign", function () { + describe("direct mode", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, memo, signed, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = tx_2.MsgDelegate.fromPartial({ + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "180000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.sign(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + signed = _a.sent(); + return [4 /*yield*/, client.broadcastTx(Uint8Array.from(tx_3.TxRaw.encode(signed).finish()))]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with a modifying signer", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, memo, signed, body, authInfo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, testutils_spec_1.ModifyingDirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = tx_2.MsgDelegate.fromPartial({ + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }); + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "180000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.sign(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + signed = _a.sent(); + body = tx_3.TxBody.decode(signed.bodyBytes); + authInfo = tx_3.AuthInfo.decode(signed.authInfoBytes); + // From ModifyingDirectSecp256k1HdWallet + expect(body.memo).toEqual("This was modified"); + expect(__assign({}, authInfo.fee.amount[0])).toEqual((0, proto_signing_1.coin)(3000, "ucosm")); + expect(authInfo.fee.gasLimit.toNumber()).toEqual(333333); + return [4 /*yield*/, client.broadcastTx(Uint8Array.from(tx_3.TxRaw.encode(signed).finish()))]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("legacy Amino mode", function () { + it("works with bank MsgSend", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msgSend, msgAny, fee, memo, signed, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msgSend = { + fromAddress: testutils_spec_1.faucet.address0, + toAddress: (0, testutils_spec_1.makeRandomAddress)(), + amount: (0, proto_signing_1.coins)(1234, "ucosm") + }; + msgAny = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msgSend + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "200000" + }; + memo = "Use your tokens wisely"; + return [4 /*yield*/, client.sign(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + signed = _a.sent(); + return [4 /*yield*/, client.broadcastTx(Uint8Array.from(tx_3.TxRaw.encode(signed).finish()))]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with staking MsgDelegate", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msgDelegate, msgAny, fee, memo, signed, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msgDelegate = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msgDelegate + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ustake"), + gas: "200000" + }; + memo = "Use your tokens wisely"; + return [4 /*yield*/, client.sign(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + signed = _a.sent(); + return [4 /*yield*/, client.broadcastTx(Uint8Array.from(tx_3.TxRaw.encode(signed).finish()))]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with a custom registry and custom message", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, customRegistry, msgDelegateTypeUrl, baseCustomMsgDelegate, CustomMsgDelegate, customAminoTypes, options, client, msg, msgAny, fee, memo, signed, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, amino_1.Secp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + customRegistry = new proto_signing_1.Registry(); + msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate"; + baseCustomMsgDelegate = { + customDelegatorAddress: "", + customValidatorAddress: "" + }; + CustomMsgDelegate = { + // Adapted from autogenerated MsgDelegate implementation + encode: function (message, writer) { + var _a, _b; + if (writer === void 0) { writer = minimal_1["default"].Writer.create(); } + writer.uint32(10).string((_a = message.customDelegatorAddress) !== null && _a !== void 0 ? _a : ""); + writer.uint32(18).string((_b = message.customValidatorAddress) !== null && _b !== void 0 ? _b : ""); + if (message.customAmount !== undefined && message.customAmount !== undefined) { + coin_1.Coin.encode(message.customAmount, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + decode: function () { + throw new Error("decode method should not be required"); + }, + fromJSON: function () { + throw new Error("fromJSON method should not be required"); + }, + fromPartial: function (object) { + var message = __assign({}, baseCustomMsgDelegate); + if (object.customDelegatorAddress !== undefined && object.customDelegatorAddress !== null) { + message.customDelegatorAddress = object.customDelegatorAddress; + } + else { + message.customDelegatorAddress = ""; + } + if (object.customValidatorAddress !== undefined && object.customValidatorAddress !== null) { + message.customValidatorAddress = object.customValidatorAddress; + } + else { + message.customValidatorAddress = ""; + } + if (object.customAmount !== undefined && object.customAmount !== null) { + message.customAmount = coin_1.Coin.fromPartial(object.customAmount); + } + else { + message.customAmount = undefined; + } + return message; + }, + toJSON: function () { + throw new Error("toJSON method should not be required"); + } + }; + customRegistry.register(msgDelegateTypeUrl, CustomMsgDelegate); + customAminoTypes = new aminotypes_1.AminoTypes({ + additions: { + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: function (_a) { + var customDelegatorAddress = _a.customDelegatorAddress, customValidatorAddress = _a.customValidatorAddress, customAmount = _a.customAmount; + (0, utils_1.assert)(customDelegatorAddress, "missing customDelegatorAddress"); + (0, utils_1.assert)(customValidatorAddress, "missing validatorAddress"); + (0, utils_1.assert)(customAmount, "missing amount"); + return { + delegator_address: customDelegatorAddress, + validator_address: customValidatorAddress, + amount: { + amount: customAmount.amount, + denom: customAmount.denom + } + }; + }, + fromAmino: function (_a) { + var delegator_address = _a.delegator_address, validator_address = _a.validator_address, amount = _a.amount; + return ({ + customDelegatorAddress: delegator_address, + customValidatorAddress: validator_address, + customAmount: coin_1.Coin.fromPartial(amount) + }); + } + } + } + }); + options = __assign(__assign({}, testutils_spec_1.defaultSigningClientOptions), { registry: customRegistry, aminoTypes: customAminoTypes }); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, options)]; + case 2: + client = _a.sent(); + msg = { + customDelegatorAddress: testutils_spec_1.faucet.address0, + customValidatorAddress: testutils_spec_1.validator.validatorAddress, + customAmount: (0, proto_signing_1.coin)(1234, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "200000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.sign(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + signed = _a.sent(); + return [4 /*yield*/, client.broadcastTx(Uint8Array.from(tx_3.TxRaw.encode(signed).finish()))]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + it("works with a modifying signer", function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, msg, msgAny, fee, memo, signed, body, authInfo, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, testutils_spec_1.ModifyingSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.connectWithSigner(testutils_spec_1.simapp.tendermintUrl, wallet, testutils_spec_1.defaultSigningClientOptions)]; + case 2: + client = _a.sent(); + msg = { + delegatorAddress: testutils_spec_1.faucet.address0, + validatorAddress: testutils_spec_1.validator.validatorAddress, + amount: (0, proto_signing_1.coin)(1234, "ustake") + }; + msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg + }; + fee = { + amount: (0, proto_signing_1.coins)(2000, "ucosm"), + gas: "200000" + }; + memo = "Use your power wisely"; + return [4 /*yield*/, client.sign(testutils_spec_1.faucet.address0, [msgAny], fee, memo)]; + case 3: + signed = _a.sent(); + body = tx_3.TxBody.decode(signed.bodyBytes); + authInfo = tx_3.AuthInfo.decode(signed.authInfoBytes); + // From ModifyingSecp256k1HdWallet + expect(body.memo).toEqual("This was modified"); + expect(__assign({}, authInfo.fee.amount[0])).toEqual((0, proto_signing_1.coin)(3000, "ucosm")); + expect(authInfo.fee.gasLimit.toNumber()).toEqual(333333); + return [4 /*yield*/, client.broadcastTx(Uint8Array.from(tx_3.TxRaw.encode(signed).finish()))]; + case 4: + result = _a.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(result); + return [2 /*return*/]; + } + }); + }); }); + }); + }); +}); diff --git a/build/stargateclient.js b/build/stargateclient.js new file mode 100644 index 0000000..aec54e1 --- /dev/null +++ b/build/stargateclient.js @@ -0,0 +1,457 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +exports.__esModule = true; +exports.StargateClient = exports.assertIsDeliverTxFailure = exports.assertIsDeliverTxSuccess = exports.isDeliverTxSuccess = exports.isDeliverTxFailure = exports.TimeoutError = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var encoding_1 = require("@cosmjs/encoding"); +var math_1 = require("@cosmjs/math"); +var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc"); +var utils_1 = require("@cosmjs/utils"); +var accounts_1 = require("./accounts"); +var queries_1 = require("./queries"); +var search_1 = require("./search"); +var TimeoutError = /** @class */ (function (_super) { + __extends(TimeoutError, _super); + function TimeoutError(message, txId) { + var _this = _super.call(this, message) || this; + _this.txId = txId; + return _this; + } + return TimeoutError; +}(Error)); +exports.TimeoutError = TimeoutError; +function isDeliverTxFailure(result) { + return !!result.code; +} +exports.isDeliverTxFailure = isDeliverTxFailure; +function isDeliverTxSuccess(result) { + return !isDeliverTxFailure(result); +} +exports.isDeliverTxSuccess = isDeliverTxSuccess; +/** + * Ensures the given result is a success. Throws a detailed error message otherwise. + */ +function assertIsDeliverTxSuccess(result) { + if (isDeliverTxFailure(result)) { + throw new Error("Error when broadcasting tx " + result.transactionHash + " at height " + result.height + ". Code: " + result.code + "; Raw log: " + result.rawLog); + } +} +exports.assertIsDeliverTxSuccess = assertIsDeliverTxSuccess; +/** + * Ensures the given result is a failure. Throws a detailed error message otherwise. + */ +function assertIsDeliverTxFailure(result) { + if (isDeliverTxSuccess(result)) { + throw new Error("Transaction " + result.transactionHash + " did not fail at height " + result.height + ". Code: " + result.code + "; Raw log: " + result.rawLog); + } +} +exports.assertIsDeliverTxFailure = assertIsDeliverTxFailure; +var StargateClient = /** @class */ (function () { + function StargateClient(tmClient) { + if (tmClient) { + this.tmClient = tmClient; + this.queryClient = queries_1.QueryClient.withExtensions(tmClient, queries_1.setupAuthExtension, queries_1.setupBankExtension, queries_1.setupStakingExtension, queries_1.setupTxExtension); + } + } + StargateClient.connect = function (endpoint) { + return __awaiter(this, void 0, void 0, function () { + var tmClient; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, tendermint_rpc_1.Tendermint34Client.connect(endpoint)]; + case 1: + tmClient = _a.sent(); + return [2 /*return*/, new StargateClient(tmClient)]; + } + }); + }); + }; + StargateClient.prototype.getTmClient = function () { + return this.tmClient; + }; + StargateClient.prototype.forceGetTmClient = function () { + if (!this.tmClient) { + throw new Error("Tendermint client not available. You cannot use online functionality in offline mode."); + } + return this.tmClient; + }; + StargateClient.prototype.getQueryClient = function () { + return this.queryClient; + }; + StargateClient.prototype.forceGetQueryClient = function () { + if (!this.queryClient) { + throw new Error("Query client not available. You cannot use online functionality in offline mode."); + } + return this.queryClient; + }; + StargateClient.prototype.getChainId = function () { + return __awaiter(this, void 0, void 0, function () { + var response, chainId; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!!this.chainId) return [3 /*break*/, 2]; + return [4 /*yield*/, this.forceGetTmClient().status()]; + case 1: + response = _a.sent(); + chainId = response.nodeInfo.network; + if (!chainId) + throw new Error("Chain ID must not be empty"); + this.chainId = chainId; + _a.label = 2; + case 2: return [2 /*return*/, this.chainId]; + } + }); + }); + }; + StargateClient.prototype.getHeight = function () { + return __awaiter(this, void 0, void 0, function () { + var status; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.forceGetTmClient().status()]; + case 1: + status = _a.sent(); + return [2 /*return*/, status.syncInfo.latestBlockHeight]; + } + }); + }); + }; + StargateClient.prototype.getAccount = function (searchAddress) { + return __awaiter(this, void 0, void 0, function () { + var account, error_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, this.forceGetQueryClient().auth.account(searchAddress)]; + case 1: + account = _a.sent(); + return [2 /*return*/, account ? (0, accounts_1.accountFromAny)(account) : null]; + case 2: + error_1 = _a.sent(); + if (/rpc error: code = NotFound/i.test(error_1.toString())) { + return [2 /*return*/, null]; + } + throw error_1; + case 3: return [2 /*return*/]; + } + }); + }); + }; + StargateClient.prototype.getSequence = function (address) { + return __awaiter(this, void 0, void 0, function () { + var account; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.getAccount(address)]; + case 1: + account = _a.sent(); + if (!account) { + throw new Error("Account does not exist on chain. Send some tokens there before trying to query sequence."); + } + return [2 /*return*/, { + accountNumber: account.accountNumber, + sequence: account.sequence + }]; + } + }); + }); + }; + StargateClient.prototype.getBlock = function (height) { + return __awaiter(this, void 0, void 0, function () { + var response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.forceGetTmClient().block(height)]; + case 1: + response = _a.sent(); + return [2 /*return*/, { + id: (0, encoding_1.toHex)(response.blockId.hash).toUpperCase(), + header: { + version: { + block: new math_1.Uint53(response.block.header.version.block).toString(), + app: new math_1.Uint53(response.block.header.version.app).toString() + }, + height: response.block.header.height, + chainId: response.block.header.chainId, + time: (0, tendermint_rpc_1.toRfc3339WithNanoseconds)(response.block.header.time) + }, + txs: response.block.txs + }]; + } + }); + }); + }; + StargateClient.prototype.getBalance = function (address, searchDenom) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, this.forceGetQueryClient().bank.balance(address, searchDenom)]; + }); + }); + }; + /** + * Queries all balances for all denoms that belong to this address. + * + * Uses the grpc queries (which iterates over the store internally), and we cannot get + * proofs from such a method. + */ + StargateClient.prototype.getAllBalances = function (address) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, this.forceGetQueryClient().bank.allBalances(address)]; + }); + }); + }; + StargateClient.prototype.getDelegation = function (delegatorAddress, validatorAddress) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var delegatedAmount, e_1; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _b.trys.push([0, 2, , 3]); + return [4 /*yield*/, this.forceGetQueryClient().staking.delegation(delegatorAddress, validatorAddress)]; + case 1: + delegatedAmount = (_a = (_b.sent()).delegationResponse) === null || _a === void 0 ? void 0 : _a.balance; + return [3 /*break*/, 3]; + case 2: + e_1 = _b.sent(); + if (e_1.toString().includes("key not found")) { + // ignore, `delegatedAmount` remains undefined + } + else { + throw e_1; + } + return [3 /*break*/, 3]; + case 3: return [2 /*return*/, delegatedAmount || null]; + } + }); + }); + }; + StargateClient.prototype.getTx = function (id) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var results; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: return [4 /*yield*/, this.txsQuery("tx.hash='" + id + "'")]; + case 1: + results = _b.sent(); + return [2 /*return*/, (_a = results[0]) !== null && _a !== void 0 ? _a : null]; + } + }); + }); + }; + StargateClient.prototype.searchTx = function (query, filter) { + if (filter === void 0) { filter = {}; } + return __awaiter(this, void 0, void 0, function () { + function withFilters(originalQuery) { + return originalQuery + " AND tx.height>=" + minHeight + " AND tx.height<=" + maxHeight; + } + var minHeight, maxHeight, txs, _a, sentQuery, receivedQuery, _b, sent, received, sentHashes_1, rawQuery, filtered; + var _this = this; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + minHeight = filter.minHeight || 0; + maxHeight = filter.maxHeight || Number.MAX_SAFE_INTEGER; + if (maxHeight < minHeight) + return [2 /*return*/, []]; // optional optimization + if (!(0, search_1.isSearchByHeightQuery)(query)) return [3 /*break*/, 4]; + if (!(query.height >= minHeight && query.height <= maxHeight)) return [3 /*break*/, 2]; + return [4 /*yield*/, this.txsQuery("tx.height=" + query.height)]; + case 1: + _a = _c.sent(); + return [3 /*break*/, 3]; + case 2: + _a = []; + _c.label = 3; + case 3: + txs = _a; + return [3 /*break*/, 9]; + case 4: + if (!(0, search_1.isSearchBySentFromOrToQuery)(query)) return [3 /*break*/, 6]; + sentQuery = withFilters("message.module='bank' AND transfer.sender='" + query.sentFromOrTo + "'"); + receivedQuery = withFilters("message.module='bank' AND transfer.recipient='" + query.sentFromOrTo + "'"); + return [4 /*yield*/, Promise.all([sentQuery, receivedQuery].map(function (rawQuery) { return _this.txsQuery(rawQuery); }))]; + case 5: + _b = _c.sent(), sent = _b[0], received = _b[1]; + sentHashes_1 = sent.map(function (t) { return t.hash; }); + txs = __spreadArray(__spreadArray([], sent, true), received.filter(function (t) { return !sentHashes_1.includes(t.hash); }), true); + return [3 /*break*/, 9]; + case 6: + if (!(0, search_1.isSearchByTagsQuery)(query)) return [3 /*break*/, 8]; + rawQuery = withFilters(query.tags.map(function (t) { return t.key + "='" + t.value + "'"; }).join(" AND ")); + return [4 /*yield*/, this.txsQuery(rawQuery)]; + case 7: + txs = _c.sent(); + return [3 /*break*/, 9]; + case 8: throw new Error("Unknown query type"); + case 9: + filtered = txs.filter(function (tx) { return tx.height >= minHeight && tx.height <= maxHeight; }); + return [2 /*return*/, filtered]; + } + }); + }); + }; + StargateClient.prototype.disconnect = function () { + if (this.tmClient) + this.tmClient.disconnect(); + }; + /** + * Broadcasts a signed transaction to the network and monitors its inclusion in a block. + * + * If broadcasting is rejected by the node for some reason (e.g. because of a CheckTx failure), + * an error is thrown. + * + * If the transaction is not included in a block before the provided timeout, this errors with a `TimeoutError`. + * + * If the transaction is included in a block, a `DeliverTxResponse` is returned. The caller then + * usually needs to check for execution success or failure. + */ + StargateClient.prototype.broadcastTx = function (tx, timeoutMs, pollIntervalMs) { + if (timeoutMs === void 0) { timeoutMs = 60000; } + if (pollIntervalMs === void 0) { pollIntervalMs = 3000; } + return __awaiter(this, void 0, void 0, function () { + var timedOut, txPollTimeout, pollForTx, broadcasted, transactionId; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + timedOut = false; + txPollTimeout = setTimeout(function () { + timedOut = true; + }, timeoutMs); + pollForTx = function (txId) { return __awaiter(_this, void 0, void 0, function () { + var result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (timedOut) { + throw new TimeoutError("Transaction with ID " + txId + " was submitted but was not yet found on the chain. You might want to check later.", txId); + } + return [4 /*yield*/, (0, utils_1.sleep)(pollIntervalMs)]; + case 1: + _a.sent(); + return [4 /*yield*/, this.getTx(txId)]; + case 2: + result = _a.sent(); + return [2 /*return*/, result + ? { + code: result.code, + height: result.height, + rawLog: result.rawLog, + transactionHash: txId, + gasUsed: result.gasUsed, + gasWanted: result.gasWanted + } + : pollForTx(txId)]; + } + }); + }); }; + return [4 /*yield*/, this.forceGetTmClient().broadcastTxSync({ tx: tx })]; + case 1: + broadcasted = _a.sent(); + if (broadcasted.code) { + throw new Error("Broadcasting transaction failed with code " + broadcasted.code + " (codespace: " + broadcasted.codeSpace + "). Log: " + broadcasted.log); + } + transactionId = (0, encoding_1.toHex)(broadcasted.hash).toUpperCase(); + return [2 /*return*/, new Promise(function (resolve, reject) { + return pollForTx(transactionId).then(function (value) { + clearTimeout(txPollTimeout); + resolve(value); + }, function (error) { + clearTimeout(txPollTimeout); + reject(error); + }); + })]; + } + }); + }); + }; + StargateClient.prototype.txsQuery = function (query) { + return __awaiter(this, void 0, void 0, function () { + var results; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.forceGetTmClient().txSearchAll({ query: query })]; + case 1: + results = _a.sent(); + return [2 /*return*/, results.txs.map(function (tx) { + return { + height: tx.height, + hash: (0, encoding_1.toHex)(tx.hash).toUpperCase(), + code: tx.result.code, + rawLog: tx.result.log || "", + tx: tx.tx, + gasUsed: tx.result.gasUsed, + gasWanted: tx.result.gasWanted + }; + })]; + } + }); + }); + }; + return StargateClient; +}()); +exports.StargateClient = StargateClient; diff --git a/build/stargateclient.searchtx.spec.js b/build/stargateclient.searchtx.spec.js new file mode 100644 index 0000000..52d840e --- /dev/null +++ b/build/stargateclient.searchtx.spec.js @@ -0,0 +1,449 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var encoding_1 = require("@cosmjs/encoding"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var utils_1 = require("@cosmjs/utils"); +var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var encodeobjects_1 = require("./encodeobjects"); +var stargateclient_1 = require("./stargateclient"); +var testutils_spec_1 = require("./testutils.spec"); +function sendTokens(client, registry, wallet, recipient, amount, memo) { + return __awaiter(this, void 0, void 0, function () { + var _a, walletAddress, pubkeyBytes, pubkey, txBodyFields, txBodyBytes, _b, accountNumber, sequence, feeAmount, gasLimit, authInfoBytes, chainId, signDoc, signature, txRaw, txRawBytes, broadcastResponse; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: return [4 /*yield*/, wallet.getAccounts()]; + case 1: + _a = (_c.sent())[0], walletAddress = _a.address, pubkeyBytes = _a.pubkey; + pubkey = (0, proto_signing_1.encodePubkey)({ + type: "tendermint/PubKeySecp256k1", + value: (0, encoding_1.toBase64)(pubkeyBytes) + }); + txBodyFields = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: walletAddress, + toAddress: recipient, + amount: amount + } + }, + ], + memo: memo + } + }; + txBodyBytes = registry.encode(txBodyFields); + return [4 /*yield*/, client.getSequence(walletAddress)]; + case 2: + _b = (_c.sent()), accountNumber = _b.accountNumber, sequence = _b.sequence; + feeAmount = [ + { + amount: "2000", + denom: "ucosm" + }, + ]; + gasLimit = 200000; + authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: sequence }], feeAmount, gasLimit); + return [4 /*yield*/, client.getChainId()]; + case 3: + chainId = _c.sent(); + signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, accountNumber); + return [4 /*yield*/, wallet.signDirect(walletAddress, signDoc)]; + case 4: + signature = (_c.sent()).signature; + txRaw = tx_1.TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes, + signatures: [(0, encoding_1.fromBase64)(signature.signature)] + }); + txRawBytes = Uint8Array.from(tx_1.TxRaw.encode(txRaw).finish()); + return [4 /*yield*/, client.broadcastTx(txRawBytes, testutils_spec_1.defaultSigningClientOptions.broadcastTimeoutMs, testutils_spec_1.defaultSigningClientOptions.broadcastPollIntervalMs)]; + case 5: + broadcastResponse = _c.sent(); + return [2 /*return*/, { + broadcastResponse: broadcastResponse, + tx: txRawBytes + }]; + } + }); + }); +} +describe("StargateClient.getTx and .searchTx", function () { + var registry = new proto_signing_1.Registry(); + var sendUnsuccessful; + var sendSuccessful; + beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () { + var wallet, client, unsuccessfulRecipient, successfulRecipient, unsuccessfulResult, successfulResult; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!(0, testutils_spec_1.simappEnabled)()) return [3 /*break*/, 6]; + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 1: + wallet = _a.sent(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 2: + client = _a.sent(); + unsuccessfulRecipient = (0, testutils_spec_1.makeRandomAddress)(); + successfulRecipient = (0, testutils_spec_1.makeRandomAddress)(); + return [4 /*yield*/, sendTokens(client, registry, wallet, unsuccessfulRecipient, (0, proto_signing_1.coins)(123456700000000, "ucosm"), "Sending more than I can afford")]; + case 3: + unsuccessfulResult = _a.sent(); + if ((0, stargateclient_1.isDeliverTxFailure)(unsuccessfulResult.broadcastResponse)) { + sendUnsuccessful = { + sender: testutils_spec_1.faucet.address0, + recipient: unsuccessfulRecipient, + hash: unsuccessfulResult.broadcastResponse.transactionHash, + height: unsuccessfulResult.broadcastResponse.height, + tx: unsuccessfulResult.tx + }; + } + return [4 /*yield*/, sendTokens(client, registry, wallet, successfulRecipient, (0, proto_signing_1.coins)(1234567, "ucosm"), "Something I can afford")]; + case 4: + successfulResult = _a.sent(); + if ((0, stargateclient_1.isDeliverTxSuccess)(successfulResult.broadcastResponse)) { + sendSuccessful = { + sender: testutils_spec_1.faucet.address0, + recipient: successfulRecipient, + hash: successfulResult.broadcastResponse.transactionHash, + height: successfulResult.broadcastResponse.height, + tx: successfulResult.tx + }; + } + return [4 /*yield*/, (0, utils_1.sleep)(75)]; + case 5: + _a.sent(); // wait until transactions are indexed + _a.label = 6; + case 6: return [2 /*return*/]; + } + }); + }); }); + describe("getTx", function () { + it("can get successful tx by ID", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getTx(sendSuccessful.hash)]; + case 2: + result = _a.sent(); + expect(result).toEqual(jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + code: 0, + tx: sendSuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + it("can get unsuccessful tx by ID", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendUnsuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getTx(sendUnsuccessful.hash)]; + case 2: + result = _a.sent(); + expect(result).toEqual(jasmine.objectContaining({ + height: sendUnsuccessful.height, + hash: sendUnsuccessful.hash, + code: 5, + tx: sendUnsuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + it("can get by ID (non existent)", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, nonExistentId, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + nonExistentId = "0000000000000000000000000000000000000000000000000000000000000000"; + return [4 /*yield*/, client.getTx(nonExistentId)]; + case 2: + result = _a.sent(); + expect(result).toBeNull(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("with SearchByHeightQuery", function () { + it("can search successful tx by height", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.searchTx({ height: sendSuccessful.height })]; + case 2: + result = _a.sent(); + expect(result.length).toBeGreaterThanOrEqual(1); + expect(result).toContain(jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + code: 0, + tx: sendSuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + it("can search unsuccessful tx by height", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendUnsuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.searchTx({ height: sendUnsuccessful.height })]; + case 2: + result = _a.sent(); + expect(result.length).toBeGreaterThanOrEqual(1); + expect(result).toContain(jasmine.objectContaining({ + height: sendUnsuccessful.height, + hash: sendUnsuccessful.hash, + code: 5, + tx: sendUnsuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("with SearchBySentFromOrToQuery", function () { + it("can search by sender", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, results, _i, results_1, result, tx, filteredMsgs; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.searchTx({ sentFromOrTo: sendSuccessful.sender })]; + case 2: + results = _a.sent(); + expect(results.length).toBeGreaterThanOrEqual(1); + // Check basic structure of all results + for (_i = 0, results_1 = results; _i < results_1.length; _i++) { + result = results_1[_i]; + tx = (0, proto_signing_1.decodeTxRaw)(result.tx); + filteredMsgs = tx.body.messages.filter(function (msg) { + if (!(0, encodeobjects_1.isMsgSendEncodeObject)(msg)) + return false; + var decoded = registry.decode(msg); + return decoded.fromAddress === (sendSuccessful === null || sendSuccessful === void 0 ? void 0 : sendSuccessful.sender); + }); + expect(filteredMsgs.length).toBeGreaterThanOrEqual(1); + } + // Check details of most recent result + expect(results[results.length - 1]).toEqual(jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + tx: sendSuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + it("can search by recipient", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, results, _i, results_2, result, tx, filteredMsgs; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.searchTx({ sentFromOrTo: sendSuccessful.recipient })]; + case 2: + results = _a.sent(); + expect(results.length).toBeGreaterThanOrEqual(1); + // Check basic structure of all results + for (_i = 0, results_2 = results; _i < results_2.length; _i++) { + result = results_2[_i]; + tx = (0, proto_signing_1.decodeTxRaw)(result.tx); + filteredMsgs = tx.body.messages.filter(function (msg) { + if (!(0, encodeobjects_1.isMsgSendEncodeObject)(msg)) + return false; + var decoded = registry.decode(msg); + return decoded.toAddress === (sendSuccessful === null || sendSuccessful === void 0 ? void 0 : sendSuccessful.recipient); + }); + expect(filteredMsgs.length).toBeGreaterThanOrEqual(1); + } + // Check details of most recent result + expect(results[results.length - 1]).toEqual(jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + tx: sendSuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + it("can search by recipient and filter by minHeight", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, query, result, result, result, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + query = { sentFromOrTo: sendSuccessful.recipient }; + return [4 /*yield*/, client.searchTx(query, { minHeight: 0 })]; + case 2: + result = _a.sent(); + expect(result.length).toEqual(1); + return [4 /*yield*/, client.searchTx(query, { minHeight: sendSuccessful.height - 1 })]; + case 3: + result = _a.sent(); + expect(result.length).toEqual(1); + return [4 /*yield*/, client.searchTx(query, { minHeight: sendSuccessful.height })]; + case 4: + result = _a.sent(); + expect(result.length).toEqual(1); + return [4 /*yield*/, client.searchTx(query, { minHeight: sendSuccessful.height + 1 })]; + case 5: + result = _a.sent(); + expect(result.length).toEqual(0); + return [2 /*return*/]; + } + }); + }); }); + it("can search by recipient and filter by maxHeight", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, query, result, result, result, result; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + query = { sentFromOrTo: sendSuccessful.recipient }; + return [4 /*yield*/, client.searchTx(query, { maxHeight: 9999999999999 })]; + case 2: + result = _a.sent(); + expect(result.length).toEqual(1); + return [4 /*yield*/, client.searchTx(query, { maxHeight: sendSuccessful.height + 1 })]; + case 3: + result = _a.sent(); + expect(result.length).toEqual(1); + return [4 /*yield*/, client.searchTx(query, { maxHeight: sendSuccessful.height })]; + case 4: + result = _a.sent(); + expect(result.length).toEqual(1); + return [4 /*yield*/, client.searchTx(query, { maxHeight: sendSuccessful.height - 1 })]; + case 5: + result = _a.sent(); + expect(result.length).toEqual(0); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("with SearchByTagsQuery", function () { + it("can search by transfer.recipient", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, results, _i, results_3, result, tx, msg, decoded; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + (0, utils_1.assert)(sendSuccessful, "value must be set in beforeAll()"); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.searchTx({ + tags: [{ key: "transfer.recipient", value: sendSuccessful.recipient }] + })]; + case 2: + results = _a.sent(); + expect(results.length).toBeGreaterThanOrEqual(1); + // Check basic structure of all results + for (_i = 0, results_3 = results; _i < results_3.length; _i++) { + result = results_3[_i]; + tx = (0, proto_signing_1.decodeTxRaw)(result.tx); + msg = (0, testutils_spec_1.fromOneElementArray)(tx.body.messages); + expect(msg.typeUrl).toEqual("/cosmos.bank.v1beta1.MsgSend"); + decoded = registry.decode(msg); + expect(decoded.toAddress).toEqual(sendSuccessful.recipient); + } + // Check details of most recent result + expect(results[results.length - 1]).toEqual(jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + tx: sendSuccessful.tx + })); + return [2 /*return*/]; + } + }); + }); }); + }); +}); diff --git a/build/stargateclient.spec.js b/build/stargateclient.spec.js new file mode 100644 index 0000000..a04cb6b --- /dev/null +++ b/build/stargateclient.spec.js @@ -0,0 +1,700 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/naming-convention */ +var encoding_1 = require("@cosmjs/encoding"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var utils_1 = require("@cosmjs/utils"); +var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var readonly_date_1 = require("readonly-date"); +var stargateclient_1 = require("./stargateclient"); +var testutils_spec_1 = require("./testutils.spec"); +var resultFailure = { + code: 5, + height: 219901, + rawLog: "failed to execute message; message index: 0: 1855527000ufct is smaller than 20000000000000000000000ufct: insufficient funds", + transactionHash: "FDC4FB701AABD465935F7D04AE490D1EF5F2BD4B227601C4E98B57EB077D9B7D", + gasUsed: 54396, + gasWanted: 200000 +}; +var resultSuccess = { + code: 0, + height: 219894, + rawLog: '[{"events":[{"type":"message","attributes":[{"key":"action","value":"send"},{"key":"sender","value":"firma1trqyle9m2nvyafc2n25frkpwed2504y6avgfzr"},{"key":"module","value":"bank"}]},{"type":"transfer","attributes":[{"key":"recipient","value":"firma12er8ls2sf5zess3jgjxz59xat9xtf8hz0hk6n4"},{"key":"sender","value":"firma1trqyle9m2nvyafc2n25frkpwed2504y6avgfzr"},{"key":"amount","value":"2000000ufct"}]}]}]', + transactionHash: "C0B416CA868C55C2B8C1BBB8F3CFA233854F13A5CB15D3E9599F50CAF7B3D161", + gasUsed: 61556, + gasWanted: 200000 +}; +describe("isDeliverTxFailure", function () { + it("works", function () { + expect((0, stargateclient_1.isDeliverTxFailure)(resultFailure)).toEqual(true); + expect((0, stargateclient_1.isDeliverTxFailure)(resultSuccess)).toEqual(false); + }); +}); +describe("isDeliverTxSuccess", function () { + it("works", function () { + expect((0, stargateclient_1.isDeliverTxSuccess)(resultFailure)).toEqual(false); + expect((0, stargateclient_1.isDeliverTxSuccess)(resultSuccess)).toEqual(true); + }); +}); +describe("StargateClient", function () { + describe("connect", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var client; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + expect(client).toBeTruthy(); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getChainId", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _b.sent(); + _a = expect; + return [4 /*yield*/, client.getChainId()]; + case 2: + _a.apply(void 0, [_b.sent()]).toEqual(testutils_spec_1.simapp.chainId); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("caches chain ID", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, openedClient, getCodeSpy, _a, _b; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _c.sent(); + openedClient = client; + getCodeSpy = spyOn(openedClient.tmClient, "status").and.callThrough(); + _a = expect; + return [4 /*yield*/, client.getChainId()]; + case 2: + _a.apply(void 0, [_c.sent()]).toEqual(testutils_spec_1.simapp.chainId); // from network + _b = expect; + return [4 /*yield*/, client.getChainId()]; + case 3: + _b.apply(void 0, [_c.sent()]).toEqual(testutils_spec_1.simapp.chainId); // from cache + expect(getCodeSpy).toHaveBeenCalledTimes(1); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getHeight", function () { + it("works", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, height1, height2; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getHeight()]; + case 2: + height1 = _a.sent(); + expect(height1).toBeGreaterThan(0); + return [4 /*yield*/, (0, utils_1.sleep)(testutils_spec_1.simapp.blockTime * 1.4)]; + case 3: + _a.sent(); // tolerate chain being 40% slower than expected + return [4 /*yield*/, client.getHeight()]; + case 4: + height2 = _a.sent(); + expect(height2).toBeGreaterThanOrEqual(height1 + 1); + expect(height2).toBeLessThanOrEqual(height1 + 2); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getAccount", function () { + it("works for unused account", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, account; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getAccount(testutils_spec_1.unused.address)]; + case 2: + account = _a.sent(); + (0, utils_1.assert)(account); + expect(account).toEqual({ + address: testutils_spec_1.unused.address, + pubkey: null, + accountNumber: testutils_spec_1.unused.accountNumber, + sequence: testutils_spec_1.unused.sequence + }); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works for account with pubkey and non-zero sequence", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, account; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getAccount(testutils_spec_1.validator.delegatorAddress)]; + case 2: + account = _a.sent(); + (0, utils_1.assert)(account); + expect(account).toEqual({ + address: testutils_spec_1.validator.delegatorAddress, + pubkey: testutils_spec_1.validator.pubkey, + accountNumber: testutils_spec_1.validator.accountNumber, + sequence: testutils_spec_1.validator.sequence + }); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns null for non-existent address", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, account; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getAccount(testutils_spec_1.nonExistentAddress)]; + case 2: + account = _a.sent(); + expect(account).toBeNull(); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getSequence", function () { + it("works for unused account", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, account; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getSequence(testutils_spec_1.unused.address)]; + case 2: + account = _a.sent(); + (0, utils_1.assert)(account); + expect(account).toEqual({ + accountNumber: testutils_spec_1.unused.accountNumber, + sequence: testutils_spec_1.unused.sequence + }); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("rejects for non-existent address", function () { return __awaiter(void 0, void 0, void 0, function () { + var client; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, expectAsync(client.getSequence(testutils_spec_1.nonExistentAddress)).toBeRejectedWithError(/account does not exist on chain/i)]; + case 2: + _a.sent(); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getBlock", function () { + it("works for latest block", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, response, _a, _b, _c, _d, _e, _f; + var _g, _h; + return __generator(this, function (_j) { + switch (_j.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _j.sent(); + return [4 /*yield*/, client.getBlock()]; + case 2: + response = _j.sent(); + _b = (_a = expect(response)).toEqual; + _d = (_c = jasmine).objectContaining; + _g = { + id: jasmine.stringMatching(testutils_spec_1.tendermintIdMatcher) + }; + _f = (_e = jasmine).objectContaining; + _h = {}; + return [4 /*yield*/, client.getChainId()]; + case 3: + _b.apply(_a, [_d.apply(_c, [(_g.header = _f.apply(_e, [(_h.chainId = _j.sent(), + _h)]), + _g.txs = jasmine.arrayContaining([]), + _g)])]); + expect(response.header.height).toBeGreaterThanOrEqual(1); + expect(new readonly_date_1.ReadonlyDate(response.header.time).getTime()).toBeLessThan(readonly_date_1.ReadonlyDate.now()); + expect(new readonly_date_1.ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual(readonly_date_1.ReadonlyDate.now() - 5000); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("works for block by height", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, height, response, _a, _b, _c, _d, _e, _f; + var _g, _h; + return __generator(this, function (_j) { + switch (_j.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _j.sent(); + return [4 /*yield*/, client.getBlock()]; + case 2: + height = (_j.sent()).header.height; + return [4 /*yield*/, client.getBlock(height - 1)]; + case 3: + response = _j.sent(); + _b = (_a = expect(response)).toEqual; + _d = (_c = jasmine).objectContaining; + _g = { + id: jasmine.stringMatching(testutils_spec_1.tendermintIdMatcher) + }; + _f = (_e = jasmine).objectContaining; + _h = { + height: height - 1 + }; + return [4 /*yield*/, client.getChainId()]; + case 4: + _b.apply(_a, [_d.apply(_c, [(_g.header = _f.apply(_e, [(_h.chainId = _j.sent(), + _h)]), + _g.txs = jasmine.arrayContaining([]), + _g)])]); + expect(new readonly_date_1.ReadonlyDate(response.header.time).getTime()).toBeLessThan(readonly_date_1.ReadonlyDate.now()); + expect(new readonly_date_1.ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual(readonly_date_1.ReadonlyDate.now() - 5000); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getBalance", function () { + it("works for different existing balances", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, response1, response2; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getBalance(testutils_spec_1.unused.address, testutils_spec_1.simapp.denomFee)]; + case 2: + response1 = _a.sent(); + expect(response1).toEqual({ + amount: testutils_spec_1.unused.balanceFee, + denom: testutils_spec_1.simapp.denomFee + }); + return [4 /*yield*/, client.getBalance(testutils_spec_1.unused.address, testutils_spec_1.simapp.denomStaking)]; + case 3: + response2 = _a.sent(); + expect(response2).toEqual({ + amount: testutils_spec_1.unused.balanceStaking, + denom: testutils_spec_1.simapp.denomStaking + }); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns 0 for non-existent balance", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getBalance(testutils_spec_1.unused.address, "gintonic")]; + case 2: + response = _a.sent(); + expect(response).toEqual({ + denom: "gintonic", + amount: "0" + }); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns 0 for non-existent address", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, response; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getBalance(testutils_spec_1.nonExistentAddress, testutils_spec_1.simapp.denomFee)]; + case 2: + response = _a.sent(); + expect(response).toEqual({ + denom: testutils_spec_1.simapp.denomFee, + amount: "0" + }); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("getAllBalances", function () { + it("returns all balances for unused account", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, balances; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getAllBalances(testutils_spec_1.unused.address)]; + case 2: + balances = _a.sent(); + expect(balances).toEqual([ + { + amount: testutils_spec_1.unused.balanceFee, + denom: testutils_spec_1.simapp.denomFee + }, + { + amount: testutils_spec_1.unused.balanceStaking, + denom: testutils_spec_1.simapp.denomStaking + }, + ]); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("returns an empty list for non-existent account", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, balances; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _a.sent(); + return [4 /*yield*/, client.getAllBalances(testutils_spec_1.nonExistentAddress)]; + case 2: + balances = _a.sent(); + expect(balances).toEqual([]); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + }); + describe("broadcastTx", function () { + it("broadcasts a transaction", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, wallet, _a, address, pubkeyBytes, pubkey, registry, txBodyFields, txBodyBytes, _b, accountNumber, sequence, feeAmount, gasLimit, authInfoBytes, chainId, signDoc, signature, txRaw, txRawBytes, txResult, gasUsed, rawLog, transactionHash; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _c.sent(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 2: + wallet = _c.sent(); + return [4 /*yield*/, wallet.getAccounts()]; + case 3: + _a = (_c.sent())[0], address = _a.address, pubkeyBytes = _a.pubkey; + pubkey = (0, proto_signing_1.encodePubkey)({ + type: "tendermint/PubKeySecp256k1", + value: (0, encoding_1.toBase64)(pubkeyBytes) + }); + registry = new proto_signing_1.Registry(); + txBodyFields = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: address, + toAddress: (0, testutils_spec_1.makeRandomAddress)(), + amount: [ + { + denom: "ucosm", + amount: "1234567" + }, + ] + } + }, + ] + } + }; + txBodyBytes = registry.encode(txBodyFields); + return [4 /*yield*/, client.getSequence(address)]; + case 4: + _b = (_c.sent()), accountNumber = _b.accountNumber, sequence = _b.sequence; + feeAmount = (0, proto_signing_1.coins)(2000, "ucosm"); + gasLimit = 200000; + authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: sequence }], feeAmount, gasLimit); + return [4 /*yield*/, client.getChainId()]; + case 5: + chainId = _c.sent(); + signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, accountNumber); + return [4 /*yield*/, wallet.signDirect(address, signDoc)]; + case 6: + signature = (_c.sent()).signature; + txRaw = tx_1.TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes, + signatures: [(0, encoding_1.fromBase64)(signature.signature)] + }); + txRawBytes = Uint8Array.from(tx_1.TxRaw.encode(txRaw).finish()); + return [4 /*yield*/, client.broadcastTx(txRawBytes)]; + case 7: + txResult = _c.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(txResult); + gasUsed = txResult.gasUsed, rawLog = txResult.rawLog, transactionHash = txResult.transactionHash; + expect(gasUsed).toBeGreaterThan(0); + expect(rawLog).toMatch(/{"key":"amount","value":"1234567ucosm"}/); + expect(transactionHash).toMatch(/^[0-9A-F]{64}$/); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("errors immediately for a CheckTx failure", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, wallet, _a, address, pubkeyBytes, pubkey, registry, invalidRecipientAddress, txBodyFields, txBodyBytes, _b, accountNumber, sequence, feeAmount, gasLimit, authInfoBytes, chainId, signDoc, signature, txRaw, txRawBytes; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.simapp.tendermintUrl)]; + case 1: + client = _c.sent(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 2: + wallet = _c.sent(); + return [4 /*yield*/, wallet.getAccounts()]; + case 3: + _a = (_c.sent())[0], address = _a.address, pubkeyBytes = _a.pubkey; + pubkey = (0, proto_signing_1.encodePubkey)({ + type: "tendermint/PubKeySecp256k1", + value: (0, encoding_1.toBase64)(pubkeyBytes) + }); + registry = new proto_signing_1.Registry(); + invalidRecipientAddress = "tgrade1z363ulwcrxged4z5jswyt5dn5v3lzsemwz9ewj"; + txBodyFields = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: address, + toAddress: invalidRecipientAddress, + amount: [ + { + denom: "ucosm", + amount: "1234567" + }, + ] + } + }, + ] + } + }; + txBodyBytes = registry.encode(txBodyFields); + return [4 /*yield*/, client.getSequence(address)]; + case 4: + _b = (_c.sent()), accountNumber = _b.accountNumber, sequence = _b.sequence; + feeAmount = (0, proto_signing_1.coins)(2000, "ucosm"); + gasLimit = 200000; + authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: sequence }], feeAmount, gasLimit, sequence); + return [4 /*yield*/, client.getChainId()]; + case 5: + chainId = _c.sent(); + signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, accountNumber); + return [4 /*yield*/, wallet.signDirect(address, signDoc)]; + case 6: + signature = (_c.sent()).signature; + txRaw = tx_1.TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes, + signatures: [(0, encoding_1.fromBase64)(signature.signature)] + }); + txRawBytes = Uint8Array.from(tx_1.TxRaw.encode(txRaw).finish()); + return [4 /*yield*/, expectAsync(client.broadcastTx(txRawBytes)).toBeRejectedWithError(/invalid recipient address/i)]; + case 7: + _c.sent(); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }); + it("respects user timeouts rather than RPC timeouts", function () { return __awaiter(void 0, void 0, void 0, function () { + var client, wallet, _a, address, pubkeyBytes, pubkey, registry, txBodyFields, txBodyBytes, chainId, feeAmount, gasLimit, _b, accountNumber1, sequence1, authInfoBytes1, signDoc1, signature1, txRaw1, txRawBytes1, largeTimeoutMs, txResult, _c, accountNumber2, sequence2, authInfoBytes2, signDoc2, signature2, txRaw2, txRawBytes2, smallTimeoutMs; + return __generator(this, function (_d) { + switch (_d.label) { + case 0: + (0, testutils_spec_1.pendingWithoutSlowSimapp)(); + return [4 /*yield*/, stargateclient_1.StargateClient.connect(testutils_spec_1.slowSimapp.tendermintUrl)]; + case 1: + client = _d.sent(); + return [4 /*yield*/, proto_signing_1.DirectSecp256k1HdWallet.fromMnemonic(testutils_spec_1.faucet.mnemonic)]; + case 2: + wallet = _d.sent(); + return [4 /*yield*/, wallet.getAccounts()]; + case 3: + _a = (_d.sent())[0], address = _a.address, pubkeyBytes = _a.pubkey; + pubkey = (0, proto_signing_1.encodePubkey)({ + type: "tendermint/PubKeySecp256k1", + value: (0, encoding_1.toBase64)(pubkeyBytes) + }); + registry = new proto_signing_1.Registry(); + txBodyFields = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: address, + toAddress: (0, testutils_spec_1.makeRandomAddress)(), + amount: [ + { + denom: "ucosm", + amount: "1234567" + }, + ] + } + }, + ] + } + }; + txBodyBytes = registry.encode(txBodyFields); + return [4 /*yield*/, client.getChainId()]; + case 4: + chainId = _d.sent(); + feeAmount = (0, proto_signing_1.coins)(2000, "ucosm"); + gasLimit = 200000; + return [4 /*yield*/, client.getSequence(address)]; + case 5: + _b = (_d.sent()), accountNumber1 = _b.accountNumber, sequence1 = _b.sequence; + authInfoBytes1 = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: sequence1 }], feeAmount, gasLimit); + signDoc1 = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes1, chainId, accountNumber1); + return [4 /*yield*/, wallet.signDirect(address, signDoc1)]; + case 6: + signature1 = (_d.sent()).signature; + txRaw1 = tx_1.TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes1, + signatures: [(0, encoding_1.fromBase64)(signature1.signature)] + }); + txRawBytes1 = Uint8Array.from(tx_1.TxRaw.encode(txRaw1).finish()); + largeTimeoutMs = 30000; + return [4 /*yield*/, client.broadcastTx(txRawBytes1, largeTimeoutMs)]; + case 7: + txResult = _d.sent(); + (0, stargateclient_1.assertIsDeliverTxSuccess)(txResult); + return [4 /*yield*/, client.getSequence(address)]; + case 8: + _c = (_d.sent()), accountNumber2 = _c.accountNumber, sequence2 = _c.sequence; + authInfoBytes2 = (0, proto_signing_1.makeAuthInfoBytes)([{ pubkey: pubkey, sequence: sequence2 }], feeAmount, gasLimit); + signDoc2 = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes2, chainId, accountNumber2); + return [4 /*yield*/, wallet.signDirect(address, signDoc2)]; + case 9: + signature2 = (_d.sent()).signature; + txRaw2 = tx_1.TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes2, + signatures: [(0, encoding_1.fromBase64)(signature2.signature)] + }); + txRawBytes2 = Uint8Array.from(tx_1.TxRaw.encode(txRaw2).finish()); + smallTimeoutMs = 1000; + return [4 /*yield*/, expectAsync(client.broadcastTx(txRawBytes2, smallTimeoutMs)).toBeRejectedWithError(stargateclient_1.TimeoutError, /transaction with id .+ was submitted but was not yet found on the chain/i)]; + case 10: + _d.sent(); + client.disconnect(); + return [2 /*return*/]; + } + }); + }); }, 30000); + }); +}); diff --git a/build/testutils.spec.js b/build/testutils.spec.js new file mode 100644 index 0000000..eec6fb5 --- /dev/null +++ b/build/testutils.spec.js @@ -0,0 +1,308 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +exports.ModifyingDirectSecp256k1HdWallet = exports.ModifyingSecp256k1HdWallet = exports.tendermintIdMatcher = exports.nonNegativeIntegerMatcher = exports.nonExistentAddress = exports.validator = exports.unused = exports.faucet = exports.defaultSigningClientOptions = exports.slowSimapp = exports.simapp = exports.defaultSendFee = exports.defaultGasPrice = exports.fromOneElementArray = exports.makeRandomAddress = exports.makeRandomAddressBytes = exports.pendingWithoutSlowSimapp = exports.slowSimappEnabled = exports.pendingWithoutSimapp = exports.pendingWithoutSimapp42 = exports.simappEnabled = exports.simapp44Enabled = exports.simapp42Enabled = void 0; +/* eslint-disable @typescript-eslint/naming-convention */ +var amino_1 = require("@cosmjs/amino"); +var crypto_1 = require("@cosmjs/crypto"); +var encoding_1 = require("@cosmjs/encoding"); +var proto_signing_1 = require("@cosmjs/proto-signing"); +var signing_1 = require("cosmjs-types/cosmos/tx/signing/v1beta1/signing"); +var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx"); +var fee_1 = require("./fee"); +function simapp42Enabled() { + return !!process.env.SIMAPP42_ENABLED; +} +exports.simapp42Enabled = simapp42Enabled; +function simapp44Enabled() { + return !!process.env.SIMAPP44_ENABLED; +} +exports.simapp44Enabled = simapp44Enabled; +function simappEnabled() { + return simapp42Enabled() || simapp44Enabled(); +} +exports.simappEnabled = simappEnabled; +function pendingWithoutSimapp42() { + if (!simapp42Enabled()) { + return pending("Set SIMAPP44_ENABLED to enable Simapp based tests"); + } +} +exports.pendingWithoutSimapp42 = pendingWithoutSimapp42; +function pendingWithoutSimapp() { + if (!simappEnabled()) { + return pending("Set SIMAPP42_ENABLED or SIMAPP44_ENABLED to enable Simapp based tests"); + } +} +exports.pendingWithoutSimapp = pendingWithoutSimapp; +function slowSimappEnabled() { + return !!process.env.SLOW_SIMAPP42_ENABLED || !!process.env.SLOW_SIMAPP44_ENABLED; +} +exports.slowSimappEnabled = slowSimappEnabled; +function pendingWithoutSlowSimapp() { + if (!slowSimappEnabled()) { + return pending("Set SLOW_SIMAPP42_ENABLED or SLOW_SIMAPP44_ENABLED to enable slow Simapp based tests"); + } +} +exports.pendingWithoutSlowSimapp = pendingWithoutSlowSimapp; +function makeRandomAddressBytes() { + return crypto_1.Random.getBytes(20); +} +exports.makeRandomAddressBytes = makeRandomAddressBytes; +function makeRandomAddress() { + return encoding_1.Bech32.encode("cosmos", makeRandomAddressBytes()); +} +exports.makeRandomAddress = makeRandomAddress; +/** Returns first element. Throws if array has a different length than 1. */ +function fromOneElementArray(elements) { + if (elements.length !== 1) + throw new Error("Expected exactly one element but got " + elements.length); + return elements[0]; +} +exports.fromOneElementArray = fromOneElementArray; +exports.defaultGasPrice = fee_1.GasPrice.fromString("0.025ucosm"); +exports.defaultSendFee = (0, fee_1.calculateFee)(80000, exports.defaultGasPrice); +exports.simapp = { + tendermintUrl: "localhost:26658", + tendermintUrlWs: "ws://localhost:26658", + tendermintUrlHttp: "http://localhost:26658", + chainId: "simd-testing", + denomStaking: "ustake", + denomFee: "ucosm", + blockTime: 1000, + totalSupply: 21000000000, + govMinDeposit: (0, proto_signing_1.coins)(10000000, "ustake") +}; +exports.slowSimapp = { + tendermintUrl: "localhost:26660", + tendermintUrlWs: "ws://localhost:26660", + tendermintUrlHttp: "http://localhost:26660", + chainId: "simd-testing", + denomStaking: "ustake", + denomFee: "ucosm", + blockTime: 10000, + totalSupply: 21000000000 +}; +/** Setting to speed up testing */ +exports.defaultSigningClientOptions = { + broadcastPollIntervalMs: 300, + broadcastTimeoutMs: 8000 +}; +exports.faucet = { + mnemonic: "economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone", + pubkey0: { + type: "tendermint/PubKeySecp256k1", + value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" + }, + pubkey1: { + type: "tendermint/PubKeySecp256k1", + value: "AiDosfIbBi54XJ1QjCeApumcy/FjdtF+YhywPf3DKTx7" + }, + pubkey2: { + type: "tendermint/PubKeySecp256k1", + value: "AzQg33JZqH7vSsm09esZY5bZvmzYwE/SY78cA0iLxpD7" + }, + pubkey3: { + type: "tendermint/PubKeySecp256k1", + value: "A3gOAlB6aiRTCPvWMQg2+ZbGYNsLd8qlvV28m8p2UhY2" + }, + pubkey4: { + type: "tendermint/PubKeySecp256k1", + value: "Aum2063ub/ErUnIUB36sK55LktGUStgcbSiaAnL1wadu" + }, + address0: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + address1: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + address2: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + address3: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", + address4: "cosmos1hsm76p4ahyhl5yh3ve9ur49r5kemhp2r0dcjvx" +}; +/** Unused account */ +exports.unused = { + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "ArkCaFUJ/IH+vKBmNRCdUVl3mCAhbopk9jjW4Ko4OfRQ" + }, + address: "cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u", + accountNumber: 16, + sequence: 0, + balanceStaking: "2000000000", + balanceFee: "1000000000" +}; +exports.validator = { + /** + * From first gentx's auth_info.signer_infos in scripts/simapp42/template/.simapp/config/genesis.json + * + * ``` + * jq ".app_state.genutil.gen_txs[0].auth_info.signer_infos[0].public_key" scripts/simapp42/template/.simapp/config/genesis.json + * ``` + */ + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "AtDcuH4cX1eaxZrJ5shheLG3tXPAoV4awoIZmNQtQxmf" + }, + /** + * delegator_address from /cosmos.staking.v1beta1.MsgCreateValidator in scripts/simapp42/template/.simapp/config/genesis.json + * + * ``` + * jq ".app_state.genutil.gen_txs[0].body.messages[0].delegator_address" scripts/simapp42/template/.simapp/config/genesis.json + * ``` + */ + delegatorAddress: "cosmos1urk9gy7cfws0ak9x5nu7lx4un9n6gqkry79679", + /** + * validator_address from /cosmos.staking.v1beta1.MsgCreateValidator in scripts/simapp42/template/.simapp/config/genesis.json + * + * ``` + * jq ".app_state.genutil.gen_txs[0].body.messages[0].validator_address" scripts/simapp42/template/.simapp/config/genesis.json + * ``` + */ + validatorAddress: "cosmosvaloper1urk9gy7cfws0ak9x5nu7lx4un9n6gqkrp230jk", + accountNumber: 0, + sequence: 1 +}; +exports.nonExistentAddress = "cosmos1p79apjaufyphcmsn4g07cynqf0wyjuezqu84hd"; +exports.nonNegativeIntegerMatcher = /^[0-9]+$/; +exports.tendermintIdMatcher = /^[0-9A-F]{64}$/; +/** + * A class for testing clients using an Amino signer which modifies the transaction it receives before signing + */ +var ModifyingSecp256k1HdWallet = /** @class */ (function (_super) { + __extends(ModifyingSecp256k1HdWallet, _super); + function ModifyingSecp256k1HdWallet() { + return _super !== null && _super.apply(this, arguments) || this; + } + ModifyingSecp256k1HdWallet.fromMnemonic = function (mnemonic, options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + var mnemonicChecked, seed; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + mnemonicChecked = new crypto_1.EnglishMnemonic(mnemonic); + return [4 /*yield*/, crypto_1.Bip39.mnemonicToSeed(mnemonicChecked, options.bip39Password)]; + case 1: + seed = _a.sent(); + return [2 /*return*/, new ModifyingSecp256k1HdWallet(mnemonicChecked, __assign(__assign({}, options), { seed: seed }))]; + } + }); + }); + }; + ModifyingSecp256k1HdWallet.prototype.signAmino = function (signerAddress, signDoc) { + return __awaiter(this, void 0, void 0, function () { + var modifiedSignDoc; + return __generator(this, function (_a) { + modifiedSignDoc = __assign(__assign({}, signDoc), { fee: { + amount: (0, proto_signing_1.coins)(3000, "ucosm"), + gas: "333333" + }, memo: "This was modified" }); + return [2 /*return*/, _super.prototype.signAmino.call(this, signerAddress, modifiedSignDoc)]; + }); + }); + }; + return ModifyingSecp256k1HdWallet; +}(amino_1.Secp256k1HdWallet)); +exports.ModifyingSecp256k1HdWallet = ModifyingSecp256k1HdWallet; +/** + * A class for testing clients using a direct signer which modifies the transaction it receives before signing + */ +var ModifyingDirectSecp256k1HdWallet = /** @class */ (function (_super) { + __extends(ModifyingDirectSecp256k1HdWallet, _super); + function ModifyingDirectSecp256k1HdWallet() { + return _super !== null && _super.apply(this, arguments) || this; + } + ModifyingDirectSecp256k1HdWallet.fromMnemonic = function (mnemonic, options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + var mnemonicChecked, seed; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + mnemonicChecked = new crypto_1.EnglishMnemonic(mnemonic); + return [4 /*yield*/, crypto_1.Bip39.mnemonicToSeed(mnemonicChecked, options.bip39Password)]; + case 1: + seed = _a.sent(); + return [2 /*return*/, new ModifyingDirectSecp256k1HdWallet(mnemonicChecked, __assign(__assign({}, options), { seed: seed }))]; + } + }); + }); + }; + ModifyingDirectSecp256k1HdWallet.prototype.signDirect = function (address, signDoc) { + return __awaiter(this, void 0, void 0, function () { + var txBody, modifiedTxBody, authInfo, signers, modifiedFeeAmount, modifiedGasLimit, modifiedSignDoc; + return __generator(this, function (_a) { + txBody = tx_1.TxBody.decode(signDoc.bodyBytes); + modifiedTxBody = tx_1.TxBody.fromPartial(__assign(__assign({}, txBody), { memo: "This was modified" })); + authInfo = tx_1.AuthInfo.decode(signDoc.authInfoBytes); + signers = authInfo.signerInfos.map(function (signerInfo) { return ({ + pubkey: signerInfo.publicKey, + sequence: signerInfo.sequence.toNumber() + }); }); + modifiedFeeAmount = (0, proto_signing_1.coins)(3000, "ucosm"); + modifiedGasLimit = 333333; + modifiedSignDoc = __assign(__assign({}, signDoc), { bodyBytes: Uint8Array.from(tx_1.TxBody.encode(modifiedTxBody).finish()), authInfoBytes: (0, proto_signing_1.makeAuthInfoBytes)(signers, modifiedFeeAmount, modifiedGasLimit, signing_1.SignMode.SIGN_MODE_DIRECT) }); + return [2 /*return*/, _super.prototype.signDirect.call(this, address, modifiedSignDoc)]; + }); + }); + }; + return ModifyingDirectSecp256k1HdWallet; +}(proto_signing_1.DirectSecp256k1HdWallet)); +exports.ModifyingDirectSecp256k1HdWallet = ModifyingDirectSecp256k1HdWallet; diff --git a/jasmine-testrunner.js b/jasmine-testrunner.js new file mode 100644 index 0000000..afefb63 --- /dev/null +++ b/jasmine-testrunner.js @@ -0,0 +1,38 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +if (process.env.SES_ENABLED) { + require("ses/lockdown"); + // eslint-disable-next-line no-undef + lockdown(); +} + +require("source-map-support").install(); +const defaultSpecReporterConfig = require("../../jasmine-spec-reporter.config.json"); + +// setup Jasmine +const Jasmine = require("jasmine"); +const jasmine = new Jasmine(); +jasmine.loadConfig({ + spec_dir: "build", + spec_files: ["**/*.spec.js"], + helpers: [], + random: false, + seed: null, + stopSpecOnExpectationFailure: false, +}); +jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 15 * 1000; + +// setup reporter +const { SpecReporter } = require("jasmine-spec-reporter"); +const reporter = new SpecReporter({ + ...defaultSpecReporterConfig, + spec: { + ...defaultSpecReporterConfig.spec, + displaySuccessful: !process.argv.includes("--quiet"), + }, +}); + +// initialize and execute +jasmine.env.clearReporters(); +jasmine.addReporter(reporter); +void jasmine.execute(); diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..31c44e8 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,54 @@ +const chrome = require("karma-chrome-launcher"); +const firefox = require("karma-firefox-launcher"); +const jasmine = require("karma-jasmine"); +const kjhtml = require("karma-jasmine-html-reporter"); + +module.exports = function (config) { + config.set({ + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: ".", + // registers plugins but does not activate them + plugins: [jasmine, kjhtml, chrome, firefox], + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ["jasmine"], + + // list of files / patterns to load in the browser + files: ["dist/web/tests.js"], + + client: { + jasmine: { + random: false, + timeoutInterval: 15000, + }, + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["progress", "kjhtml"], + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ["Firefox"], + + browserNoActivityTimeout: 90000, + + // Keep brower open for debugging. This is overridden by yarn scripts + singleRun: false, + }); +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ad06f45 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11878 @@ +{ + "name": "@cosmjs/stargate", + "version": "0.27.0-rc2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@cosmjs/stargate", + "version": "0.27.0-rc2", + "license": "Apache-2.0", + "dependencies": { + "@confio/ics23": "^0.6.3", + "@cosmjs/amino": "v0.26.5", + "@cosmjs/encoding": "v0.26.5", + "@cosmjs/math": "v0.26.5", + "@cosmjs/proto-signing": "v0.26.5", + "@cosmjs/stream": "v0.26.5", + "@cosmjs/tendermint-rpc": "v0.26.5", + "@cosmjs/utils": "v0.26.5", + "cosmjs-types": "^0.4.0", + "long": "^4.0.0", + "protobufjs": "~6.10.2", + "xstream": "^11.14.0" + }, + "devDependencies": { + "@cosmjs/crypto": "v0.26.5", + "@istanbuljs/nyc-config-typescript": "^1.0.1", + "@types/eslint-plugin-prettier": "^3", + "@types/jasmine": "^3.8", + "@types/karma-firefox-launcher": "^2", + "@types/karma-jasmine": "^4", + "@types/karma-jasmine-html-reporter": "^1", + "@types/long": "^4.0.1", + "@types/node": "^15.0.1", + "@typescript-eslint/eslint-plugin": "^4.28", + "@typescript-eslint/parser": "^4.28", + "eslint": "^7.5", + "eslint-config-prettier": "^8.3.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-prettier": "^3.4.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "esm": "^3.2.25", + "glob": "^7.1.6", + "jasmine": "^3.8", + "jasmine-core": "^3.7.1", + "jasmine-spec-reporter": "^6", + "karma": "^6.1.1", + "karma-chrome-launcher": "^3.1.0", + "karma-firefox-launcher": "^2.1.0", + "karma-jasmine": "^4.0.1", + "karma-jasmine-html-reporter": "^1.5.4", + "nyc": "^15.1.0", + "prettier": "^2.4.1", + "readonly-date": "^1.0.0", + "ses": "^0.11.0", + "source-map-support": "^0.5.19", + "stream-browserify": "^3.0.0", + "ts-node": "^8", + "typedoc": "^0.22", + "typescript": "~4.4", + "webpack": "^5.32.0", + "webpack-cli": "^4.6.0" + } + }, + "node_modules/@agoric/babel-standalone": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@agoric/babel-standalone/-/babel-standalone-7.14.3.tgz", + "integrity": "sha512-Rdlxts19kvxHsqTjTrhGJv0yKgCyjCSVgXoLBZf9dZ7lyo/j+6xFQBiWjP03bXve3X74wUvA1QU55wVey8DEiQ==", + "dev": true + }, + "node_modules/@agoric/make-hardener": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@agoric/make-hardener/-/make-hardener-0.1.3.tgz", + "integrity": "sha512-rc9M2ErE/Zu822OLCnAltr957ZVTsBvVZ7KA2unqDpjo3q7PqZF2hWFB1xXD2Qkfwt5exQ3BjFbkj+NUaTg4gA==", + "deprecated": "The `ses` package provides `harden` after `lockdown`. Do not use `@agoric/make-hardener` directly.", + "dev": true + }, + "node_modules/@agoric/transform-module": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@agoric/transform-module/-/transform-module-0.4.1.tgz", + "integrity": "sha512-4TJJHXeXAWu1FCA7yXCAZmhBNoGTB/BEAe2pv+J2X8W/mJTr9b395OkDCSRMpzvmSshLfBx6wT0D7dqWIWEC1w==", + "dev": true + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz", + "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.7.tgz", + "integrity": "sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", + "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.7.tgz", + "integrity": "sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.7.tgz", + "integrity": "sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.7.tgz", + "integrity": "sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@confio/ics23": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.5.tgz", + "integrity": "sha512-1GdPMsaP/l8JSF4P4HWFLBhdcxHcJT8lS0nknBYNSZ1XrJOsJKUy6EkOwd9Pa1qJkXzY2gyNv7MdHR+AIwSTAg==", + "dependencies": { + "js-sha512": "^0.8.0", + "protobufjs": "^6.8.8", + "ripemd160": "^2.0.2", + "sha.js": "^2.4.11" + } + }, + "node_modules/@cosmjs/amino": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.26.5.tgz", + "integrity": "sha512-RFf9P1eb7O60JEWaZ5jbQA0wVbwU4SiBJINEjZkhkB1vUrAxCkfSHBZdJrVg8+IIRSWxPUUVr8PMuIyWlORV3A==", + "dependencies": { + "@cosmjs/crypto": "0.26.5", + "@cosmjs/encoding": "0.26.5", + "@cosmjs/math": "0.26.5", + "@cosmjs/utils": "0.26.5" + } + }, + "node_modules/@cosmjs/crypto": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.26.5.tgz", + "integrity": "sha512-ab7+qR/gdRi/DIdOLrjyimRdyD/2K/JdpRaFY1bl6Drr3ktVjDQrGsv53THvHONy33yCwD+YS+328ayQRv/pQA==", + "dependencies": { + "@cosmjs/encoding": "0.26.5", + "@cosmjs/math": "0.26.5", + "@cosmjs/utils": "0.26.5", + "bip39": "^3.0.2", + "bn.js": "^4.11.8", + "elliptic": "^6.5.3", + "js-sha3": "^0.8.0", + "libsodium-wrappers": "^0.7.6", + "ripemd160": "^2.0.2", + "sha.js": "^2.4.11" + } + }, + "node_modules/@cosmjs/encoding": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.26.5.tgz", + "integrity": "sha512-lkw2mLvDZJqVCOZCBqdMzoGUtC4CN7c4+WMCGKDej3TpC0khsv7KZ1eFcsnN6EuZwHyGH67uyyjrs5x0ah9rYg==", + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "node_modules/@cosmjs/json-rpc": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.26.5.tgz", + "integrity": "sha512-SFGm5MlY54v3I26hXThwVteh91U+/DKS+KGqFL5lPLHZ2EHxggASqhKMiTJBMJVUDWvnmv1ikjFndkWNhpTPNw==", + "dependencies": { + "@cosmjs/stream": "0.26.5", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/math": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.26.5.tgz", + "integrity": "sha512-1G7NgLJ35g4jUupvyu7Igtgu/fj2NmgpOofpNk1JqIwMXrm3Tx7lOWbxJq8Wrjj2EoH7FNytSO1dXNGeK15UJw==", + "dependencies": { + "bn.js": "^4.11.8" + } + }, + "node_modules/@cosmjs/proto-signing": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.26.5.tgz", + "integrity": "sha512-F94Uh+PX9nF5zGzUHMdEGgys+YCOudaWQehiHBfOjbHUIv0khufcRXs3l9/5dKzizz9ouQ5DHQAiWq/nYKZKqA==", + "dependencies": { + "@cosmjs/amino": "0.26.5", + "@cosmjs/crypto": "0.26.5", + "@cosmjs/math": "0.26.5", + "cosmjs-types": "^0.2.0", + "long": "^4.0.0", + "protobufjs": "~6.10.2" + } + }, + "node_modules/@cosmjs/proto-signing/node_modules/cosmjs-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.2.1.tgz", + "integrity": "sha512-EUG6TgdWkYHBzXjo5tZ82L+0QLijTu/rZGNIbJ/n07ST30GmptYkPmO+REX7qF4YUtli//Rfy0rrNzH9IMrMmw==", + "dependencies": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@cosmjs/proto-signing/node_modules/cosmjs-types/node_modules/protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/@cosmjs/socket": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.26.5.tgz", + "integrity": "sha512-kBpXw9wuNHkO1AGuKgDA4/DOA+jZ6Lt0GVJVJIJ6bfjGbsewsNVocktAiH+1dGb47xXg2oH7OwGJL+B/PB3qPQ==", + "dependencies": { + "@cosmjs/stream": "0.26.5", + "isomorphic-ws": "^4.0.1", + "ws": "^7", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/stream": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.26.5.tgz", + "integrity": "sha512-CIr/8bkRlLl36LAtbapsKxA7cMVhmPPWTihAcXgBXik1FM/0XCVNETPTQ64HX47eNQuP5AhWwaMoO553Sf9T2w==", + "dependencies": { + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/tendermint-rpc": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.26.5.tgz", + "integrity": "sha512-bBcFgpTHEP15m8n/bG3cx/LO110sScpEvYvurZDewfy7MW8WETF6sYZaPCGfVDGWde1EPjFLwKKxQ1Da/XoK0A==", + "dependencies": { + "@cosmjs/crypto": "0.26.5", + "@cosmjs/encoding": "0.26.5", + "@cosmjs/json-rpc": "0.26.5", + "@cosmjs/math": "0.26.5", + "@cosmjs/socket": "0.26.5", + "@cosmjs/stream": "0.26.5", + "axios": "^0.21.2", + "readonly-date": "^1.0.0", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/utils": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.26.5.tgz", + "integrity": "sha512-VB4Z7lEIXA36q0RON15KexzEosToUtdDyMv7UXSBHSl4mLG/fIZgBIpBEYsaPZ1kh43xyINeKQJiGCp2z5rI+g==" + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", + "integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/nyc-config-typescript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.2.tgz", + "integrity": "sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "nyc": ">=15" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "node_modules/@types/component-emitter": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", + "dev": true + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", + "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-plugin-prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz", + "integrity": "sha512-6/UIuz99F0IvtDez4U3bRwAmN4VKnuw10Ibblf0iZhtNbmbonMSLqs/qqsXrGIAWvjy+vXqYwOljgtLhrETSMg==", + "dev": true, + "dependencies": { + "@types/eslint": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.2.tgz", + "integrity": "sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "node_modules/@types/jasmine": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.10.3.tgz", + "integrity": "sha512-SWyMrjgdAUHNQmutvDcKablrJhkDLy4wunTme8oYLjKp41GnHGxMRXr2MQMvy/qy8H3LdzwQk9gH4hZ6T++H8g==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/karma": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@types/karma/-/karma-6.3.1.tgz", + "integrity": "sha512-t7hSJ8oWrgzrJV0nBqqMrDnQFft/W3WCPOfSi2aOq7rUPARLC8XpZfbsQ+mfYaNk18v1XqkBU12uirp1ISJVAA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "log4js": "^6.2.1" + } + }, + "node_modules/@types/karma-firefox-launcher": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/karma-firefox-launcher/-/karma-firefox-launcher-2.1.1.tgz", + "integrity": "sha512-4Z8uO7IxRIFhclT95eYKJW5tLcFY4HL/bXJgJNmDViT2FodeZGZViCD6pWk8PyUO35xoJYUJluTmw3AsYDTIYg==", + "dev": true, + "dependencies": { + "@types/karma": "*" + } + }, + "node_modules/@types/karma-jasmine": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/karma-jasmine/-/karma-jasmine-4.0.2.tgz", + "integrity": "sha512-eI7nm/IOPMMMYv9E0iVJVb90sp+mYSVCeWAEToyji37jOGEJKf8nfQZ7OwG9gMbymYuiaViEHY3l+fU7cmlI6w==", + "dev": true, + "dependencies": { + "@types/jasmine": "*", + "@types/karma": "*" + } + }, + "node_modules/@types/karma-jasmine-html-reporter": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@types/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", + "integrity": "sha512-a+COVKn0g4SnniJlUJqDnblSWbpNU7486/szfz/BZ1bBT1bJxSW2aCBsyvRqjTN2k5PBEEPfq39efhkqXGKDqw==", + "dev": true, + "dependencies": { + "@types/karma": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, + "node_modules/@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "dev": true, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "dev": true, + "dependencies": { + "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "dev": true, + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bip39": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", + "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/bip39/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/body-parser": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "dev": true, + "dependencies": { + "bytes": "3.1.1", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001296", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz", + "integrity": "sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmjs-types": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", + "integrity": "sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog==", + "dependencies": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/cosmjs-types/node_modules/protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "node_modules/date-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.35", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.35.tgz", + "integrity": "sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz", + "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "dev": true, + "dependencies": { + "base64-arraybuffer": "~1.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.2", + "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.12.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-simple-import-sort": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz", + "integrity": "sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==", + "dev": true, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isbinaryfile": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", + "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jasmine": { + "version": "3.99.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.99.0.tgz", + "integrity": "sha512-YIThBuHzaIIcjxeuLmPD40SjxkEcc8i//sGMDKCgkRMVgIwRJf5qyExtlJpQeh7pkeoBSOe6lQEdg+/9uKg9mw==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "jasmine-core": "~3.99.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } + }, + "node_modules/jasmine-core": { + "version": "3.99.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.99.0.tgz", + "integrity": "sha512-+ZDaJlEfRopINQqgE+hvzRyDIQDeKfqqTvF8RzXsvU1yE3pBDRud2+Qfh9WvGgRpuzqxyQJVI6Amy5XQ11r/3w==", + "dev": true + }, + "node_modules/jasmine-spec-reporter": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-6.0.0.tgz", + "integrity": "sha512-MvTOVoMxDZAftQYBApIlSfKnGMzi9cj351nXeqtnZTuXffPlbONN31+Es7F+Ke4okUeQ2xISukt4U1npfzLVrQ==", + "dev": true, + "dependencies": { + "colors": "1.4.0" + } + }, + "node_modules/jest-worker": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/karma": { + "version": "6.3.9", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.9.tgz", + "integrity": "sha512-E/MqdLM9uVIhfuyVnrhlGBu4miafBdXEAEqCmwdEMh3n17C7UWC/8Kvm3AYKr91gc7scutekZ0xv6rxRaUCtnw==", + "dev": true, + "dependencies": { + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "colors": "^1.4.0", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.3.0", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.2.0", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", + "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", + "dev": true, + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-chrome-launcher/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/karma-firefox-launcher": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", + "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==", + "dev": true, + "dependencies": { + "is-wsl": "^2.2.0", + "which": "^2.0.1" + } + }, + "node_modules/karma-jasmine": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz", + "integrity": "sha512-h8XDAhTiZjJKzfkoO1laMH+zfNlra+dEQHUAjpn5JV1zCPtOIVWGQjLBrqhnzQa/hrU2XrZwSyBa6XjEBzfXzw==", + "dev": true, + "dependencies": { + "jasmine-core": "^3.6.0" + }, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "karma": "*" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", + "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==", + "dev": true, + "peerDependencies": { + "jasmine-core": ">=3.8", + "karma": ">=0.9", + "karma-jasmine": ">=1.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libsodium": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.9.tgz", + "integrity": "sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A==" + }, + "node_modules/libsodium-wrappers": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz", + "integrity": "sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ==", + "dependencies": { + "libsodium": "^0.7.0" + } + }, + "node_modules/loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/log4js": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", + "dev": true, + "dependencies": { + "date-format": "^3.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.1", + "rfdc": "^1.1.4", + "streamroller": "^2.2.4" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/log4js/node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/marked": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/marked/-/marked-3.0.8.tgz", + "integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==", + "dev": true, + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/protobufjs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dev": true, + "dependencies": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readonly-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", + "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", + "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/ses": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/ses/-/ses-0.11.1.tgz", + "integrity": "sha512-ulorTzYygfVpvlKiAf/ZlnGFhJ7wngGHdJgi6hBrYwoV1tPsQNvBse9gfXMc7b0W8t98N9qagIYYveBkN+SiVA==", + "dev": true, + "dependencies": { + "@agoric/babel-standalone": "^7.9.5", + "@agoric/make-hardener": "^0.1.2", + "@agoric/transform-module": "^0.4.1" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.15.tgz", + "integrity": "sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/socket.io": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.0.tgz", + "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.1.0", + "socket.io-adapter": "~2.3.3", + "socket.io-parser": "~4.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", + "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==", + "dev": true + }, + "node_modules/socket.io-parser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "dev": true, + "dependencies": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/streamroller": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "dev": true, + "dependencies": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", + "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/table": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", + "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz", + "integrity": "sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==", + "dev": true, + "dependencies": { + "jest-worker": "^27.4.1", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/terser": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "acorn": "^8.5.0" + }, + "peerDependenciesMeta": { + "acorn": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typedoc": { + "version": "0.22.10", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.10.tgz", + "integrity": "sha512-hQYZ4WtoMZ61wDC6w10kxA42+jclWngdmztNZsDvIz7BMJg7F2xnT+uYsUa7OluyKossdFj9E9Ye4QOZKTy8SA==", + "dev": true, + "dependencies": { + "glob": "^7.2.0", + "lunr": "^2.3.9", + "marked": "^3.0.8", + "minimatch": "^3.0.4", + "shiki": "^0.9.12" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 12.10.0" + }, + "peerDependencies": { + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x" + } + }, + "node_modules/typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", + "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz", + "integrity": "sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "dev": true + }, + "node_modules/watchpack": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", + "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.65.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", + "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.2" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", + "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", + "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xstream": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", + "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", + "dependencies": { + "globalthis": "^1.0.1", + "symbol-observable": "^2.0.3" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@agoric/babel-standalone": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@agoric/babel-standalone/-/babel-standalone-7.14.3.tgz", + "integrity": "sha512-Rdlxts19kvxHsqTjTrhGJv0yKgCyjCSVgXoLBZf9dZ7lyo/j+6xFQBiWjP03bXve3X74wUvA1QU55wVey8DEiQ==", + "dev": true + }, + "@agoric/make-hardener": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@agoric/make-hardener/-/make-hardener-0.1.3.tgz", + "integrity": "sha512-rc9M2ErE/Zu822OLCnAltr957ZVTsBvVZ7KA2unqDpjo3q7PqZF2hWFB1xXD2Qkfwt5exQ3BjFbkj+NUaTg4gA==", + "dev": true + }, + "@agoric/transform-module": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@agoric/transform-module/-/transform-module-0.4.1.tgz", + "integrity": "sha512-4TJJHXeXAWu1FCA7yXCAZmhBNoGTB/BEAe2pv+J2X8W/mJTr9b395OkDCSRMpzvmSshLfBx6wT0D7dqWIWEC1w==", + "dev": true + }, + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true + }, + "@babel/core": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz", + "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.7.tgz", + "integrity": "sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/highlight": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", + "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.7.tgz", + "integrity": "sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==", + "dev": true + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + } + } + }, + "@babel/traverse": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.7.tgz", + "integrity": "sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.7.tgz", + "integrity": "sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@confio/ics23": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.5.tgz", + "integrity": "sha512-1GdPMsaP/l8JSF4P4HWFLBhdcxHcJT8lS0nknBYNSZ1XrJOsJKUy6EkOwd9Pa1qJkXzY2gyNv7MdHR+AIwSTAg==", + "requires": { + "js-sha512": "^0.8.0", + "protobufjs": "^6.8.8", + "ripemd160": "^2.0.2", + "sha.js": "^2.4.11" + } + }, + "@cosmjs/amino": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.26.5.tgz", + "integrity": "sha512-RFf9P1eb7O60JEWaZ5jbQA0wVbwU4SiBJINEjZkhkB1vUrAxCkfSHBZdJrVg8+IIRSWxPUUVr8PMuIyWlORV3A==", + "requires": { + "@cosmjs/crypto": "0.26.5", + "@cosmjs/encoding": "0.26.5", + "@cosmjs/math": "0.26.5", + "@cosmjs/utils": "0.26.5" + } + }, + "@cosmjs/crypto": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.26.5.tgz", + "integrity": "sha512-ab7+qR/gdRi/DIdOLrjyimRdyD/2K/JdpRaFY1bl6Drr3ktVjDQrGsv53THvHONy33yCwD+YS+328ayQRv/pQA==", + "requires": { + "@cosmjs/encoding": "0.26.5", + "@cosmjs/math": "0.26.5", + "@cosmjs/utils": "0.26.5", + "bip39": "^3.0.2", + "bn.js": "^4.11.8", + "elliptic": "^6.5.3", + "js-sha3": "^0.8.0", + "libsodium-wrappers": "^0.7.6", + "ripemd160": "^2.0.2", + "sha.js": "^2.4.11" + } + }, + "@cosmjs/encoding": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.26.5.tgz", + "integrity": "sha512-lkw2mLvDZJqVCOZCBqdMzoGUtC4CN7c4+WMCGKDej3TpC0khsv7KZ1eFcsnN6EuZwHyGH67uyyjrs5x0ah9rYg==", + "requires": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "@cosmjs/json-rpc": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.26.5.tgz", + "integrity": "sha512-SFGm5MlY54v3I26hXThwVteh91U+/DKS+KGqFL5lPLHZ2EHxggASqhKMiTJBMJVUDWvnmv1ikjFndkWNhpTPNw==", + "requires": { + "@cosmjs/stream": "0.26.5", + "xstream": "^11.14.0" + } + }, + "@cosmjs/math": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.26.5.tgz", + "integrity": "sha512-1G7NgLJ35g4jUupvyu7Igtgu/fj2NmgpOofpNk1JqIwMXrm3Tx7lOWbxJq8Wrjj2EoH7FNytSO1dXNGeK15UJw==", + "requires": { + "bn.js": "^4.11.8" + } + }, + "@cosmjs/proto-signing": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.26.5.tgz", + "integrity": "sha512-F94Uh+PX9nF5zGzUHMdEGgys+YCOudaWQehiHBfOjbHUIv0khufcRXs3l9/5dKzizz9ouQ5DHQAiWq/nYKZKqA==", + "requires": { + "@cosmjs/amino": "0.26.5", + "@cosmjs/crypto": "0.26.5", + "@cosmjs/math": "0.26.5", + "cosmjs-types": "^0.2.0", + "long": "^4.0.0", + "protobufjs": "~6.10.2" + }, + "dependencies": { + "cosmjs-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.2.1.tgz", + "integrity": "sha512-EUG6TgdWkYHBzXjo5tZ82L+0QLijTu/rZGNIbJ/n07ST30GmptYkPmO+REX7qF4YUtli//Rfy0rrNzH9IMrMmw==", + "requires": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + }, + "dependencies": { + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } + } + } + }, + "@cosmjs/socket": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.26.5.tgz", + "integrity": "sha512-kBpXw9wuNHkO1AGuKgDA4/DOA+jZ6Lt0GVJVJIJ6bfjGbsewsNVocktAiH+1dGb47xXg2oH7OwGJL+B/PB3qPQ==", + "requires": { + "@cosmjs/stream": "0.26.5", + "isomorphic-ws": "^4.0.1", + "ws": "^7", + "xstream": "^11.14.0" + } + }, + "@cosmjs/stream": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.26.5.tgz", + "integrity": "sha512-CIr/8bkRlLl36LAtbapsKxA7cMVhmPPWTihAcXgBXik1FM/0XCVNETPTQ64HX47eNQuP5AhWwaMoO553Sf9T2w==", + "requires": { + "xstream": "^11.14.0" + } + }, + "@cosmjs/tendermint-rpc": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.26.5.tgz", + "integrity": "sha512-bBcFgpTHEP15m8n/bG3cx/LO110sScpEvYvurZDewfy7MW8WETF6sYZaPCGfVDGWde1EPjFLwKKxQ1Da/XoK0A==", + "requires": { + "@cosmjs/crypto": "0.26.5", + "@cosmjs/encoding": "0.26.5", + "@cosmjs/json-rpc": "0.26.5", + "@cosmjs/math": "0.26.5", + "@cosmjs/socket": "0.26.5", + "@cosmjs/stream": "0.26.5", + "axios": "^0.21.2", + "readonly-date": "^1.0.0", + "xstream": "^11.14.0" + } + }, + "@cosmjs/utils": { + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.26.5.tgz", + "integrity": "sha512-VB4Z7lEIXA36q0RON15KexzEosToUtdDyMv7UXSBHSl4mLG/fIZgBIpBEYsaPZ1kh43xyINeKQJiGCp2z5rI+g==" + }, + "@discoveryjs/json-ext": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", + "integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/nyc-config-typescript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.2.tgz", + "integrity": "sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@types/component-emitter": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", + "dev": true + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "dev": true + }, + "@types/eslint": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", + "integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-plugin-prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz", + "integrity": "sha512-6/UIuz99F0IvtDez4U3bRwAmN4VKnuw10Ibblf0iZhtNbmbonMSLqs/qqsXrGIAWvjy+vXqYwOljgtLhrETSMg==", + "dev": true, + "requires": { + "@types/eslint": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.2.tgz", + "integrity": "sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "@types/jasmine": { + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.10.3.tgz", + "integrity": "sha512-SWyMrjgdAUHNQmutvDcKablrJhkDLy4wunTme8oYLjKp41GnHGxMRXr2MQMvy/qy8H3LdzwQk9gH4hZ6T++H8g==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/karma": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@types/karma/-/karma-6.3.1.tgz", + "integrity": "sha512-t7hSJ8oWrgzrJV0nBqqMrDnQFft/W3WCPOfSi2aOq7rUPARLC8XpZfbsQ+mfYaNk18v1XqkBU12uirp1ISJVAA==", + "dev": true, + "requires": { + "@types/node": "*", + "log4js": "^6.2.1" + } + }, + "@types/karma-firefox-launcher": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/karma-firefox-launcher/-/karma-firefox-launcher-2.1.1.tgz", + "integrity": "sha512-4Z8uO7IxRIFhclT95eYKJW5tLcFY4HL/bXJgJNmDViT2FodeZGZViCD6pWk8PyUO35xoJYUJluTmw3AsYDTIYg==", + "dev": true, + "requires": { + "@types/karma": "*" + } + }, + "@types/karma-jasmine": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/karma-jasmine/-/karma-jasmine-4.0.2.tgz", + "integrity": "sha512-eI7nm/IOPMMMYv9E0iVJVb90sp+mYSVCeWAEToyji37jOGEJKf8nfQZ7OwG9gMbymYuiaViEHY3l+fU7cmlI6w==", + "dev": true, + "requires": { + "@types/jasmine": "*", + "@types/karma": "*" + } + }, + "@types/karma-jasmine-html-reporter": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@types/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", + "integrity": "sha512-a+COVKn0g4SnniJlUJqDnblSWbpNU7486/szfz/BZ1bBT1bJxSW2aCBsyvRqjTN2k5PBEEPfq39efhkqXGKDqw==", + "dev": true, + "requires": { + "@types/karma": "*" + } + }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, + "@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + } + }, + "@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bip39": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", + "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", + "requires": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" + } + } + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "body-parser": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "dev": true, + "requires": { + "bytes": "3.1.1", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "dev": true + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001296", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz", + "integrity": "sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmjs-types": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", + "integrity": "sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog==", + "requires": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + }, + "dependencies": { + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "date-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.35", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.35.tgz", + "integrity": "sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "engine.io": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz", + "integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==", + "dev": true, + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" + }, + "dependencies": { + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "requires": {} + } + } + }, + "engine.io-parser": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.2.tgz", + "integrity": "sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g==", + "dev": true, + "requires": { + "base64-arraybuffer": "~1.0.1" + } + }, + "enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true, + "requires": {} + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.2", + "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-simple-import-sort": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz", + "integrity": "sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "follow-redirects": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==" + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globalthis": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", + "requires": { + "define-properties": "^1.1.3" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isbinaryfile": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", + "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "requires": {} + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jasmine": { + "version": "3.99.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.99.0.tgz", + "integrity": "sha512-YIThBuHzaIIcjxeuLmPD40SjxkEcc8i//sGMDKCgkRMVgIwRJf5qyExtlJpQeh7pkeoBSOe6lQEdg+/9uKg9mw==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "jasmine-core": "~3.99.0" + } + }, + "jasmine-core": { + "version": "3.99.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.99.0.tgz", + "integrity": "sha512-+ZDaJlEfRopINQqgE+hvzRyDIQDeKfqqTvF8RzXsvU1yE3pBDRud2+Qfh9WvGgRpuzqxyQJVI6Amy5XQ11r/3w==", + "dev": true + }, + "jasmine-spec-reporter": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-6.0.0.tgz", + "integrity": "sha512-MvTOVoMxDZAftQYBApIlSfKnGMzi9cj351nXeqtnZTuXffPlbONN31+Es7F+Ke4okUeQ2xISukt4U1npfzLVrQ==", + "dev": true, + "requires": { + "colors": "1.4.0" + } + }, + "jest-worker": { + "version": "27.4.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", + "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "karma": { + "version": "6.3.9", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.9.tgz", + "integrity": "sha512-E/MqdLM9uVIhfuyVnrhlGBu4miafBdXEAEqCmwdEMh3n17C7UWC/8Kvm3AYKr91gc7scutekZ0xv6rxRaUCtnw==", + "dev": true, + "requires": { + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "colors": "^1.4.0", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.3.0", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.2.0", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + } + }, + "karma-chrome-launcher": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", + "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==", + "dev": true, + "requires": { + "which": "^1.2.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "karma-firefox-launcher": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", + "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==", + "dev": true, + "requires": { + "is-wsl": "^2.2.0", + "which": "^2.0.1" + } + }, + "karma-jasmine": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz", + "integrity": "sha512-h8XDAhTiZjJKzfkoO1laMH+zfNlra+dEQHUAjpn5JV1zCPtOIVWGQjLBrqhnzQa/hrU2XrZwSyBa6XjEBzfXzw==", + "dev": true, + "requires": { + "jasmine-core": "^3.6.0" + } + }, + "karma-jasmine-html-reporter": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", + "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==", + "dev": true, + "requires": {} + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "libsodium": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.9.tgz", + "integrity": "sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A==" + }, + "libsodium-wrappers": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz", + "integrity": "sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ==", + "requires": { + "libsodium": "^0.7.0" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log4js": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", + "dev": true, + "requires": { + "date-format": "^3.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.1", + "rfdc": "^1.1.4", + "streamroller": "^2.2.4" + }, + "dependencies": { + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + } + } + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "marked": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/marked/-/marked-3.0.8.tgz", + "integrity": "sha512-0gVrAjo5m0VZSJb4rpL59K1unJAMb/hm8HRXqasD8VeC8m91ytDPMritgFSlKonfdt+rRYYpP/JfLxgIX8yoSw==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "requires": { + "mime-db": "1.51.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "protobufjs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dev": true, + "requires": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "readonly-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", + "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", + "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==", + "dev": true, + "requires": { + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "ses": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/ses/-/ses-0.11.1.tgz", + "integrity": "sha512-ulorTzYygfVpvlKiAf/ZlnGFhJ7wngGHdJgi6hBrYwoV1tPsQNvBse9gfXMc7b0W8t98N9qagIYYveBkN+SiVA==", + "dev": true, + "requires": { + "@agoric/babel-standalone": "^7.9.5", + "@agoric/make-hardener": "^0.1.2", + "@agoric/transform-module": "^0.4.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shiki": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.15.tgz", + "integrity": "sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==", + "dev": true, + "requires": { + "jsonc-parser": "^3.0.0", + "vscode-oniguruma": "^1.6.1", + "vscode-textmate": "5.2.0" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "socket.io": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.0.tgz", + "integrity": "sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.1.0", + "socket.io-adapter": "~2.3.3", + "socket.io-parser": "~4.0.4" + } + }, + "socket.io-adapter": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", + "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==", + "dev": true + }, + "socket.io-parser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "dev": true, + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "streamroller": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "dev": true, + "requires": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "symbol-observable": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", + "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==" + }, + "table": { + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", + "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser-webpack-plugin": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz", + "integrity": "sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==", + "dev": true, + "requires": { + "jest-worker": "^27.4.1", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "optional": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "terser": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz", + "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, + "tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typedoc": { + "version": "0.22.10", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.10.tgz", + "integrity": "sha512-hQYZ4WtoMZ61wDC6w10kxA42+jclWngdmztNZsDvIz7BMJg7F2xnT+uYsUa7OluyKossdFj9E9Ye4QOZKTy8SA==", + "dev": true, + "requires": { + "glob": "^7.2.0", + "lunr": "^2.3.9", + "marked": "^3.0.8", + "minimatch": "^3.0.4", + "shiki": "^0.9.12" + } + }, + "typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", + "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "vscode-oniguruma": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.1.tgz", + "integrity": "sha512-vc4WhSIaVpgJ0jJIejjYxPvURJavX6QG41vu0mGhqywMkQqulezEqEQ3cO3gc8GvcOpX6ycmKGqRoROEMBNXTQ==", + "dev": true + }, + "vscode-textmate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "dev": true + }, + "watchpack": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", + "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.65.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz", + "integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.2" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true, + "requires": {} + } + } + }, + "webpack-cli": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", + "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.2.tgz", + "integrity": "sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", + "requires": {} + }, + "xstream": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", + "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", + "requires": { + "globalthis": "^1.0.1", + "symbol-observable": "^2.0.3" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8e957ec --- /dev/null +++ b/package.json @@ -0,0 +1,95 @@ +{ + "name": "@cosmjs/stargate", + "version": "0.27.0-rc2", + "description": "Utilities for Cosmos SDK 0.40", + "contributors": [ + "Simon Warta " + ], + "license": "Apache-2.0", + "main": "build/index.js", + "types": "build/index.d.ts", + "files": [ + "build/", + "*.md", + "!*.spec.*", + "!**/testdata/" + ], + "repository": { + "type": "git", + "url": "https://github.com/cosmos/cosmjs/tree/main/packages/stargate" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "scripts": { + "docs": "typedoc --options typedoc.js", + "lint": "eslint --max-warnings 0 \"./**/*.ts\" \"./*.js\"", + "lint-fix": "eslint --fix --max-warnings 0 \"./**/*.ts\" \"./*.js\"", + "format": "prettier --write --loglevel warn \"./src/**/*.ts\"", + "format-text": "prettier --write \"./*.md\"", + "build": "rm -rf ./build && tsc", + "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", + "test-node": "yarn node jasmine-testrunner.js", + "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", + "test-chrome": "yarn pack-web && karma start --single-run --browsers ChromeHeadless", + "test": "yarn build-or-skip && yarn test-node", + "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", + "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" + }, + "dependencies": { + "@confio/ics23": "^0.6.3", + "@cosmjs/amino": "v0.26.5", + "@cosmjs/encoding": "v0.26.5", + "@cosmjs/math": "v0.26.5", + "@cosmjs/proto-signing": "v0.26.5", + "@cosmjs/stream": "v0.26.5", + "@cosmjs/tendermint-rpc": "v0.26.5", + "@cosmjs/utils": "v0.26.5", + "cosmjs-types": "^0.4.0", + "long": "^4.0.0", + "protobufjs": "~6.10.2", + "xstream": "^11.14.0" + }, + "devDependencies": { + "@cosmjs/crypto": "v0.26.5", + "@istanbuljs/nyc-config-typescript": "^1.0.1", + "@types/eslint-plugin-prettier": "^3", + "@types/jasmine": "^3.8", + "@types/karma-firefox-launcher": "^2", + "@types/karma-jasmine": "^4", + "@types/karma-jasmine-html-reporter": "^1", + "@types/long": "^4.0.1", + "@types/node": "^15.0.1", + "@typescript-eslint/eslint-plugin": "^4.28", + "@typescript-eslint/parser": "^4.28", + "eslint": "^7.5", + "eslint-config-prettier": "^8.3.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-prettier": "^3.4.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "esm": "^3.2.25", + "glob": "^7.1.6", + "jasmine": "^3.8", + "jasmine-core": "^3.7.1", + "jasmine-spec-reporter": "^6", + "karma": "^6.1.1", + "karma-chrome-launcher": "^3.1.0", + "karma-firefox-launcher": "^2.1.0", + "karma-jasmine": "^4.0.1", + "karma-jasmine-html-reporter": "^1.5.4", + "nyc": "^15.1.0", + "prettier": "^2.4.1", + "readonly-date": "^1.0.0", + "ses": "^0.11.0", + "source-map-support": "^0.5.19", + "stream-browserify": "^3.0.0", + "ts-node": "^8", + "typedoc": "^0.22", + "typescript": "~4.4", + "webpack": "^5.32.0", + "webpack-cli": "^4.6.0" + }, + "stableVersion": "0.26.5" +} diff --git a/src/accounts.spec.ts b/src/accounts.spec.ts new file mode 100644 index 0000000..f4010d2 --- /dev/null +++ b/src/accounts.spec.ts @@ -0,0 +1,27 @@ +import { Any } from "cosmjs-types/google/protobuf/any"; + +import { accountFromAny } from "./accounts"; + +describe("accounts", () => { + describe("accountFromAny", () => { + it("works for PeriodicVestingAccount", () => { + // Queried from chain via `packages/cli/examples/get_akash_vesting_account.ts`. + const any = Any.fromJSON({ + typeUrl: "/cosmos.vesting.v1beta1.PeriodicVestingAccount", + value: + "CsMBCnoKLGFrYXNoMXF5MHZ1cjNmbDJ1Y3p0cHpjcmZlYTdtYzhqd3o4eGptdnE3cXZ5EkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohA/XsdhwSIKU73TltD9STcaS07FNw0szR4a+oDLr6vikaGDggGxIUCgR1YWt0EgwxNjY2NjY2NzAwMDAaEwoEdWFrdBILMzcxOTAzMzAwMDAiFAoEdWFrdBIMMTY2NjY2NjcwMDAwKOC9wZkGEODvt/sFGhoIgOeEDxITCgR1YWt0Egs4MzMzMzMzNTAwMBoaCIC/ugcSEwoEdWFrdBILNDE2NjY2Njc1MDAaGgiAqMoHEhMKBHVha3QSCzQxNjY2NjY3NTAw", + }); + + const account = accountFromAny(any); + expect(account).toEqual({ + address: "akash1qy0vur3fl2ucztpzcrfea7mc8jwz8xjmvq7qvy", + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "A/XsdhwSIKU73TltD9STcaS07FNw0szR4a+oDLr6vika", + }, + accountNumber: 56, + sequence: 27, + }); + }); + }); +}); diff --git a/src/accounts.ts b/src/accounts.ts new file mode 100644 index 0000000..20c8a3a --- /dev/null +++ b/src/accounts.ts @@ -0,0 +1,84 @@ +import { Pubkey } from "@cosmjs/amino"; +import { Uint64 } from "@cosmjs/math"; +import { decodePubkey } from "@cosmjs/proto-signing"; +import { assert } from "@cosmjs/utils"; +import { BaseAccount, ModuleAccount } from "cosmjs-types/cosmos/auth/v1beta1/auth"; +import { + BaseVestingAccount, + ContinuousVestingAccount, + DelayedVestingAccount, + PeriodicVestingAccount, +} from "cosmjs-types/cosmos/vesting/v1beta1/vesting"; +import { Any } from "cosmjs-types/google/protobuf/any"; +import Long from "long"; + +export interface Account { + /** Bech32 account address */ + readonly address: string; + readonly pubkey: Pubkey | null; + readonly accountNumber: number; + readonly sequence: number; +} + +function uint64FromProto(input: number | Long): Uint64 { + return Uint64.fromString(input.toString()); +} + +function accountFromBaseAccount(input: BaseAccount): Account { + const { address, pubKey, accountNumber, sequence } = input; + const pubkey = decodePubkey(pubKey); + return { + address: address, + pubkey: pubkey, + accountNumber: uint64FromProto(accountNumber).toNumber(), + sequence: uint64FromProto(sequence).toNumber(), + }; +} + +/** + * Takes an `Any` encoded account from the chain and extracts some common + * `Account` information from it. This is supposed to support the most relevant + * common Cosmos SDK account types. If you need support for exotic account types, + * you'll need to write your own account decoder. + */ +export function accountFromAny(input: Any): Account { + const { typeUrl, value } = input; + + switch (typeUrl) { + // auth + + case "/cosmos.auth.v1beta1.BaseAccount": + return accountFromBaseAccount(BaseAccount.decode(value)); + case "/cosmos.auth.v1beta1.ModuleAccount": { + const baseAccount = ModuleAccount.decode(value).baseAccount; + assert(baseAccount); + return accountFromBaseAccount(baseAccount); + } + + // vesting + + case "/cosmos.vesting.v1beta1.BaseVestingAccount": { + const baseAccount = BaseVestingAccount.decode(value)?.baseAccount; + assert(baseAccount); + return accountFromBaseAccount(baseAccount); + } + case "/cosmos.vesting.v1beta1.ContinuousVestingAccount": { + const baseAccount = ContinuousVestingAccount.decode(value)?.baseVestingAccount?.baseAccount; + assert(baseAccount); + return accountFromBaseAccount(baseAccount); + } + case "/cosmos.vesting.v1beta1.DelayedVestingAccount": { + const baseAccount = DelayedVestingAccount.decode(value)?.baseVestingAccount?.baseAccount; + assert(baseAccount); + return accountFromBaseAccount(baseAccount); + } + case "/cosmos.vesting.v1beta1.PeriodicVestingAccount": { + const baseAccount = PeriodicVestingAccount.decode(value)?.baseVestingAccount?.baseAccount; + assert(baseAccount); + return accountFromBaseAccount(baseAccount); + } + + default: + throw new Error(`Unsupported type: '${typeUrl}'`); + } +} diff --git a/src/aminomsgs.ts b/src/aminomsgs.ts new file mode 100644 index 0000000..886d794 --- /dev/null +++ b/src/aminomsgs.ts @@ -0,0 +1,390 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { AminoMsg, Coin } from "@cosmjs/amino"; + +// auth (no messages) - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/auth/auth.proto + +// bank - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/bank/bank.proto + +/** A high level transaction of the coin module */ +export interface AminoMsgSend extends AminoMsg { + readonly type: "cosmos-sdk/MsgSend"; + readonly value: { + /** Bech32 account address */ + readonly from_address: string; + /** Bech32 account address */ + readonly to_address: string; + readonly amount: readonly Coin[]; + }; +} + +export function isAminoMsgSend(msg: AminoMsg): msg is AminoMsgSend { + return msg.type === "cosmos-sdk/MsgSend"; +} + +interface Input { + /** Bech32 account address */ + readonly address: string; + readonly coins: readonly Coin[]; +} + +interface Output { + /** Bech32 account address */ + readonly address: string; + readonly coins: readonly Coin[]; +} + +/** A high level transaction of the coin module */ +export interface AminoMsgMultiSend extends AminoMsg { + readonly type: "cosmos-sdk/MsgMultiSend"; + readonly value: { + readonly inputs: readonly Input[]; + readonly outputs: readonly Output[]; + }; +} + +export function isAminoMsgMultiSend(msg: AminoMsg): msg is AminoMsgMultiSend { + return msg.type === "cosmos-sdk/MsgMultiSend"; +} + +// crisis - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/crisis/crisis.proto + +/** Verifies a particular invariance */ +export interface AminoMsgVerifyInvariant extends AminoMsg { + readonly type: "cosmos-sdk/MsgVerifyInvariant"; + readonly value: { + /** Bech32 account address */ + readonly sender: string; + readonly invariant_module_name: string; + readonly invariant_route: string; + }; +} + +export function isAminoMsgVerifyInvariant(msg: AminoMsg): msg is AminoMsgVerifyInvariant { + return msg.type === "cosmos-sdk/MsgVerifyInvariant"; +} + +// distribution - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/distribution/distribution.proto + +/** Changes the withdraw address for a delegator (or validator self-delegation) */ +export interface AminoMsgSetWithdrawAddress extends AminoMsg { + // NOTE: Type string and names diverge here! + readonly type: "cosmos-sdk/MsgModifyWithdrawAddress"; + readonly value: { + /** Bech32 account address */ + readonly delegator_address: string; + /** Bech32 account address */ + readonly withdraw_address: string; + }; +} + +export function isAminoMsgSetWithdrawAddress(msg: AminoMsg): msg is AminoMsgSetWithdrawAddress { + // NOTE: Type string and names diverge here! + return msg.type === "cosmos-sdk/MsgModifyWithdrawAddress"; +} + +/** Message for delegation withdraw from a single validator */ +export interface AminoMsgWithdrawDelegatorReward extends AminoMsg { + // NOTE: Type string and names diverge here! + readonly type: "cosmos-sdk/MsgWithdrawDelegationReward"; + readonly value: { + /** Bech32 account address */ + readonly delegator_address: string; + /** Bech32 account address */ + readonly validator_address: string; + }; +} + +export function isAminoMsgWithdrawDelegatorReward(msg: AminoMsg): msg is AminoMsgWithdrawDelegatorReward { + // NOTE: Type string and names diverge here! + return msg.type === "cosmos-sdk/MsgWithdrawDelegationReward"; +} + +/** Message for validator withdraw */ +export interface AminoMsgWithdrawValidatorCommission extends AminoMsg { + readonly type: "cosmos-sdk/MsgWithdrawValidatorCommission"; + readonly value: { + /** Bech32 account address */ + readonly validator_address: string; + }; +} + +export function isAminoMsgWithdrawValidatorCommission( + msg: AminoMsg, +): msg is AminoMsgWithdrawValidatorCommission { + return msg.type === "cosmos-sdk/MsgWithdrawValidatorCommission"; +} + +/** Allows an account to directly fund the community pool. */ +export interface AminoMsgFundCommunityPool extends AminoMsg { + readonly type: "cosmos-sdk/MsgFundCommunityPool"; + readonly value: { + readonly amount: readonly Coin[]; + /** Bech32 account address */ + readonly depositor: string; + }; +} + +export function isAminoMsgFundCommunityPool(msg: AminoMsg): msg is AminoMsgFundCommunityPool { + return msg.type === "cosmos-sdk/MsgFundCommunityPool"; +} + +// evidence - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/evidence/evidence.proto + +interface Any { + readonly type_url: string; + readonly value: Uint8Array; +} + +/** Supports submitting arbitrary evidence */ +export interface AminoMsgSubmitEvidence extends AminoMsg { + readonly type: "cosmos-sdk/MsgSubmitEvidence"; + readonly value: { + /** Bech32 account address */ + readonly submitter: string; + readonly evidence: Any; + }; +} + +export function isAminoMsgSubmitEvidence(msg: AminoMsg): msg is AminoMsgSubmitEvidence { + return msg.type === "cosmos-sdk/MsgSubmitEvidence"; +} + +// gov - https://github.com/cosmos/cosmos-sdk/blob/efa73c7edb31a7bd65786501da213b294f89267a/proto/cosmos/gov/gov.proto + +/** Supports submitting arbitrary proposal content. */ +export interface AminoMsgSubmitProposal extends AminoMsg { + readonly type: "cosmos-sdk/MsgSubmitProposal"; + readonly value: { + /** + * A proposal structure, e.g. + * + * ``` + * { + * type: 'cosmos-sdk/TextProposal', + * value: { + * description: 'This proposal proposes to test whether this proposal passes', + * title: 'Test Proposal' + * } + * } + * ``` + */ + readonly content: { + readonly type: string; + readonly value: any; + }; + readonly initial_deposit: readonly Coin[]; + /** Bech32 account address */ + readonly proposer: string; + }; +} + +export function isAminoMsgSubmitProposal(msg: AminoMsg): msg is AminoMsgSubmitProposal { + return msg.type === "cosmos-sdk/MsgSubmitProposal"; +} + +/** Casts a vote */ +export interface AminoMsgVote extends AminoMsg { + readonly type: "cosmos-sdk/MsgVote"; + readonly value: { + readonly proposal_id: string; + /** Bech32 account address */ + readonly voter: string; + /** + * VoteOption as integer from 0 to 4 🤷‍ + * + * @see https://github.com/cosmos/cosmos-sdk/blob/v0.42.9/x/gov/types/gov.pb.go#L38-L49 + */ + readonly option: number; + }; +} + +export function isAminoMsgVote(msg: AminoMsg): msg is AminoMsgVote { + return msg.type === "cosmos-sdk/MsgVote"; +} + +/** Submits a deposit to an existing proposal */ +export interface AminoMsgDeposit extends AminoMsg { + readonly type: "cosmos-sdk/MsgDeposit"; + readonly value: { + readonly proposal_id: string; + /** Bech32 account address */ + readonly depositor: string; + readonly amount: readonly Coin[]; + }; +} + +export function isAminoMsgDeposit(msg: AminoMsg): msg is AminoMsgDeposit { + return msg.type === "cosmos-sdk/MsgDeposit"; +} + +// mint (no messages) - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/mint/mint.proto + +// params (no messages) - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/params/params.proto + +// slashing - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/slashing/slashing.proto + +/** Unjails a jailed validator */ +export interface AminoMsgUnjail extends AminoMsg { + readonly type: "cosmos-sdk/MsgUnjail"; + readonly value: { + /** Bech32 account address */ + readonly validator_addr: string; + }; +} + +export function isAminoMsgUnjail(msg: AminoMsg): msg is AminoMsgUnjail { + return msg.type === "cosmos-sdk/MsgUnjail"; +} + +// staking - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/staking/staking.proto + +/** The initial commission rates to be used for creating a validator */ +interface CommissionRates { + readonly rate: string; + readonly max_rate: string; + readonly max_change_rate: string; +} + +/** A validator description. */ +interface Description { + readonly moniker: string; + readonly identity: string; + readonly website: string; + readonly security_contact: string; + readonly details: string; +} + +/** Creates a new validator. */ +export interface AminoMsgCreateValidator extends AminoMsg { + readonly type: "cosmos-sdk/MsgCreateValidator"; + readonly value: { + readonly description: Description; + readonly commission: CommissionRates; + readonly min_self_delegation: string; + /** Bech32 encoded delegator address */ + readonly delegator_address: string; + /** Bech32 encoded validator address */ + readonly validator_address: string; + /** Bech32 encoded public key */ + readonly pubkey: string; + readonly value: Coin; + }; +} + +export function isAminoMsgCreateValidator(msg: AminoMsg): msg is AminoMsgCreateValidator { + return msg.type === "cosmos-sdk/MsgCreateValidator"; +} + +/** Edits an existing validator. */ +export interface AminoMsgEditValidator extends AminoMsg { + readonly type: "cosmos-sdk/MsgEditValidator"; + readonly value: { + readonly description: Description; + /** Bech32 encoded validator address */ + readonly validator_address: string; + readonly commission_rate: string; + readonly min_self_delegation: string; + }; +} + +export function isAminoMsgEditValidator(msg: AminoMsg): msg is AminoMsgEditValidator { + return msg.type === "cosmos-sdk/MsgEditValidator"; +} + +/** + * Performs a delegation from a delegate to a validator. + * + * @see https://docs.cosmos.network/master/modules/staking/03_messages.html#msgdelegate + */ +export interface AminoMsgDelegate extends AminoMsg { + readonly type: "cosmos-sdk/MsgDelegate"; + readonly value: { + /** Bech32 encoded delegator address */ + readonly delegator_address: string; + /** Bech32 encoded validator address */ + readonly validator_address: string; + readonly amount: Coin; + }; +} + +export function isAminoMsgDelegate(msg: AminoMsg): msg is AminoMsgDelegate { + return msg.type === "cosmos-sdk/MsgDelegate"; +} + +/** Performs a redelegation from a delegate and source validator to a destination validator */ +export interface AminoMsgBeginRedelegate extends AminoMsg { + readonly type: "cosmos-sdk/MsgBeginRedelegate"; + readonly value: { + /** Bech32 encoded delegator address */ + readonly delegator_address: string; + /** Bech32 encoded source validator address */ + readonly validator_src_address: string; + /** Bech32 encoded destination validator address */ + readonly validator_dst_address: string; + readonly amount: Coin; + }; +} + +export function isAminoMsgBeginRedelegate(msg: AminoMsg): msg is AminoMsgBeginRedelegate { + return msg.type === "cosmos-sdk/MsgBeginRedelegate"; +} + +/** Performs an undelegation from a delegate and a validator */ +export interface AminoMsgUndelegate extends AminoMsg { + readonly type: "cosmos-sdk/MsgUndelegate"; + readonly value: { + /** Bech32 encoded delegator address */ + readonly delegator_address: string; + /** Bech32 encoded validator address */ + readonly validator_address: string; + readonly amount: Coin; + }; +} + +export function isAminoMsgUndelegate(msg: AminoMsg): msg is AminoMsgUndelegate { + return msg.type === "cosmos-sdk/MsgUndelegate"; +} + +// upgrade (no messages) - see https://github.com/cosmos/cosmos-sdk/blob/efa73c7/proto/cosmos/upgrade/upgrade.proto + +// ibc + +// https://github.com/cosmos/ibc-go/blob/07b6a97b67d17fd214a83764cbdb2c2c3daef445/modules/core/02-client/types/client.pb.go#L297-L312 +interface AminoHeight { + /** 0 values must be omitted (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/core/02-client/types/client.pb.go#L252). */ + readonly revision_number?: string; + /** 0 values must be omitted (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/core/02-client/types/client.pb.go#L254). */ + readonly revision_height?: string; +} + +// https://github.com/cosmos/ibc-go/blob/07b6a97b67d17fd214a83764cbdb2c2c3daef445/modules/apps/transfer/types/tx.pb.go#L33-L53 +/** Transfers fungible tokens (i.e Coins) between ICS20 enabled chains */ +export interface AminoMsgTransfer extends AminoMsg { + readonly type: "cosmos-sdk/MsgTransfer"; + readonly value: { + readonly source_port: string; + readonly source_channel: string; + readonly token?: Coin; + /** Bech32 account address */ + readonly sender: string; + /** Bech32 account address */ + readonly receiver: string; + /** + * The timeout as a (revision_number, revision_height) pair. + * + * This fied is is non-optional (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/applications/transfer/types/tx.pb.go#L49). + * In order to not set the timeout height, set it to {}. + */ + readonly timeout_height: AminoHeight; + /** + * Timeout timestamp (in nanoseconds). The timeout is disabled when set to 0. + * + * 0 values must be omitted (https://github.com/cosmos/cosmos-sdk/blob/v0.42.7/x/ibc/applications/transfer/types/tx.pb.go#L52). + */ + readonly timeout_timestamp?: string; + }; +} + +export function isAminoMsgTransfer(msg: AminoMsg): msg is AminoMsgTransfer { + return msg.type === "cosmos-sdk/MsgTransfer"; +} diff --git a/src/aminotypes.spec.ts b/src/aminotypes.spec.ts new file mode 100644 index 0000000..399dbf1 --- /dev/null +++ b/src/aminotypes.spec.ts @@ -0,0 +1,1011 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { encodeBech32Pubkey } from "@cosmjs/amino"; +import { fromBase64 } from "@cosmjs/encoding"; +import { coin, coins } from "@cosmjs/proto-signing"; +import { MsgMultiSend, MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; +import { + MsgFundCommunityPool, + MsgSetWithdrawAddress, + MsgWithdrawDelegatorReward, + MsgWithdrawValidatorCommission, +} from "cosmjs-types/cosmos/distribution/v1beta1/tx"; +import { TextProposal, VoteOption } from "cosmjs-types/cosmos/gov/v1beta1/gov"; +import { MsgDeposit, MsgSubmitProposal, MsgVote } from "cosmjs-types/cosmos/gov/v1beta1/tx"; +import { + MsgBeginRedelegate, + MsgCreateValidator, + MsgDelegate, + MsgEditValidator, + MsgUndelegate, +} from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx"; +import Long from "long"; + +import { + AminoMsgBeginRedelegate, + AminoMsgCreateValidator, + AminoMsgDelegate, + AminoMsgDeposit, + AminoMsgEditValidator, + AminoMsgFundCommunityPool, + AminoMsgMultiSend, + AminoMsgSend, + AminoMsgSetWithdrawAddress, + AminoMsgSubmitProposal, + AminoMsgTransfer, + AminoMsgUndelegate, + AminoMsgVote, + AminoMsgWithdrawDelegatorReward, + AminoMsgWithdrawValidatorCommission, +} from "./aminomsgs"; +import { AminoTypes } from "./aminotypes"; + +describe("AminoTypes", () => { + describe("toAmino", () => { + // bank + + it("works for MsgSend", () => { + const msg: MsgSend = { + fromAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + toAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coins(1234, "ucosm"), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msg, + }); + const expected: AminoMsgSend = { + type: "cosmos-sdk/MsgSend", + value: { + from_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + to_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coins(1234, "ucosm"), + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgMultiSend", () => { + const msg: MsgMultiSend = { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: coins(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: coins(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: coins(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: coins(912, "ucosm") }, + ], + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.bank.v1beta1.MsgMultiSend", + value: msg, + }); + const expected: AminoMsgMultiSend = { + type: "cosmos-sdk/MsgMultiSend", + value: { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: coins(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: coins(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: coins(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: coins(912, "ucosm") }, + ], + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + // gov + + it("works for MsgDeposit", () => { + const msg: MsgDeposit = { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposalId: Long.fromNumber(5), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.gov.v1beta1.MsgDeposit", + value: msg, + }); + const expected: AminoMsgDeposit = { + type: "cosmos-sdk/MsgDeposit", + value: { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposal_id: "5", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgSubmitProposal", () => { + const msg: MsgSubmitProposal = { + initialDeposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: TextProposal.encode({ + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal", + }).finish(), + }, + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal", + value: msg, + }); + const expected: AminoMsgSubmitProposal = { + type: "cosmos-sdk/MsgSubmitProposal", + value: { + initial_deposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + type: "cosmos-sdk/TextProposal", + value: { + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal", + }, + }, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgVote", () => { + const msg: MsgVote = { + option: VoteOption.VOTE_OPTION_NO_WITH_VETO, + proposalId: Long.fromNumber(5), + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: msg, + }); + const expected: AminoMsgVote = { + type: "cosmos-sdk/MsgVote", + value: { + option: 4, + proposal_id: "5", + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + // distribution + + it("works for MsgFundCommunityPool", async () => { + const msg: MsgFundCommunityPool = { + amount: coins(1234, "ucosm"), + depositor: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgFundCommunityPool", + value: msg, + }); + const expected: AminoMsgFundCommunityPool = { + type: "cosmos-sdk/MsgFundCommunityPool", + value: { + amount: coins(1234, "ucosm"), + depositor: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgSetWithdrawAddress", async () => { + const msg: MsgSetWithdrawAddress = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + withdrawAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + value: msg, + }); + const expected: AminoMsgSetWithdrawAddress = { + type: "cosmos-sdk/MsgModifyWithdrawAddress", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + withdraw_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgWithdrawDelegatorReward", async () => { + const msg: MsgWithdrawDelegatorReward = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: msg, + }); + const expected: AminoMsgWithdrawDelegatorReward = { + type: "cosmos-sdk/MsgWithdrawDelegationReward", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgWithdrawValidatorCommission", async () => { + const msg: MsgWithdrawValidatorCommission = { + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", + value: msg, + }); + const expected: AminoMsgWithdrawValidatorCommission = { + type: "cosmos-sdk/MsgWithdrawValidatorCommission", + value: { + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + // staking + + it("works for MsgBeginRedelegate", () => { + const msg: MsgBeginRedelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorSrcAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validatorDstAddress: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coin(1234, "ucosm"), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate", + value: msg, + }); + const expected: AminoMsgBeginRedelegate = { + type: "cosmos-sdk/MsgBeginRedelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_src_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validator_dst_address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coin(1234, "ucosm"), + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgCreateValidator", () => { + const msg: MsgCreateValidator = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "...", + }, + commission: { + rate: "0.2", + maxRate: "0.3", + maxChangeRate: "0.1", + }, + minSelfDelegation: "123", + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: { + typeUrl: "/cosmos.crypto.secp256k1.PubKey", + value: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"), + }, + value: coin(1234, "ucosm"), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator", + value: msg, + }); + const expected: AminoMsgCreateValidator = { + type: "cosmos-sdk/MsgCreateValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "...", + }, + commission: { + rate: "0.2", + max_rate: "0.3", + max_change_rate: "0.1", + }, + min_self_delegation: "123", + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: encodeBech32Pubkey( + { type: "tendermint/PubKeySecp256k1", value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" }, + "cosmos", + ), + value: coin(1234, "ucosm"), + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgDelegate", () => { + const msg: MsgDelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }); + const expected: AminoMsgDelegate = { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgEditValidator", () => { + const msg: MsgEditValidator = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "...", + }, + commissionRate: "0.2", + minSelfDelegation: "123", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgEditValidator", + value: msg, + }); + const expected: AminoMsgEditValidator = { + type: "cosmos-sdk/MsgEditValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "...", + }, + commission_rate: "0.2", + min_self_delegation: "123", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgUndelegate", () => { + const msg: MsgUndelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: msg, + }); + const expected: AminoMsgUndelegate = { + type: "cosmos-sdk/MsgUndelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + // ibc + + it("works for MsgTransfer", () => { + const msg: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: Long.fromString("123", true), + revisionNumber: Long.fromString("456", true), + }, + timeoutTimestamp: Long.fromString("789", true), + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg, + }); + const expected: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: "123", + revision_number: "456", + }, + timeout_timestamp: "789", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgTransfer with empty values", () => { + const msg: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: Long.UZERO, + revisionNumber: Long.UZERO, + }, + timeoutTimestamp: Long.UZERO, + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg, + }); + const expected: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: undefined, + revision_number: undefined, + }, + timeout_timestamp: undefined, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("works for MsgTransfer with no height timeout", () => { + const msg: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: undefined, + timeoutTimestamp: Long.UZERO, + }; + const aminoMsg = new AminoTypes().toAmino({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: msg, + }); + const expected: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: {}, + timeout_timestamp: undefined, + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + // other + + it("works with custom type url", () => { + const msg = { + foo: "bar", + }; + const aminoMsg = new AminoTypes({ + additions: { + "/my.CustomType": { + aminoType: "my-sdk/CustomType", + toAmino: ({ + foo, + }: { + readonly foo: string; + }): { readonly foo: string; readonly constant: string } => ({ + foo: `amino-prefix-${foo}`, + constant: "something-for-amino", + }), + fromAmino: () => {}, + }, + }, + }).toAmino({ typeUrl: "/my.CustomType", value: msg }); + expect(aminoMsg).toEqual({ + type: "my-sdk/CustomType", + value: { + foo: "amino-prefix-bar", + constant: "something-for-amino", + }, + }); + }); + + it("works with overridden type url", () => { + const msg: MsgDelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }; + const aminoMsg = new AminoTypes({ + additions: { + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "my-override/MsgDelegate", + toAmino: (m: MsgDelegate): { readonly foo: string } => ({ + foo: m.delegatorAddress ?? "", + }), + fromAmino: () => {}, + }, + }, + }).toAmino({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }); + const expected = { + type: "my-override/MsgDelegate", + value: { + foo: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, + }; + expect(aminoMsg).toEqual(expected); + }); + + it("throws for unknown type url", () => { + expect(() => new AminoTypes().toAmino({ typeUrl: "/xxx.Unknown", value: { foo: "bar" } })).toThrowError( + /Type URL does not exist in the Amino message type register./i, + ); + }); + }); + + describe("fromAmino", () => { + // bank + + it("works for MsgSend", () => { + const aminoMsg: AminoMsgSend = { + type: "cosmos-sdk/MsgSend", + value: { + from_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + to_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coins(1234, "ucosm"), + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgSend = { + fromAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + toAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coins(1234, "ucosm"), + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: expectedValue, + }); + }); + + it("works for MsgMultiSend", () => { + const aminoMsg: AminoMsgMultiSend = { + type: "cosmos-sdk/MsgMultiSend", + value: { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: coins(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: coins(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: coins(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: coins(912, "ucosm") }, + ], + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgMultiSend = { + inputs: [ + { address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", coins: coins(1234, "ucosm") }, + { address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", coins: coins(5678, "ucosm") }, + ], + outputs: [ + { address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", coins: coins(6000, "ucosm") }, + { address: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", coins: coins(912, "ucosm") }, + ], + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.bank.v1beta1.MsgMultiSend", + value: expectedValue, + }); + }); + + // gov + + it("works for MsgDeposit", () => { + const aminoMsg: AminoMsgDeposit = { + type: "cosmos-sdk/MsgDeposit", + value: { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposal_id: "5", + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgDeposit = { + amount: [{ amount: "12300000", denom: "ustake" }], + depositor: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + proposalId: Long.fromNumber(5), + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.gov.v1beta1.MsgDeposit", + value: expectedValue, + }); + }); + + it("works for MsgSubmitProposal", () => { + const aminoMsg: AminoMsgSubmitProposal = { + type: "cosmos-sdk/MsgSubmitProposal", + value: { + initial_deposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + type: "cosmos-sdk/TextProposal", + value: { + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal", + }, + }, + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgSubmitProposal = { + initialDeposit: [{ amount: "12300000", denom: "ustake" }], + proposer: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + content: { + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: TextProposal.encode({ + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal", + }).finish(), + }, + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal", + value: expectedValue, + }); + }); + + it("works for MsgVote", () => { + const aminoMsg: AminoMsgVote = { + type: "cosmos-sdk/MsgVote", + value: { + option: 4, + proposal_id: "5", + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgVote = { + option: VoteOption.VOTE_OPTION_NO_WITH_VETO, + proposalId: Long.fromNumber(5), + voter: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: expectedValue, + }); + }); + + // distribution + + // TODO: MsgFundCommunityPool + // TODO: MsgSetWithdrawAddress + // TODO: MsgWithdrawDelegatorReward + // TODO: MsgWithdrawValidatorCommission + + // staking + + it("works for MsgBeginRedelegate", () => { + const aminoMsg: AminoMsgBeginRedelegate = { + type: "cosmos-sdk/MsgBeginRedelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_src_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validator_dst_address: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coin(1234, "ucosm"), + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgBeginRedelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorSrcAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + validatorDstAddress: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + amount: coin(1234, "ucosm"), + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate", + value: expectedValue, + }); + }); + + it("works for MsgCreateValidator", () => { + const aminoMsg: AminoMsgCreateValidator = { + type: "cosmos-sdk/MsgCreateValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "...", + }, + commission: { + rate: "0.2", + max_rate: "0.3", + max_change_rate: "0.1", + }, + min_self_delegation: "123", + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: encodeBech32Pubkey( + { type: "tendermint/PubKeySecp256k1", value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" }, + "cosmos", + ), + value: coin(1234, "ucosm"), + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgCreateValidator = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "...", + }, + commission: { + rate: "0.2", + maxRate: "0.3", + maxChangeRate: "0.1", + }, + minSelfDelegation: "123", + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + pubkey: { + typeUrl: "/cosmos.crypto.secp256k1.PubKey", + value: fromBase64("A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"), + }, + value: coin(1234, "ucosm"), + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator", + value: expectedValue, + }); + }); + + it("works for MsgDelegate", () => { + const aminoMsg: AminoMsgDelegate = { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgDelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: expectedValue, + }); + }); + + it("works for MsgEditValidator", () => { + const aminoMsg: AminoMsgEditValidator = { + type: "cosmos-sdk/MsgEditValidator", + value: { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + security_contact: "Hamburglar", + details: "...", + }, + commission_rate: "0.2", + min_self_delegation: "123", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgEditValidator = { + description: { + moniker: "validator", + identity: "me", + website: "valid.com", + securityContact: "Hamburglar", + details: "...", + }, + commissionRate: "0.2", + minSelfDelegation: "123", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgEditValidator", + value: expectedValue, + }); + }); + + it("works for MsgUndelegate", () => { + const aminoMsg: AminoMsgUndelegate = { + type: "cosmos-sdk/MsgUndelegate", + value: { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgUndelegate = { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }; + expect(msg).toEqual({ + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: expectedValue, + }); + }); + + // ibc + + it("works for MsgTransfer", () => { + const aminoMsg: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + revision_height: "123", + revision_number: "456", + }, + timeout_timestamp: "789", + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: Long.fromString("123", true), + revisionNumber: Long.fromString("456", true), + }, + timeoutTimestamp: Long.fromString("789", true), + }; + expect(msg).toEqual({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: expectedValue, + }); + }); + + it("works for MsgTransfer with default values", () => { + const aminoMsg: AminoMsgTransfer = { + type: "cosmos-sdk/MsgTransfer", + value: { + source_port: "testport", + source_channel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeout_height: { + // revision_height omitted + // revision_number omitted + }, + // timeout_timestamp omitted + }, + }; + const msg = new AminoTypes().fromAmino(aminoMsg); + const expectedValue: MsgTransfer = { + sourcePort: "testport", + sourceChannel: "testchannel", + token: coin(1234, "utest"), + sender: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + receiver: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + timeoutHeight: { + revisionHeight: Long.UZERO, + revisionNumber: Long.UZERO, + }, + timeoutTimestamp: Long.UZERO, + }; + expect(msg).toEqual({ + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: expectedValue, + }); + }); + + // other + + it("works for custom type url", () => { + const aminoMsg = { + type: "my-sdk/CustomType", + value: { + foo: "amino-prefix-bar", + constant: "something-for-amino", + }, + }; + const msg = new AminoTypes({ + additions: { + "/my.CustomType": { + aminoType: "my-sdk/CustomType", + toAmino: () => {}, + fromAmino: ({ foo }: { readonly foo: string; readonly constant: string }): any => ({ + foo: foo.slice(13), + }), + }, + }, + }).fromAmino(aminoMsg); + const expectedValue = { + foo: "bar", + }; + expect(msg).toEqual({ + typeUrl: "/my.CustomType", + value: expectedValue, + }); + }); + + it("works with overridden type url", () => { + const msg = new AminoTypes({ + additions: { + "/my.OverrideType": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: () => {}, + fromAmino: ({ foo }: { readonly foo: string }): MsgDelegate => ({ + delegatorAddress: foo, + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }), + }, + }, + }).fromAmino({ + type: "cosmos-sdk/MsgDelegate", + value: { + foo: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + }, + }); + const expected: { readonly typeUrl: "/my.OverrideType"; readonly value: MsgDelegate } = { + typeUrl: "/my.OverrideType", + value: { + delegatorAddress: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validatorAddress: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + amount: coin(1234, "ucosm"), + }, + }; + expect(msg).toEqual(expected); + }); + + it("throws for unknown type url", () => { + expect(() => + new AminoTypes().fromAmino({ type: "cosmos-sdk/MsgUnknown", value: { foo: "bar" } }), + ).toThrowError(/Type does not exist in the Amino message type register./i); + }); + }); +}); diff --git a/src/aminotypes.ts b/src/aminotypes.ts new file mode 100644 index 0000000..01661f7 --- /dev/null +++ b/src/aminotypes.ts @@ -0,0 +1,568 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { AminoMsg, decodeBech32Pubkey, encodeBech32Pubkey } from "@cosmjs/amino"; +import { fromBase64, toBase64 } from "@cosmjs/encoding"; +import { EncodeObject } from "@cosmjs/proto-signing"; +import { assert, assertDefinedAndNotNull, isNonNullObject } from "@cosmjs/utils"; +import { MsgMultiSend, MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; +import { + MsgFundCommunityPool, + MsgSetWithdrawAddress, + MsgWithdrawDelegatorReward, + MsgWithdrawValidatorCommission, +} from "cosmjs-types/cosmos/distribution/v1beta1/tx"; +import { TextProposal, voteOptionFromJSON } from "cosmjs-types/cosmos/gov/v1beta1/gov"; +import { MsgDeposit, MsgSubmitProposal, MsgVote } from "cosmjs-types/cosmos/gov/v1beta1/tx"; +import { + MsgBeginRedelegate, + MsgCreateValidator, + MsgDelegate, + MsgEditValidator, + MsgUndelegate, +} from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import { Any } from "cosmjs-types/google/protobuf/any"; +import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx"; +import Long from "long"; + +import { + AminoMsgBeginRedelegate, + AminoMsgCreateValidator, + AminoMsgDelegate, + AminoMsgDeposit, + AminoMsgEditValidator, + AminoMsgFundCommunityPool, + AminoMsgMultiSend, + AminoMsgSend, + AminoMsgSetWithdrawAddress, + AminoMsgSubmitProposal, + AminoMsgTransfer, + AminoMsgUndelegate, + AminoMsgVote, + AminoMsgWithdrawDelegatorReward, + AminoMsgWithdrawValidatorCommission, +} from "./aminomsgs"; + +export interface AminoConverter { + readonly aminoType: string; + readonly toAmino: (value: any) => any; + readonly fromAmino: (value: any) => any; +} + +function omitDefault(input: T): T | undefined { + if (typeof input === "string") { + return input === "" ? undefined : input; + } + + if (typeof input === "number") { + return input === 0 ? undefined : input; + } + + if (Long.isLong(input)) { + return input.isZero() ? undefined : input; + } + + throw new Error(`Got unsupported type '${typeof input}'`); +} + +function createDefaultTypes(prefix: string): Record { + return { + // bank + + "/cosmos.bank.v1beta1.MsgSend": { + aminoType: "cosmos-sdk/MsgSend", + toAmino: ({ fromAddress, toAddress, amount }: MsgSend): AminoMsgSend["value"] => ({ + from_address: fromAddress, + to_address: toAddress, + amount: [...amount], + }), + fromAmino: ({ from_address, to_address, amount }: AminoMsgSend["value"]): MsgSend => ({ + fromAddress: from_address, + toAddress: to_address, + amount: [...amount], + }), + }, + "/cosmos.bank.v1beta1.MsgMultiSend": { + aminoType: "cosmos-sdk/MsgMultiSend", + toAmino: ({ inputs, outputs }: MsgMultiSend): AminoMsgMultiSend["value"] => ({ + inputs: inputs.map((input) => ({ + address: input.address, + coins: [...input.coins], + })), + outputs: outputs.map((output) => ({ + address: output.address, + coins: [...output.coins], + })), + }), + fromAmino: ({ inputs, outputs }: AminoMsgMultiSend["value"]): MsgMultiSend => ({ + inputs: inputs.map((input) => ({ + address: input.address, + coins: [...input.coins], + })), + outputs: outputs.map((output) => ({ + address: output.address, + coins: [...output.coins], + })), + }), + }, + + // distribution + + "/cosmos.distribution.v1beta1.MsgFundCommunityPool": { + aminoType: "cosmos-sdk/MsgFundCommunityPool", + toAmino: ({ amount, depositor }: MsgFundCommunityPool): AminoMsgFundCommunityPool["value"] => ({ + amount: [...amount], + depositor: depositor, + }), + fromAmino: ({ amount, depositor }: AminoMsgFundCommunityPool["value"]): MsgFundCommunityPool => ({ + amount: [...amount], + depositor: depositor, + }), + }, + "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress": { + aminoType: "cosmos-sdk/MsgModifyWithdrawAddress", + toAmino: ({ + delegatorAddress, + withdrawAddress, + }: MsgSetWithdrawAddress): AminoMsgSetWithdrawAddress["value"] => ({ + delegator_address: delegatorAddress, + withdraw_address: withdrawAddress, + }), + fromAmino: ({ + delegator_address, + withdraw_address, + }: AminoMsgSetWithdrawAddress["value"]): MsgSetWithdrawAddress => ({ + delegatorAddress: delegator_address, + withdrawAddress: withdraw_address, + }), + }, + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward": { + aminoType: "cosmos-sdk/MsgWithdrawDelegationReward", + toAmino: ({ + delegatorAddress, + validatorAddress, + }: MsgWithdrawDelegatorReward): AminoMsgWithdrawDelegatorReward["value"] => ({ + delegator_address: delegatorAddress, + validator_address: validatorAddress, + }), + fromAmino: ({ + delegator_address, + validator_address, + }: AminoMsgWithdrawDelegatorReward["value"]): MsgWithdrawDelegatorReward => ({ + delegatorAddress: delegator_address, + validatorAddress: validator_address, + }), + }, + "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission": { + aminoType: "cosmos-sdk/MsgWithdrawValidatorCommission", + toAmino: ({ + validatorAddress, + }: MsgWithdrawValidatorCommission): AminoMsgWithdrawValidatorCommission["value"] => ({ + validator_address: validatorAddress, + }), + fromAmino: ({ + validator_address, + }: AminoMsgWithdrawValidatorCommission["value"]): MsgWithdrawValidatorCommission => ({ + validatorAddress: validator_address, + }), + }, + + // gov + + "/cosmos.gov.v1beta1.MsgDeposit": { + aminoType: "cosmos-sdk/MsgDeposit", + toAmino: ({ amount, depositor, proposalId }: MsgDeposit): AminoMsgDeposit["value"] => { + return { + amount, + depositor, + proposal_id: proposalId.toString(), + }; + }, + fromAmino: ({ amount, depositor, proposal_id }: AminoMsgDeposit["value"]): MsgDeposit => { + return { + amount: Array.from(amount), + depositor, + proposalId: Long.fromString(proposal_id), + }; + }, + }, + "/cosmos.gov.v1beta1.MsgVote": { + aminoType: "cosmos-sdk/MsgVote", + toAmino: ({ option, proposalId, voter }: MsgVote): AminoMsgVote["value"] => { + return { + option: option, + proposal_id: proposalId.toString(), + voter: voter, + }; + }, + fromAmino: ({ option, proposal_id, voter }: AminoMsgVote["value"]): MsgVote => { + return { + option: voteOptionFromJSON(option), + proposalId: Long.fromString(proposal_id), + voter: voter, + }; + }, + }, + "/cosmos.gov.v1beta1.MsgSubmitProposal": { + aminoType: "cosmos-sdk/MsgSubmitProposal", + toAmino: ({ + initialDeposit, + proposer, + content, + }: MsgSubmitProposal): AminoMsgSubmitProposal["value"] => { + assertDefinedAndNotNull(content); + let proposal: any; + switch (content.typeUrl) { + case "/cosmos.gov.v1beta1.TextProposal": { + const textProposal = TextProposal.decode(content.value); + proposal = { + type: "cosmos-sdk/TextProposal", + value: { + description: textProposal.description, + title: textProposal.title, + }, + }; + break; + } + default: + throw new Error(`Unsupported proposal type: '${content.typeUrl}'`); + } + return { + initial_deposit: initialDeposit, + proposer: proposer, + content: proposal, + }; + }, + fromAmino: ({ + initial_deposit, + proposer, + content, + }: AminoMsgSubmitProposal["value"]): MsgSubmitProposal => { + let any_content: Any; + switch (content.type) { + case "cosmos-sdk/TextProposal": { + const { value } = content; + assert(isNonNullObject(value)); + const { title, description } = value as any; + assert(typeof title === "string"); + assert(typeof description === "string"); + any_content = Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: TextProposal.encode( + TextProposal.fromPartial({ + title: title, + description: description, + }), + ).finish(), + }); + break; + } + default: + throw new Error(`Unsupported proposal type: '${content.type}'`); + } + return { + initialDeposit: Array.from(initial_deposit), + proposer: proposer, + content: any_content, + }; + }, + }, + + // staking + + "/cosmos.staking.v1beta1.MsgBeginRedelegate": { + aminoType: "cosmos-sdk/MsgBeginRedelegate", + toAmino: ({ + delegatorAddress, + validatorSrcAddress, + validatorDstAddress, + amount, + }: MsgBeginRedelegate): AminoMsgBeginRedelegate["value"] => { + assertDefinedAndNotNull(amount, "missing amount"); + return { + delegator_address: delegatorAddress, + validator_src_address: validatorSrcAddress, + validator_dst_address: validatorDstAddress, + amount: amount, + }; + }, + fromAmino: ({ + delegator_address, + validator_src_address, + validator_dst_address, + amount, + }: AminoMsgBeginRedelegate["value"]): MsgBeginRedelegate => ({ + delegatorAddress: delegator_address, + validatorSrcAddress: validator_src_address, + validatorDstAddress: validator_dst_address, + amount: amount, + }), + }, + "/cosmos.staking.v1beta1.MsgCreateValidator": { + aminoType: "cosmos-sdk/MsgCreateValidator", + toAmino: ({ + description, + commission, + minSelfDelegation, + delegatorAddress, + validatorAddress, + pubkey, + value, + }: MsgCreateValidator): AminoMsgCreateValidator["value"] => { + assertDefinedAndNotNull(description, "missing description"); + assertDefinedAndNotNull(commission, "missing commission"); + assertDefinedAndNotNull(pubkey, "missing pubkey"); + assertDefinedAndNotNull(value, "missing value"); + return { + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + security_contact: description.securityContact, + details: description.details, + }, + commission: { + rate: commission.rate, + max_rate: commission.maxRate, + max_change_rate: commission.maxChangeRate, + }, + min_self_delegation: minSelfDelegation, + delegator_address: delegatorAddress, + validator_address: validatorAddress, + pubkey: encodeBech32Pubkey( + { + type: "tendermint/PubKeySecp256k1", + value: toBase64(pubkey.value), + }, + prefix, + ), + value: value, + }; + }, + fromAmino: ({ + description, + commission, + min_self_delegation, + delegator_address, + validator_address, + pubkey, + value, + }: AminoMsgCreateValidator["value"]): MsgCreateValidator => { + const decodedPubkey = decodeBech32Pubkey(pubkey); + if (decodedPubkey.type !== "tendermint/PubKeySecp256k1") { + throw new Error("Only Secp256k1 public keys are supported"); + } + return { + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + securityContact: description.security_contact, + details: description.details, + }, + commission: { + rate: commission.rate, + maxRate: commission.max_rate, + maxChangeRate: commission.max_change_rate, + }, + minSelfDelegation: min_self_delegation, + delegatorAddress: delegator_address, + validatorAddress: validator_address, + pubkey: { + typeUrl: "/cosmos.crypto.secp256k1.PubKey", + value: fromBase64(decodedPubkey.value), + }, + value: value, + }; + }, + }, + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: ({ delegatorAddress, validatorAddress, amount }: MsgDelegate): AminoMsgDelegate["value"] => { + assertDefinedAndNotNull(amount, "missing amount"); + return { + delegator_address: delegatorAddress, + validator_address: validatorAddress, + amount: amount, + }; + }, + fromAmino: ({ + delegator_address, + validator_address, + amount, + }: AminoMsgDelegate["value"]): MsgDelegate => ({ + delegatorAddress: delegator_address, + validatorAddress: validator_address, + amount: amount, + }), + }, + "/cosmos.staking.v1beta1.MsgEditValidator": { + aminoType: "cosmos-sdk/MsgEditValidator", + toAmino: ({ + description, + commissionRate, + minSelfDelegation, + validatorAddress, + }: MsgEditValidator): AminoMsgEditValidator["value"] => { + assertDefinedAndNotNull(description, "missing description"); + return { + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + security_contact: description.securityContact, + details: description.details, + }, + commission_rate: commissionRate, + min_self_delegation: minSelfDelegation, + validator_address: validatorAddress, + }; + }, + fromAmino: ({ + description, + commission_rate, + min_self_delegation, + validator_address, + }: AminoMsgEditValidator["value"]): MsgEditValidator => ({ + description: { + moniker: description.moniker, + identity: description.identity, + website: description.website, + securityContact: description.security_contact, + details: description.details, + }, + commissionRate: commission_rate, + minSelfDelegation: min_self_delegation, + validatorAddress: validator_address, + }), + }, + "/cosmos.staking.v1beta1.MsgUndelegate": { + aminoType: "cosmos-sdk/MsgUndelegate", + toAmino: ({ + delegatorAddress, + validatorAddress, + amount, + }: MsgUndelegate): AminoMsgUndelegate["value"] => { + assertDefinedAndNotNull(amount, "missing amount"); + return { + delegator_address: delegatorAddress, + validator_address: validatorAddress, + amount: amount, + }; + }, + fromAmino: ({ + delegator_address, + validator_address, + amount, + }: AminoMsgUndelegate["value"]): MsgUndelegate => ({ + delegatorAddress: delegator_address, + validatorAddress: validator_address, + amount: amount, + }), + }, + + // ibc + + "/ibc.applications.transfer.v1.MsgTransfer": { + aminoType: "cosmos-sdk/MsgTransfer", + toAmino: ({ + sourcePort, + sourceChannel, + token, + sender, + receiver, + timeoutHeight, + timeoutTimestamp, + }: MsgTransfer): AminoMsgTransfer["value"] => ({ + source_port: sourcePort, + source_channel: sourceChannel, + token: token, + sender: sender, + receiver: receiver, + timeout_height: timeoutHeight + ? { + revision_height: omitDefault(timeoutHeight.revisionHeight)?.toString(), + revision_number: omitDefault(timeoutHeight.revisionNumber)?.toString(), + } + : {}, + timeout_timestamp: omitDefault(timeoutTimestamp)?.toString(), + }), + fromAmino: ({ + source_port, + source_channel, + token, + sender, + receiver, + timeout_height, + timeout_timestamp, + }: AminoMsgTransfer["value"]): MsgTransfer => ({ + sourcePort: source_port, + sourceChannel: source_channel, + token: token, + sender: sender, + receiver: receiver, + timeoutHeight: timeout_height + ? { + revisionHeight: Long.fromString(timeout_height.revision_height || "0", true), + revisionNumber: Long.fromString(timeout_height.revision_number || "0", true), + } + : undefined, + timeoutTimestamp: Long.fromString(timeout_timestamp || "0", true), + }), + }, + }; +} + +interface AminoTypesOptions { + readonly additions?: Record; + readonly prefix?: string; +} + +/** + * A map from Stargate message types as used in the messages's `Any` type + * to Amino types. + */ +export class AminoTypes { + private readonly register: Record; + + public constructor({ additions = {}, prefix = "cosmos" }: AminoTypesOptions = {}) { + const additionalAminoTypes = Object.values(additions); + const filteredDefaultTypes = Object.entries(createDefaultTypes(prefix)).reduce( + (acc, [key, value]) => + additionalAminoTypes.find(({ aminoType }) => value.aminoType === aminoType) + ? acc + : { ...acc, [key]: value }, + {}, + ); + this.register = { ...filteredDefaultTypes, ...additions }; + } + + public toAmino({ typeUrl, value }: EncodeObject): AminoMsg { + const converter = this.register[typeUrl]; + if (!converter) { + throw new Error( + "Type URL does not exist in the Amino message type register. " + + "If you need support for this message type, you can pass in additional entries to the AminoTypes constructor. " + + "If you think this message type should be included by default, please open an issue at https://github.com/cosmos/cosmjs/issues.", + ); + } + return { + type: converter.aminoType, + value: converter.toAmino(value), + }; + } + + public fromAmino({ type, value }: AminoMsg): EncodeObject { + const result = Object.entries(this.register).find(([_typeUrl, { aminoType }]) => aminoType === type); + if (!result) { + throw new Error( + "Type does not exist in the Amino message type register. " + + "If you need support for this message type, you can pass in additional entries to the AminoTypes constructor. " + + "If you think this message type should be included by default, please open an issue at https://github.com/cosmos/cosmjs/issues.", + ); + } + const [typeUrl, converter] = result; + return { + typeUrl: typeUrl, + value: converter.fromAmino(value), + }; + } +} diff --git a/src/encodeobjects.ts b/src/encodeobjects.ts new file mode 100644 index 0000000..8572e2a --- /dev/null +++ b/src/encodeobjects.ts @@ -0,0 +1,93 @@ +import { EncodeObject } from "@cosmjs/proto-signing"; +import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; +import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx"; +import { MsgDeposit, MsgSubmitProposal, MsgVote } from "cosmjs-types/cosmos/gov/v1beta1/tx"; +import { MsgDelegate, MsgUndelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx"; + +export interface MsgSendEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.bank.v1beta1.MsgSend"; + readonly value: Partial; +} + +export function isMsgSendEncodeObject(encodeObject: EncodeObject): encodeObject is MsgSendEncodeObject { + return (encodeObject as MsgSendEncodeObject).typeUrl === "/cosmos.bank.v1beta1.MsgSend"; +} + +export interface MsgDelegateEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.staking.v1beta1.MsgDelegate"; + readonly value: Partial; +} + +export function isMsgDelegateEncodeObject( + encodeObject: EncodeObject, +): encodeObject is MsgDelegateEncodeObject { + return (encodeObject as MsgDelegateEncodeObject).typeUrl === "/cosmos.staking.v1beta1.MsgDelegate"; +} + +export interface MsgUndelegateEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate"; + readonly value: Partial; +} + +export function isMsgUndelegateEncodeObject( + encodeObject: EncodeObject, +): encodeObject is MsgUndelegateEncodeObject { + return (encodeObject as MsgUndelegateEncodeObject).typeUrl === "/cosmos.staking.v1beta1.MsgUndelegate"; +} + +export interface MsgWithdrawDelegatorRewardEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"; + readonly value: Partial; +} + +export function isMsgWithdrawDelegatorRewardEncodeObject( + encodeObject: EncodeObject, +): encodeObject is MsgWithdrawDelegatorRewardEncodeObject { + return ( + (encodeObject as MsgWithdrawDelegatorRewardEncodeObject).typeUrl === + "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward" + ); +} + +export interface MsgTransferEncodeObject extends EncodeObject { + readonly typeUrl: "/ibc.applications.transfer.v1.MsgTransfer"; + readonly value: Partial; +} + +export function isMsgTransferEncodeObject( + encodeObject: EncodeObject, +): encodeObject is MsgTransferEncodeObject { + return (encodeObject as MsgTransferEncodeObject).typeUrl === "/ibc.applications.transfer.v1.MsgTransfer"; +} + +export interface MsgDepositEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.gov.v1beta1.MsgDeposit"; + readonly value: Partial; +} + +export function isMsgDepositEncodeObject( + encodeObject: EncodeObject, +): encodeObject is MsgSubmitProposalEncodeObject { + return (encodeObject as MsgDepositEncodeObject).typeUrl === "/cosmos.gov.v1beta1.MsgDeposit"; +} + +export interface MsgSubmitProposalEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal"; + readonly value: Partial; +} + +export function isMsgSubmitProposalEncodeObject( + encodeObject: EncodeObject, +): encodeObject is MsgSubmitProposalEncodeObject { + return (encodeObject as MsgSubmitProposalEncodeObject).typeUrl === "/cosmos.gov.v1beta1.MsgSubmitProposal"; +} + +export interface MsgVoteEncodeObject extends EncodeObject { + readonly typeUrl: "/cosmos.gov.v1beta1.MsgVote"; + readonly value: Partial; +} + +export function isMsgVoteEncodeObject(encodeObject: EncodeObject): encodeObject is MsgVoteEncodeObject { + return (encodeObject as MsgVoteEncodeObject).typeUrl === "/cosmos.gov.v1beta1.MsgVote"; +} diff --git a/src/fee.spec.ts b/src/fee.spec.ts new file mode 100644 index 0000000..4389704 --- /dev/null +++ b/src/fee.spec.ts @@ -0,0 +1,83 @@ +import { Decimal } from "@cosmjs/math"; + +import { calculateFee, GasPrice } from "./fee"; + +describe("GasPrice", () => { + it("can be constructed", () => { + const inputs = ["3.14", "3", "0.14"]; + inputs.forEach((input) => { + const gasPrice = new GasPrice(Decimal.fromUserInput(input, 18), "utest"); + expect(gasPrice.amount.toString()).toEqual(input); + expect(gasPrice.denom).toEqual("utest"); + }); + }); + + describe("fromString", () => { + it("works", () => { + const inputs: Record = { + // Test amounts + "3.14utest": { amount: "3.14", denom: "utest" }, + "3utest": { amount: "3", denom: "utest" }, + "0.14utest": { amount: "0.14", denom: "utest" }, + // Test denoms + "0.14sht": { amount: "0.14", denom: "sht" }, + "0.14testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest": + { + amount: "0.14", + denom: + "testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest", + }, + "0.14ucoin2": { amount: "0.14", denom: "ucoin2" }, + // eslint-disable-next-line @typescript-eslint/naming-convention + "0.14FOOBAR": { amount: "0.14", denom: "FOOBAR" }, + }; + for (const [input, expected] of Object.entries(inputs)) { + const gasPrice = GasPrice.fromString(input); + expect(gasPrice.amount.toString()).withContext(`Input: ${input}`).toEqual(expected.amount); + expect(gasPrice.denom).withContext(`Input: ${input}`).toEqual(expected.denom); + } + }); + + it("errors for invalid gas price", () => { + // Checks basic format + expect(() => GasPrice.fromString("")).toThrowError(/Invalid gas price string/i); + expect(() => GasPrice.fromString("utkn")).toThrowError(/Invalid gas price string/i); + expect(() => GasPrice.fromString("@utkn")).toThrowError(/Invalid gas price string/i); + expect(() => GasPrice.fromString("234")).toThrowError(/Invalid gas price string/i); + expect(() => GasPrice.fromString("-234tkn")).toThrowError(/Invalid gas price string/i); + // Checks details of + expect(() => GasPrice.fromString("234t")).toThrowError(/denom must be between 3 and 128 characters/i); + expect(() => GasPrice.fromString("234tt")).toThrowError(/denom must be between 3 and 128 characters/i); + expect(() => + GasPrice.fromString( + "234ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", + ), + ).toThrowError(/denom must be between 3 and 128 characters/i); + // Checks details of + expect(() => GasPrice.fromString("3.utkn")).toThrowError(/Fractional part missing/i); + expect(() => GasPrice.fromString("..utkn")).toThrowError(/More than one separator found/i); + }); + }); +}); + +describe("calculateFee", () => { + it("multiplies the gas price by the gas limit", () => { + const gasLimit = 80000; + const gasPrice = GasPrice.fromString("0.025ucosm"); + const fee = calculateFee(gasLimit, gasPrice); + expect(fee).toEqual({ + amount: [{ amount: "2000", denom: "ucosm" }], + gas: "80000", + }); + }); + + it("accepts a string gas price", () => { + const gasLimit = 80000; + const gasPrice = "0.025ucosm"; + const fee = calculateFee(gasLimit, gasPrice); + expect(fee).toEqual({ + amount: [{ amount: "2000", denom: "ucosm" }], + gas: "80000", + }); + }); +}); diff --git a/src/fee.ts b/src/fee.ts new file mode 100644 index 0000000..f8b4059 --- /dev/null +++ b/src/fee.ts @@ -0,0 +1,62 @@ +import { StdFee } from "@cosmjs/amino"; +import { Decimal, Uint53 } from "@cosmjs/math"; +import { coins } from "@cosmjs/proto-signing"; + +/** + * Denom checker for the Cosmos SDK 0.42 denom pattern + * (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601). + * + * This is like a regexp but with helpful error messages. + */ +function checkDenom(denom: string): void { + if (denom.length < 3 || denom.length > 128) { + throw new Error("Denom must be between 3 and 128 characters"); + } +} + +/** + * A gas price, i.e. the price of a single unit of gas. This is typically a fraction of + * the smallest fee token unit, such as 0.012utoken. + * + * This is the same as GasPrice from @cosmjs/launchpad but those might diverge in the future. + */ +export class GasPrice { + public readonly amount: Decimal; + public readonly denom: string; + + public constructor(amount: Decimal, denom: string) { + this.amount = amount; + this.denom = denom; + } + + /** + * Parses a gas price formatted as ``, e.g. `GasPrice.fromString("0.012utoken")`. + * + * The denom must match the Cosmos SDK 0.42 pattern (https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/types/coin.go#L599-L601). + * See `GasPrice` in @cosmjs/stargate for a more generic matcher. + * + * Separators are not yet supported. + */ + public static fromString(gasPrice: string): GasPrice { + // Use Decimal.fromUserInput and checkDenom for detailed checks and helpful error messages + const matchResult = gasPrice.match(/^([0-9.]+)([a-z][a-z0-9]*)$/i); + if (!matchResult) { + throw new Error("Invalid gas price string"); + } + const [_, amount, denom] = matchResult; + checkDenom(denom); + const fractionalDigits = 18; + const decimalAmount = Decimal.fromUserInput(amount, fractionalDigits); + return new GasPrice(decimalAmount, denom); + } +} + +export function calculateFee(gasLimit: number, gasPrice: GasPrice | string): StdFee { + const processedGasPrice = typeof gasPrice === "string" ? GasPrice.fromString(gasPrice) : gasPrice; + const { denom, amount: gasPriceAmount } = processedGasPrice; + const amount = Math.ceil(gasPriceAmount.multiply(new Uint53(gasLimit)).toFloatApproximation()); + return { + amount: coins(amount, denom), + gas: gasLimit.toString(), + }; +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..c9a633a --- /dev/null +++ b/src/index.ts @@ -0,0 +1,116 @@ +export { Account, accountFromAny } from "./accounts"; +export { + AminoMsgBeginRedelegate, + AminoMsgCreateValidator, + AminoMsgDelegate, + AminoMsgDeposit, + AminoMsgEditValidator, + AminoMsgFundCommunityPool, + AminoMsgMultiSend, + AminoMsgSend, + AminoMsgSetWithdrawAddress, + AminoMsgSubmitEvidence, + AminoMsgSubmitProposal, + AminoMsgUndelegate, + AminoMsgUnjail, + AminoMsgVerifyInvariant, + AminoMsgVote, + AminoMsgWithdrawDelegatorReward, + AminoMsgWithdrawValidatorCommission, + isAminoMsgBeginRedelegate, + isAminoMsgCreateValidator, + isAminoMsgDelegate, + isAminoMsgDeposit, + isAminoMsgEditValidator, + isAminoMsgFundCommunityPool, + isAminoMsgMultiSend, + isAminoMsgSend, + isAminoMsgSetWithdrawAddress, + isAminoMsgSubmitEvidence, + isAminoMsgSubmitProposal, + isAminoMsgUndelegate, + isAminoMsgUnjail, + isAminoMsgVerifyInvariant, + isAminoMsgVote, + isAminoMsgWithdrawDelegatorReward, + isAminoMsgWithdrawValidatorCommission, +} from "./aminomsgs"; +export { AminoConverter, AminoTypes } from "./aminotypes"; +export { + isMsgDelegateEncodeObject, + isMsgDepositEncodeObject, + isMsgSendEncodeObject, + isMsgSubmitProposalEncodeObject, + isMsgTransferEncodeObject, + isMsgUndelegateEncodeObject, + isMsgVoteEncodeObject, + isMsgWithdrawDelegatorRewardEncodeObject, + MsgDelegateEncodeObject, + MsgDepositEncodeObject, + MsgSendEncodeObject, + MsgSubmitProposalEncodeObject, + MsgTransferEncodeObject, + MsgUndelegateEncodeObject, + MsgVoteEncodeObject, + MsgWithdrawDelegatorRewardEncodeObject, +} from "./encodeobjects"; +export { calculateFee, GasPrice } from "./fee"; +export * as logs from "./logs"; +export { makeMultisignedTx } from "./multisignature"; +export { + AuthExtension, + BankExtension, + createPagination, + createProtobufRpcClient, + decodeCosmosSdkDecFromProto, + DistributionExtension, + GovExtension, + GovParamsType, + GovProposalId, + IbcExtension, + MintExtension, + MintParams, + ProtobufRpcClient, + QueryClient, + setupAuthExtension, + setupBankExtension, + setupDistributionExtension, + setupGovExtension, + setupIbcExtension, + setupMintExtension, + setupStakingExtension, + setupTxExtension, + StakingExtension, + TxExtension, +} from "./queries"; +export { + isSearchByHeightQuery, + isSearchBySentFromOrToQuery, + isSearchByTagsQuery, + SearchByHeightQuery, + SearchBySentFromOrToQuery, + SearchByTagsQuery, + SearchTxFilter, + SearchTxQuery, +} from "./search"; +export { + defaultRegistryTypes, + SignerData, + SigningStargateClient, + SigningStargateClientOptions, +} from "./signingstargateclient"; +export { + assertIsDeliverTxFailure, + assertIsDeliverTxSuccess, + Block, + BlockHeader, + DeliverTxResponse, + IndexedTx, + isDeliverTxFailure, + isDeliverTxSuccess, + SequenceResponse, + StargateClient, + TimeoutError, +} from "./stargateclient"; +export { StdFee } from "@cosmjs/amino"; +export { Coin, coin, coins, makeCosmoshubPath, parseCoins } from "@cosmjs/proto-signing"; diff --git a/src/logs.ts b/src/logs.ts new file mode 100644 index 0000000..91be910 --- /dev/null +++ b/src/logs.ts @@ -0,0 +1,91 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { isNonNullObject } from "@cosmjs/utils"; + +export interface Attribute { + readonly key: string; + readonly value: string; +} + +export interface Event { + readonly type: string; + readonly attributes: readonly Attribute[]; +} + +export interface Log { + readonly msg_index: number; + readonly log: string; + readonly events: readonly Event[]; +} + +export function parseAttribute(input: unknown): Attribute { + if (!isNonNullObject(input)) throw new Error("Attribute must be a non-null object"); + const { key, value } = input as any; + if (typeof key !== "string" || !key) throw new Error("Attribute's key must be a non-empty string"); + if (typeof value !== "string" && typeof value !== "undefined") { + throw new Error("Attribute's value must be a string or unset"); + } + + return { + key: key, + value: value || "", + }; +} + +export function parseEvent(input: unknown): Event { + if (!isNonNullObject(input)) throw new Error("Event must be a non-null object"); + const { type, attributes } = input as any; + if (typeof type !== "string" || type === "") { + throw new Error(`Event type must be a non-empty string`); + } + if (!Array.isArray(attributes)) throw new Error("Event's attributes must be an array"); + return { + type: type, + attributes: attributes.map(parseAttribute), + }; +} + +export function parseLog(input: unknown): Log { + if (!isNonNullObject(input)) throw new Error("Log must be a non-null object"); + const { msg_index, log, events } = input as any; + if (typeof msg_index !== "number") throw new Error("Log's msg_index must be a number"); + if (typeof log !== "string") throw new Error("Log's log must be a string"); + if (!Array.isArray(events)) throw new Error("Log's events must be an array"); + return { + msg_index: msg_index, + log: log, + events: events.map(parseEvent), + }; +} + +export function parseLogs(input: unknown): readonly Log[] { + if (!Array.isArray(input)) throw new Error("Logs must be an array"); + return input.map(parseLog); +} + +export function parseRawLog(input = "[]"): readonly Log[] { + const logsToParse = JSON.parse(input).map(({ events }: { events: readonly unknown[] }, i: number) => ({ + msg_index: i, + events, + log: "", + })); + return parseLogs(logsToParse); +} + +/** + * Searches in logs for the first event of the given event type and in that event + * for the first first attribute with the given attribute key. + * + * Throws if the attribute was not found. + */ +export function findAttribute(logs: readonly Log[], eventType: string, attrKey: string): Attribute { + const firstLogs = logs.find(() => true); + const out = firstLogs?.events + .find((event) => event.type === eventType) + ?.attributes.find((attr) => attr.key === attrKey); + if (!out) { + throw new Error( + `Could not find attribute '${attrKey}' in first event of type '${eventType}' in first log.`, + ); + } + return out; +} diff --git a/src/multisignature.spec.ts b/src/multisignature.spec.ts new file mode 100644 index 0000000..bf43e01 --- /dev/null +++ b/src/multisignature.spec.ts @@ -0,0 +1,275 @@ +import { + createMultisigThresholdPubkey, + encodeSecp256k1Pubkey, + makeCosmoshubPath, + pubkeyToAddress, + Secp256k1HdWallet, +} from "@cosmjs/amino"; +import { coins } from "@cosmjs/proto-signing"; +import { assert } from "@cosmjs/utils"; +import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; +import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; + +import { MsgSendEncodeObject } from "./encodeobjects"; +import { makeCompactBitArray, makeMultisignedTx } from "./multisignature"; +import { SignerData, SigningStargateClient } from "./signingstargateclient"; +import { assertIsDeliverTxSuccess, StargateClient } from "./stargateclient"; +import { faucet, pendingWithoutSimapp, simapp } from "./testutils.spec"; + +describe("multisignature", () => { + describe("makeCompactBitArray", () => { + it("works for 0 bits of different lengths", () => { + expect(makeCompactBitArray([])).toEqual({ elems: new Uint8Array([]), extraBitsStored: 0 }); + expect(makeCompactBitArray([false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 1, + }); + expect(makeCompactBitArray([false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 2, + }); + expect(makeCompactBitArray([false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 3, + }); + expect(makeCompactBitArray([false, false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 4, + }); + expect(makeCompactBitArray([false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 5, + }); + expect(makeCompactBitArray([false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 6, + }); + expect(makeCompactBitArray([false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 7, + }); + expect(makeCompactBitArray([false, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000]), + extraBitsStored: 0, + }); + expect(makeCompactBitArray([false, false, false, false, false, false, false, false, false])).toEqual({ + elems: new Uint8Array([0b00000000, 0b00000000]), + extraBitsStored: 1, + }); + expect( + makeCompactBitArray([false, false, false, false, false, false, false, false, false, false]), + ).toEqual({ elems: new Uint8Array([0b00000000, 0b00000000]), extraBitsStored: 2 }); + }); + + it("works for 1 bits of different lengths", () => { + expect(makeCompactBitArray([])).toEqual({ elems: new Uint8Array([]), extraBitsStored: 0 }); + expect(makeCompactBitArray([true])).toEqual({ + elems: new Uint8Array([0b10000000]), + extraBitsStored: 1, + }); + expect(makeCompactBitArray([true, true])).toEqual({ + elems: new Uint8Array([0b11000000]), + extraBitsStored: 2, + }); + expect(makeCompactBitArray([true, true, true])).toEqual({ + elems: new Uint8Array([0b11100000]), + extraBitsStored: 3, + }); + expect(makeCompactBitArray([true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11110000]), + extraBitsStored: 4, + }); + expect(makeCompactBitArray([true, true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11111000]), + extraBitsStored: 5, + }); + expect(makeCompactBitArray([true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11111100]), + extraBitsStored: 6, + }); + expect(makeCompactBitArray([true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11111110]), + extraBitsStored: 7, + }); + expect(makeCompactBitArray([true, true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11111111]), + extraBitsStored: 0, + }); + expect(makeCompactBitArray([true, true, true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11111111, 0b10000000]), + extraBitsStored: 1, + }); + expect(makeCompactBitArray([true, true, true, true, true, true, true, true, true, true])).toEqual({ + elems: new Uint8Array([0b11111111, 0b11000000]), + extraBitsStored: 2, + }); + }); + + it("works for 1 bit in different places", () => { + expect( + makeCompactBitArray([true, false, false, false, false, false, false, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b10000000, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, true, false, false, false, false, false, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b01000000, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, true, false, false, false, false, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b00100000, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, true, false, false, false, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b00010000, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, false, true, false, false, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b00001000, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, false, false, true, false, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b00000100, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, false, false, false, true, false, false, false]), + ).toEqual({ + elems: new Uint8Array([0b00000010, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, false, false, false, false, true, false, false]), + ).toEqual({ + elems: new Uint8Array([0b00000001, 0b00000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, false, false, false, false, false, true, false]), + ).toEqual({ + elems: new Uint8Array([0b00000000, 0b10000000]), + extraBitsStored: 2, + }); + expect( + makeCompactBitArray([false, false, false, false, false, false, false, false, false, true]), + ).toEqual({ + elems: new Uint8Array([0b00000000, 0b01000000]), + extraBitsStored: 2, + }); + }); + }); + + describe("makeMultisignedTx", () => { + it("works", async () => { + pendingWithoutSimapp(); + const multisigAccountAddress = "cosmos1h90ml36rcu7yegwduzgzderj2jmq49hcpfclw9"; + + // On the composer's machine signing instructions are created. + // The composer does not need to be one of the signers. + const signingInstruction = await (async () => { + const client = await StargateClient.connect(simapp.tendermintUrl); + const accountOnChain = await client.getAccount(multisigAccountAddress); + assert(accountOnChain, "Account does not exist on chain"); + + const msgSend: MsgSend = { + fromAddress: multisigAccountAddress, + toAddress: "cosmos19rvl6ja9h0erq9dc2xxfdzypc739ej8k5esnhg", + amount: coins(1234, "ucosm"), + }; + const msg: MsgSendEncodeObject = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msgSend, + }; + const gasLimit = 200000; + const fee = { + amount: coins(2000, "ucosm"), + gas: gasLimit.toString(), + }; + + return { + accountNumber: accountOnChain.accountNumber, + sequence: accountOnChain.sequence, + chainId: await client.getChainId(), + msgs: [msg], + fee: fee, + memo: "Use your tokens wisely", + }; + })(); + + const [ + [pubkey0, signature0, bodyBytes], + [pubkey1, signature1], + [pubkey2, signature2], + [pubkey3, signature3], + [pubkey4, signature4], + ] = await Promise.all( + [0, 1, 2, 3, 4].map(async (i) => { + // Signing environment + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic, { + hdPaths: [makeCosmoshubPath(i)], + }); + const pubkey = encodeSecp256k1Pubkey((await wallet.getAccounts())[0].pubkey); + const address = (await wallet.getAccounts())[0].address; + const signingClient = await SigningStargateClient.offline(wallet); + const signerData: SignerData = { + accountNumber: signingInstruction.accountNumber, + sequence: signingInstruction.sequence, + chainId: signingInstruction.chainId, + }; + const { bodyBytes: bb, signatures } = await signingClient.sign( + address, + signingInstruction.msgs, + signingInstruction.fee, + signingInstruction.memo, + signerData, + ); + return [pubkey, signatures[0], bb] as const; + }), + ); + + // From here on, no private keys are required anymore. Any anonymous entity + // can collect, assemble and broadcast. + { + const multisigPubkey = createMultisigThresholdPubkey( + [pubkey0, pubkey1, pubkey2, pubkey3, pubkey4], + 2, + ); + expect(pubkeyToAddress(multisigPubkey, "cosmos")).toEqual(multisigAccountAddress); + + const address0 = pubkeyToAddress(pubkey0, "cosmos"); + const address1 = pubkeyToAddress(pubkey1, "cosmos"); + const address2 = pubkeyToAddress(pubkey2, "cosmos"); + const address3 = pubkeyToAddress(pubkey3, "cosmos"); + const address4 = pubkeyToAddress(pubkey4, "cosmos"); + + const broadcaster = await StargateClient.connect(simapp.tendermintUrl); + const signedTx = makeMultisignedTx( + multisigPubkey, + signingInstruction.sequence, + signingInstruction.fee, + bodyBytes, + new Map([ + [address0, signature0], + [address1, signature1], + [address2, signature2], + [address3, signature3], + [address4, signature4], + ]), + ); + // ensure signature is valid + const result = await broadcaster.broadcastTx(Uint8Array.from(TxRaw.encode(signedTx).finish())); + assertIsDeliverTxSuccess(result); + } + }); + }); +}); diff --git a/src/multisignature.ts b/src/multisignature.ts new file mode 100644 index 0000000..2a71220 --- /dev/null +++ b/src/multisignature.ts @@ -0,0 +1,72 @@ +import { MultisigThresholdPubkey, pubkeyToAddress, StdFee } from "@cosmjs/amino"; +import { Bech32 } from "@cosmjs/encoding"; +import { encodePubkey } from "@cosmjs/proto-signing"; +import { CompactBitArray, MultiSignature } from "cosmjs-types/cosmos/crypto/multisig/v1beta1/multisig"; +import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; +import { AuthInfo, SignerInfo } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import Long from "long"; + +export function makeCompactBitArray(bits: readonly boolean[]): CompactBitArray { + const byteCount = Math.ceil(bits.length / 8); + const extraBits = bits.length - Math.floor(bits.length / 8) * 8; + const bytes = new Uint8Array(byteCount); // zero-filled + + bits.forEach((value, index) => { + const bytePos = Math.floor(index / 8); + const bitPos = index % 8; + // eslint-disable-next-line no-bitwise + if (value) bytes[bytePos] |= 0b1 << (8 - 1 - bitPos); + }); + + return CompactBitArray.fromPartial({ elems: bytes, extraBitsStored: extraBits }); +} + +export function makeMultisignedTx( + multisigPubkey: MultisigThresholdPubkey, + sequence: number, + fee: StdFee, + bodyBytes: Uint8Array, + signatures: Map, +): TxRaw { + const addresses = Array.from(signatures.keys()); + const prefix = Bech32.decode(addresses[0]).prefix; + + const signers: boolean[] = Array(multisigPubkey.value.pubkeys.length).fill(false); + const signaturesList = new Array(); + for (let i = 0; i < multisigPubkey.value.pubkeys.length; i++) { + const signerAddress = pubkeyToAddress(multisigPubkey.value.pubkeys[i], prefix); + const signature = signatures.get(signerAddress); + if (signature) { + signers[i] = true; + signaturesList.push(signature); + } + } + + const signerInfo: SignerInfo = { + publicKey: encodePubkey(multisigPubkey), + modeInfo: { + multi: { + bitarray: makeCompactBitArray(signers), + modeInfos: signaturesList.map((_) => ({ single: { mode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON } })), + }, + }, + sequence: Long.fromNumber(sequence), + }; + + const authInfo = AuthInfo.fromPartial({ + signerInfos: [signerInfo], + fee: { + amount: [...fee.amount], + gasLimit: Long.fromString(fee.gas), + }, + }); + + const authInfoBytes = AuthInfo.encode(authInfo).finish(); + const signedTx = TxRaw.fromPartial({ + bodyBytes: bodyBytes, + authInfoBytes: authInfoBytes, + signatures: [MultiSignature.encode(MultiSignature.fromPartial({ signatures: signaturesList })).finish()], + }); + return signedTx; +} diff --git a/src/queries/auth.spec.ts b/src/queries/auth.spec.ts new file mode 100644 index 0000000..d744bb4 --- /dev/null +++ b/src/queries/auth.spec.ts @@ -0,0 +1,67 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { encodePubkey } from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { assert } from "@cosmjs/utils"; +import { BaseAccount } from "cosmjs-types/cosmos/auth/v1beta1/auth"; +import { Any } from "cosmjs-types/google/protobuf/any"; +import Long from "long"; + +import { nonExistentAddress, pendingWithoutSimapp, simapp, unused, validator } from "../testutils.spec"; +import { AuthExtension, setupAuthExtension } from "./auth"; +import { QueryClient } from "./queryclient"; + +async function makeClientWithAuth( + rpcUrl: string, +): Promise<[QueryClient & AuthExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupAuthExtension), tmClient]; +} + +describe("AuthExtension", () => { + describe("account", () => { + it("works for unused account", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl); + const account = await client.auth.account(unused.address); + assert(account); + + expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount"); + expect(BaseAccount.decode(account.value)).toEqual({ + address: unused.address, + // pubKey not set + accountNumber: Long.fromNumber(unused.accountNumber, true), + sequence: Long.fromNumber(0, true), + }); + + tmClient.disconnect(); + }); + + it("works for account with pubkey and non-zero sequence", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl); + const account = await client.auth.account(validator.delegatorAddress); + assert(account); + + expect(account.typeUrl).toEqual("/cosmos.auth.v1beta1.BaseAccount"); + expect(BaseAccount.decode(account.value)).toEqual({ + address: validator.delegatorAddress, + pubKey: Any.fromPartial(encodePubkey(validator.pubkey)), + accountNumber: Long.fromNumber(0, true), + sequence: Long.fromNumber(validator.sequence, true), + }); + + tmClient.disconnect(); + }); + + it("rejects for non-existent address", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithAuth(simapp.tendermintUrl); + + await expectAsync(client.auth.account(nonExistentAddress)).toBeRejectedWithError( + /account cosmos1p79apjaufyphcmsn4g07cynqf0wyjuezqu84hd not found/i, + ); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/auth.ts b/src/queries/auth.ts new file mode 100644 index 0000000..958f5a4 --- /dev/null +++ b/src/queries/auth.ts @@ -0,0 +1,34 @@ +import { QueryClientImpl } from "cosmjs-types/cosmos/auth/v1beta1/query"; +import { Any } from "cosmjs-types/google/protobuf/any"; + +import { QueryClient } from "./queryclient"; +import { createProtobufRpcClient } from "./utils"; + +export interface AuthExtension { + readonly auth: { + /** + * Returns an account if it exists and `null` otherwise. + * + * The account is a protobuf Any in order to be able to support many different + * account types in one API. The caller needs to switch over the expected and supported + * `typeUrl` and decode the `value` using its own type decoder. + */ + readonly account: (address: string) => Promise; + }; +} + +export function setupAuthExtension(base: QueryClient): AuthExtension { + const rpc = createProtobufRpcClient(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const queryService = new QueryClientImpl(rpc); + + return { + auth: { + account: async (address: string) => { + const { account } = await queryService.Account({ address: address }); + return account ?? null; + }, + }, + }; +} diff --git a/src/queries/bank.spec.ts b/src/queries/bank.spec.ts new file mode 100644 index 0000000..724f35d --- /dev/null +++ b/src/queries/bank.spec.ts @@ -0,0 +1,216 @@ +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; + +import { + nonExistentAddress, + nonNegativeIntegerMatcher, + pendingWithoutSimapp, + simapp, + unused, +} from "../testutils.spec"; +import { BankExtension, setupBankExtension } from "./bank"; +import { QueryClient } from "./queryclient"; + +async function makeClientWithBank( + rpcUrl: string, +): Promise<[QueryClient & BankExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupBankExtension), tmClient]; +} + +describe("BankExtension", () => { + describe("balance", () => { + it("works for different existing balances", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(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, + }); + + tmClient.disconnect(); + }); + + it("returns zero for non-existent balance", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const response = await client.bank.balance(unused.address, "gintonic"); + expect(response).toEqual({ + amount: "0", + denom: "gintonic", + }); + + tmClient.disconnect(); + }); + + it("returns zero for non-existent address", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const response = await client.bank.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, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const balances = await client.bank.allBalances(unused.address); + expect(balances).toEqual([ + { + amount: unused.balanceFee, + denom: simapp.denomFee, + }, + { + amount: unused.balanceStaking, + denom: simapp.denomStaking, + }, + ]); + + tmClient.disconnect(); + }); + + it("returns an empty list for non-existent account", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const balances = await client.bank.allBalances(nonExistentAddress); + expect(balances).toEqual([]); + + tmClient.disconnect(); + }); + }); + + describe("totalSupply", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const response = await client.bank.totalSupply(); + expect(response).toEqual([ + { + amount: simapp.totalSupply.toString(), + denom: simapp.denomFee, + }, + { + amount: jasmine.stringMatching(nonNegativeIntegerMatcher), + denom: simapp.denomStaking, + }, + ]); + + tmClient.disconnect(); + }); + }); + + describe("supplyOf", () => { + it("works for existing denom", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const response = await client.bank.supplyOf(simapp.denomFee); + expect(response).toEqual({ + amount: simapp.totalSupply.toString(), + denom: simapp.denomFee, + }); + + tmClient.disconnect(); + }); + + it("returns zero for non-existent denom", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const response = await client.bank.supplyOf("gintonic"); + expect(response).toEqual({ + amount: "0", + denom: "gintonic", + }); + + tmClient.disconnect(); + }); + }); + + describe("denomMetadata", () => { + it("works for existent denom", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const metadata = await client.bank.denomMetadata("ucosm"); + expect(metadata).toEqual({ + description: "The fee token of this test chain", + denomUnits: [ + { + denom: "ucosm", + exponent: 0, + aliases: [], + }, + { + denom: "COSM", + exponent: 6, + aliases: [], + }, + ], + base: "ucosm", + display: "COSM", + name: "", + symbol: "", + }); + + tmClient.disconnect(); + }); + + it("works for non-existent denom", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + await expectAsync(client.bank.denomMetadata("nothere")).toBeRejectedWithError(/code = NotFound/i); + + tmClient.disconnect(); + }); + }); + + describe("denomsMetadata", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithBank(simapp.tendermintUrl); + + const metadatas = await client.bank.denomsMetadata(); + expect(metadatas.length).toEqual(1); + expect(metadatas[0]).toEqual({ + description: "The fee token of this test chain", + denomUnits: [ + { + denom: "ucosm", + exponent: 0, + aliases: [], + }, + { + denom: "COSM", + exponent: 6, + aliases: [], + }, + ], + base: "ucosm", + display: "COSM", + name: "", + symbol: "", + }); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/bank.ts b/src/queries/bank.ts new file mode 100644 index 0000000..399a0b4 --- /dev/null +++ b/src/queries/bank.ts @@ -0,0 +1,60 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { assert } from "@cosmjs/utils"; +import { Metadata } from "cosmjs-types/cosmos/bank/v1beta1/bank"; +import { QueryClientImpl } from "cosmjs-types/cosmos/bank/v1beta1/query"; +import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; + +import { QueryClient } from "./queryclient"; +import { createProtobufRpcClient } from "./utils"; + +export interface BankExtension { + readonly bank: { + readonly balance: (address: string, denom: string) => Promise; + readonly allBalances: (address: string) => Promise; + readonly totalSupply: () => Promise; + readonly supplyOf: (denom: string) => Promise; + readonly denomMetadata: (denom: string) => Promise; + readonly denomsMetadata: () => Promise; + }; +} + +export function setupBankExtension(base: QueryClient): BankExtension { + const rpc = createProtobufRpcClient(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const queryService = new QueryClientImpl(rpc); + + return { + bank: { + balance: async (address: string, denom: string) => { + const { balance } = await queryService.Balance({ address: address, denom: denom }); + assert(balance); + return balance; + }, + allBalances: async (address: string) => { + const { balances } = await queryService.AllBalances({ address: address }); + return balances; + }, + totalSupply: async () => { + const { supply } = await queryService.TotalSupply({}); + return supply; + }, + supplyOf: async (denom: string) => { + const { amount } = await queryService.SupplyOf({ denom: denom }); + assert(amount); + return amount; + }, + denomMetadata: async (denom: string) => { + const { metadata } = await queryService.DenomMetadata({ denom }); + assert(metadata); + return metadata; + }, + denomsMetadata: async () => { + const { metadatas } = await queryService.DenomsMetadata({ + pagination: undefined, // Not implemented + }); + return metadatas; + }, + }, + }; +} diff --git a/src/queries/distribution.spec.ts b/src/queries/distribution.spec.ts new file mode 100644 index 0000000..bb33473 --- /dev/null +++ b/src/queries/distribution.spec.ts @@ -0,0 +1,179 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { coin, coins, DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { sleep } from "@cosmjs/utils"; +import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; + +import { MsgDelegateEncodeObject } from "../encodeobjects"; +import { SigningStargateClient } from "../signingstargateclient"; +import { assertIsDeliverTxSuccess } from "../stargateclient"; +import { + defaultSigningClientOptions, + faucet, + pendingWithoutSimapp, + simapp, + simappEnabled, + validator, +} from "../testutils.spec"; +import { DistributionExtension, setupDistributionExtension } from "./distribution"; +import { QueryClient } from "./queryclient"; + +async function makeClientWithDistribution( + rpcUrl: string, +): Promise<[QueryClient & DistributionExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupDistributionExtension), tmClient]; +} + +describe("DistributionExtension", () => { + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + + beforeAll(async () => { + if (simappEnabled()) { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(25000, "ustake"), + }; + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const memo = "Test delegation for Stargate"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], defaultFee, memo); + assertIsDeliverTxSuccess(result); + + await sleep(75); // wait until transactions are indexed + } + }); + + describe("communityPool", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.communityPool(); + expect(response.pool).toBeDefined(); + expect(response.pool).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegationRewards", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.delegationRewards( + faucet.address0, + validator.validatorAddress, + ); + expect(response.rewards).toBeDefined(); + expect(response.rewards).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegationTotalRewards", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.delegationTotalRewards(faucet.address0); + expect(response.rewards).toBeDefined(); + expect(response.rewards).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegatorValidators", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.delegatorValidators(faucet.address0); + expect(response.validators).toBeDefined(); + expect(response.validators).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegatorWithdrawAddress", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.delegatorWithdrawAddress(faucet.address0); + expect(response.withdrawAddress).toBeDefined(); + expect(response.withdrawAddress).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("params", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.params(); + expect(response.params).toBeDefined(); + expect(response.params).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validatorCommission", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.validatorCommission(validator.validatorAddress); + expect(response.commission).toBeDefined(); + expect(response.commission).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validatorOutstandingRewards", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.validatorOutstandingRewards(validator.validatorAddress); + expect(response.rewards).toBeDefined(); + expect(response.rewards).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validatorSlashes", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithDistribution(simapp.tendermintUrl); + + const response = await client.distribution.validatorSlashes(validator.validatorAddress, 1, 5); + expect(response.slashes).toBeDefined(); + expect(response.slashes).not.toBeNull(); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/distribution.ts b/src/queries/distribution.ts new file mode 100644 index 0000000..ea91d4b --- /dev/null +++ b/src/queries/distribution.ts @@ -0,0 +1,112 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { + QueryClientImpl, + QueryCommunityPoolResponse, + QueryDelegationRewardsResponse, + QueryDelegationTotalRewardsResponse, + QueryDelegatorValidatorsResponse, + QueryDelegatorWithdrawAddressResponse, + QueryParamsResponse, + QueryValidatorCommissionResponse, + QueryValidatorOutstandingRewardsResponse, + QueryValidatorSlashesResponse, +} from "cosmjs-types/cosmos/distribution/v1beta1/query"; +import Long from "long"; + +import { QueryClient } from "./queryclient"; +import { createPagination, createProtobufRpcClient } from "./utils"; + +export interface DistributionExtension { + readonly distribution: { + communityPool: () => Promise; + delegationRewards: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + delegationTotalRewards: (delegatorAddress: string) => Promise; + delegatorValidators: (delegatorAddress: string) => Promise; + delegatorWithdrawAddress: (delegatorAddress: string) => Promise; + params: () => Promise; + validatorCommission: (validatorAddress: string) => Promise; + validatorOutstandingRewards: ( + validatorAddress: string, + ) => Promise; + validatorSlashes: ( + validatorAddress: string, + startingHeight: number, + endingHeight: number, + paginationKey?: Uint8Array, + ) => Promise; + }; +} + +export function setupDistributionExtension(base: QueryClient): DistributionExtension { + const rpc = createProtobufRpcClient(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const queryService = new QueryClientImpl(rpc); + + return { + distribution: { + communityPool: async () => { + const response = await queryService.CommunityPool({}); + return response; + }, + delegationRewards: async (delegatorAddress: string, validatorAddress: string) => { + const response = await queryService.DelegationRewards({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress, + }); + return response; + }, + delegationTotalRewards: async (delegatorAddress: string) => { + const response = await queryService.DelegationTotalRewards({ + delegatorAddress: delegatorAddress, + }); + return response; + }, + delegatorValidators: async (delegatorAddress: string) => { + const response = await queryService.DelegatorValidators({ + delegatorAddress: delegatorAddress, + }); + return response; + }, + delegatorWithdrawAddress: async (delegatorAddress: string) => { + const response = await queryService.DelegatorWithdrawAddress({ + delegatorAddress: delegatorAddress, + }); + return response; + }, + params: async () => { + const response = await queryService.Params({}); + return response; + }, + validatorCommission: async (validatorAddress: string) => { + const response = await queryService.ValidatorCommission({ + validatorAddress: validatorAddress, + }); + return response; + }, + validatorOutstandingRewards: async (validatorAddress: string) => { + const response = await queryService.ValidatorOutstandingRewards({ + validatorAddress: validatorAddress, + }); + return response; + }, + validatorSlashes: async ( + validatorAddress: string, + startingHeight: number, + endingHeight: number, + paginationKey?: Uint8Array, + ) => { + const response = await queryService.ValidatorSlashes({ + validatorAddress: validatorAddress, + startingHeight: Long.fromNumber(startingHeight, true), + endingHeight: Long.fromNumber(endingHeight, true), + pagination: createPagination(paginationKey), + }); + return response; + }, + }, + }; +} diff --git a/src/queries/gov.spec.ts b/src/queries/gov.spec.ts new file mode 100644 index 0000000..cae143f --- /dev/null +++ b/src/queries/gov.spec.ts @@ -0,0 +1,416 @@ +import { coin, coins, makeCosmoshubPath } from "@cosmjs/amino"; +import { toAscii } from "@cosmjs/encoding"; +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { assert, sleep } from "@cosmjs/utils"; +import { + ProposalStatus, + TextProposal, + Vote, + VoteOption, + WeightedVoteOption, +} from "cosmjs-types/cosmos/gov/v1beta1/gov"; +import { Any } from "cosmjs-types/google/protobuf/any"; +import Long from "long"; + +import { + MsgDelegateEncodeObject, + MsgSubmitProposalEncodeObject, + MsgVoteEncodeObject, +} from "../encodeobjects"; +import { SigningStargateClient } from "../signingstargateclient"; +import { assertIsDeliverTxSuccess } from "../stargateclient"; +import { + defaultSigningClientOptions, + faucet, + nonNegativeIntegerMatcher, + pendingWithoutSimapp, + simapp, + simapp42Enabled, + simappEnabled, + validator, +} from "../testutils.spec"; +import { GovExtension, setupGovExtension } from "./gov"; +import { QueryClient } from "./queryclient"; +import { longify } from "./utils"; + +async function makeClientWithGov(rpcUrl: string): Promise<[QueryClient & GovExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupGovExtension), tmClient]; +} + +describe("GovExtension", () => { + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + const textProposal = TextProposal.fromPartial({ + title: "Test Proposal", + description: "This proposal proposes to test whether this proposal passes", + }); + const initialDeposit = coins(12300000, "ustake"); + const delegationVoter1 = coin(424242, "ustake"); + const delegationVoter2 = coin(777, "ustake"); + const voter1Address = faucet.address1; + const voter2Address = faucet.address2; + let proposalId: string | undefined; + + beforeAll(async () => { + if (simappEnabled()) { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic, { + // Use address 1 and 2 instead of 0 to avoid conflicts with other delegation tests + // This must match `voterAddress` above. + hdPaths: [makeCosmoshubPath(1), makeCosmoshubPath(2)], + }); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const proposalMsg: MsgSubmitProposalEncodeObject = { + typeUrl: "/cosmos.gov.v1beta1.MsgSubmitProposal", + value: { + content: Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: Uint8Array.from(TextProposal.encode(textProposal).finish()), + }), + proposer: voter1Address, + initialDeposit: initialDeposit, + }, + }; + const proposalResult = await client.signAndBroadcast( + voter1Address, + [proposalMsg], + defaultFee, + "Test proposal for simd", + ); + assertIsDeliverTxSuccess(proposalResult); + const logs = JSON.parse(proposalResult.rawLog || ""); + proposalId = logs[0].events + .find(({ type }: any) => type === "submit_proposal") + .attributes.find(({ key }: any) => key === "proposal_id").value; + assert(proposalId, "Proposal ID not found in events"); + assert(proposalId.match(nonNegativeIntegerMatcher)); + + // Voter 1 + { + // My vote only counts when I delegate + if (!(await client.getDelegation(voter1Address, validator.validatorAddress))) { + const msgDelegate: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: { + delegatorAddress: voter1Address, + validatorAddress: validator.validatorAddress, + amount: delegationVoter1, + }, + }; + const result = await client.signAndBroadcast(voter1Address, [msgDelegate], defaultFee); + assertIsDeliverTxSuccess(result); + } + + const voteMsg: MsgVoteEncodeObject = { + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: { + proposalId: longify(proposalId), + voter: voter1Address, + option: VoteOption.VOTE_OPTION_YES, + }, + }; + const voteResult = await client.signAndBroadcast(voter1Address, [voteMsg], defaultFee); + assertIsDeliverTxSuccess(voteResult); + } + + // Voter 2 + { + // My vote only counts when I delegate + if (!(await client.getDelegation(voter2Address, validator.validatorAddress))) { + const msgDelegate: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: { + delegatorAddress: voter2Address, + validatorAddress: validator.validatorAddress, + amount: delegationVoter2, + }, + }; + const result = await client.signAndBroadcast(voter2Address, [msgDelegate], defaultFee); + assertIsDeliverTxSuccess(result); + } + + const voteMsg: MsgVoteEncodeObject = { + typeUrl: "/cosmos.gov.v1beta1.MsgVote", + value: { + proposalId: longify(proposalId), + voter: voter2Address, + option: VoteOption.VOTE_OPTION_NO_WITH_VETO, + }, + }; + const voteResult = await client.signAndBroadcast(voter2Address, [voteMsg], defaultFee); + assertIsDeliverTxSuccess(voteResult); + } + + await sleep(75); // wait until transactions are indexed + + client.disconnect(); + } + }); + + describe("params", () => { + it("works for deposit", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.params("deposit"); + expect(response).toEqual( + jasmine.objectContaining({ + depositParams: { + minDeposit: simapp.govMinDeposit, + maxDepositPeriod: { + seconds: Long.fromNumber(172800, false), + nanos: 0, + }, + }, + }), + ); + + tmClient.disconnect(); + }); + + it("works for tallying", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.params("tallying"); + expect(response).toEqual( + jasmine.objectContaining({ + tallyParams: { + // Why the f*** are we getting binary values here? + quorum: toAscii("334000000000000000"), // 0.334 + threshold: toAscii("500000000000000000"), // 0.5 + vetoThreshold: toAscii("334000000000000000"), // 0.334 + }, + }), + ); + + tmClient.disconnect(); + }); + + it("works for voting", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.params("voting"); + expect(response).toEqual( + jasmine.objectContaining({ + votingParams: { + votingPeriod: { + seconds: Long.fromNumber(172800, false), + nanos: 0, + }, + }, + }), + ); + + tmClient.disconnect(); + }); + }); + + describe("proposals", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.proposals( + ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD, + voter1Address, + voter1Address, + ); + expect(response.proposals.length).toBeGreaterThanOrEqual(1); + expect(response.proposals[response.proposals.length - 1]).toEqual({ + content: Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: Uint8Array.from(TextProposal.encode(textProposal).finish()), + }), + proposalId: longify(proposalId), + status: ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD, + finalTallyResult: { yes: "0", abstain: "0", no: "0", noWithVeto: "0" }, + submitTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + depositEndTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + totalDeposit: initialDeposit, + votingStartTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + votingEndTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + }); + + tmClient.disconnect(); + }); + }); + + describe("proposal", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.proposal(proposalId); + expect(response.proposal).toEqual({ + content: Any.fromPartial({ + typeUrl: "/cosmos.gov.v1beta1.TextProposal", + value: Uint8Array.from(TextProposal.encode(textProposal).finish()), + }), + proposalId: longify(proposalId), + status: ProposalStatus.PROPOSAL_STATUS_VOTING_PERIOD, + finalTallyResult: { yes: "0", abstain: "0", no: "0", noWithVeto: "0" }, + submitTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + depositEndTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + totalDeposit: initialDeposit, + votingStartTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + votingEndTime: { seconds: jasmine.any(Long), nanos: jasmine.any(Number) }, + }); + + tmClient.disconnect(); + }); + }); + + describe("deposits", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.deposits(proposalId); + expect(response.deposits).toEqual([ + { + proposalId: longify(proposalId), + depositor: voter1Address, + amount: initialDeposit, + }, + ]); + + tmClient.disconnect(); + }); + }); + + describe("deposit", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.deposit(proposalId, voter1Address); + expect(response.deposit).toEqual({ + proposalId: longify(proposalId), + depositor: voter1Address, + amount: initialDeposit, + }); + + tmClient.disconnect(); + }); + }); + + describe("tally", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.tally(proposalId); + expect(response.tally).toEqual({ + yes: delegationVoter1.amount, + abstain: "0", + no: "0", + noWithVeto: delegationVoter2.amount, + }); + + tmClient.disconnect(); + }); + }); + + describe("votes", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.votes(proposalId); + if (simapp42Enabled()) { + expect(response.votes).toEqual([ + // why is vote 2 first? + Vote.fromPartial({ + proposalId: longify(proposalId), + voter: voter2Address, + option: VoteOption.VOTE_OPTION_NO_WITH_VETO, + }), + Vote.fromPartial({ + proposalId: longify(proposalId), + voter: voter1Address, + option: VoteOption.VOTE_OPTION_YES, + }), + ]); + } else { + expect(response.votes).toEqual([ + // why is vote 2 first? + Vote.fromPartial({ + proposalId: longify(proposalId), + voter: voter2Address, + option: VoteOption.VOTE_OPTION_NO_WITH_VETO, + options: [ + WeightedVoteOption.fromPartial({ + option: VoteOption.VOTE_OPTION_NO_WITH_VETO, + weight: "1000000000000000000", + }), + ], + }), + Vote.fromPartial({ + proposalId: longify(proposalId), + voter: voter1Address, + option: VoteOption.VOTE_OPTION_YES, + options: [ + WeightedVoteOption.fromPartial({ + option: VoteOption.VOTE_OPTION_YES, + weight: "1000000000000000000", + }), + ], + }), + ]); + } + + tmClient.disconnect(); + }); + }); + + describe("vote", () => { + it("works", async () => { + pendingWithoutSimapp(); + assert(proposalId, "Missing proposal ID"); + const [client, tmClient] = await makeClientWithGov(simapp.tendermintUrl); + + const response = await client.gov.vote(proposalId, voter1Address); + if (simapp42Enabled()) { + expect(response.vote).toEqual( + Vote.fromPartial({ + voter: voter1Address, + proposalId: longify(proposalId), + option: VoteOption.VOTE_OPTION_YES, + }), + ); + } else { + expect(response.vote).toEqual( + Vote.fromPartial({ + voter: voter1Address, + proposalId: longify(proposalId), + option: VoteOption.VOTE_OPTION_YES, + options: [ + WeightedVoteOption.fromPartial({ + option: VoteOption.VOTE_OPTION_YES, + weight: "1000000000000000000", + }), + ], + }), + ); + } + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/gov.ts b/src/queries/gov.ts new file mode 100644 index 0000000..e8c81aa --- /dev/null +++ b/src/queries/gov.ts @@ -0,0 +1,111 @@ +import { Uint64 } from "@cosmjs/math"; +import { ProposalStatus } from "cosmjs-types/cosmos/gov/v1beta1/gov"; +import { + QueryClientImpl, + QueryDepositResponse, + QueryDepositsResponse, + QueryParamsResponse, + QueryProposalResponse, + QueryProposalsResponse, + QueryTallyResultResponse, + QueryVoteResponse, + QueryVotesResponse, +} from "cosmjs-types/cosmos/gov/v1beta1/query"; +import Long from "long"; + +import { QueryClient } from "./queryclient"; +import { createPagination, createProtobufRpcClient, longify } from "./utils"; + +export type GovParamsType = "deposit" | "tallying" | "voting"; + +export type GovProposalId = string | number | Long | Uint64; + +export interface GovExtension { + readonly gov: { + readonly params: (parametersType: GovParamsType) => Promise; + readonly proposals: ( + proposalStatus: ProposalStatus, + depositor: string, + voter: string, + paginationKey?: Uint8Array, + ) => Promise; + readonly proposal: (proposalId: GovProposalId) => Promise; + readonly deposits: ( + proposalId: GovProposalId, + paginationKey?: Uint8Array, + ) => Promise; + readonly deposit: (proposalId: GovProposalId, depositorAddress: string) => Promise; + readonly tally: (proposalId: GovProposalId) => Promise; + readonly votes: (proposalId: GovProposalId, paginationKey?: Uint8Array) => Promise; + readonly vote: (proposalId: GovProposalId, voterAddress: string) => Promise; + }; +} + +export function setupGovExtension(base: QueryClient): GovExtension { + const rpc = createProtobufRpcClient(base); + + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const queryService = new QueryClientImpl(rpc); + + return { + gov: { + params: async (parametersType: GovParamsType) => { + const response = await queryService.Params({ paramsType: parametersType }); + return response; + }, + proposals: async ( + proposalStatus: ProposalStatus, + depositorAddress: string, + voterAddress: string, + paginationKey?: Uint8Array, + ) => { + const response = await queryService.Proposals({ + proposalStatus, + depositor: depositorAddress, + voter: voterAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + proposal: async (proposalId: GovProposalId) => { + const response = await queryService.Proposal({ proposalId: longify(proposalId) }); + return response; + }, + deposits: async (proposalId: GovProposalId, paginationKey?: Uint8Array) => { + const response = await queryService.Deposits({ + proposalId: longify(proposalId), + pagination: createPagination(paginationKey), + }); + return response; + }, + deposit: async (proposalId: GovProposalId, depositorAddress: string) => { + const response = await queryService.Deposit({ + proposalId: longify(proposalId), + depositor: depositorAddress, + }); + return response; + }, + tally: async (proposalId: GovProposalId) => { + const response = await queryService.TallyResult({ + proposalId: longify(proposalId), + }); + return response; + }, + votes: async (proposalId: GovProposalId, paginationKey?: Uint8Array) => { + const response = await queryService.Votes({ + proposalId: longify(proposalId), + pagination: createPagination(paginationKey), + }); + return response; + }, + vote: async (proposalId: GovProposalId, voterAddress: string) => { + const response = await queryService.Vote({ + proposalId: longify(proposalId), + voter: voterAddress, + }); + return response; + }, + }, + }; +} diff --git a/src/queries/ibc.spec.ts b/src/queries/ibc.spec.ts new file mode 100644 index 0000000..5d425f6 --- /dev/null +++ b/src/queries/ibc.spec.ts @@ -0,0 +1,558 @@ +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import Long from "long"; + +import { pendingWithoutSimapp42, simapp } from "../testutils.spec"; +import { IbcExtension, setupIbcExtension } from "./ibc"; +import * as ibcTest from "./ibctestdata.spec"; +import { QueryClient } from "./queryclient"; + +async function makeClientWithIbc(rpcUrl: string): Promise<[QueryClient & IbcExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupIbcExtension), tmClient]; +} + +describe("IbcExtension", () => { + describe("channel", () => { + describe("channel", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.channel(ibcTest.portId, ibcTest.channelId); + expect(response.channel).toEqual(ibcTest.channel); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("channels", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.channels(); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("allChannels", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.allChannels(); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + + tmClient.disconnect(); + }); + }); + + describe("connectionChannels", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.connectionChannels(ibcTest.connectionId); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("allConnectionChannels", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.allConnectionChannels(ibcTest.connectionId); + expect(response.channels).toEqual([ibcTest.identifiedChannel]); + + tmClient.disconnect(); + }); + }); + + describe("clientState", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.clientState(ibcTest.portId, ibcTest.channelId); + expect(response.identifiedClientState).toEqual({ + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array), + }, + }); + + tmClient.disconnect(); + }); + }); + + describe("consensusState", () => { + xit("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.consensusState( + ibcTest.portId, + ibcTest.channelId, + // TODO: Find valid values + 0, + 0, + ); + expect(response.consensusState).toEqual({ + typeUrl: "/haha", + value: jasmine.any(Uint8Array), + }); + expect(response.clientId).toEqual(ibcTest.clientId); + + tmClient.disconnect(); + }); + }); + + describe("packetCommitment", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.packetCommitment( + ibcTest.portId, + ibcTest.channelId, + Long.fromInt(ibcTest.commitment.sequence, true), + ); + expect(response.commitment).toEqual(ibcTest.commitment.data); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("packetCommitments", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.packetCommitments(ibcTest.portId, ibcTest.channelId); + expect(response.commitments).toEqual([ibcTest.packetState]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("allPacketCommitments", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.allPacketCommitments(ibcTest.portId, ibcTest.channelId); + expect(response.commitments).toEqual([ibcTest.packetState]); + + tmClient.disconnect(); + }); + }); + + describe("packetReceipt", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.packetReceipt(ibcTest.portId, ibcTest.channelId, 1); + expect(response.received).toEqual(false); + + tmClient.disconnect(); + }); + }); + + describe("packetAcknowledgement", () => { + it("works", async () => { + pending("We don't have an acknowledgement for testing at the moment"); + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.packetAcknowledgement( + ibcTest.portId, + ibcTest.channelId, + ibcTest.commitment.sequence, + ); + expect(response.acknowledgement).toEqual(ibcTest.packetAcknowledgements[0].data); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("packetAcknowledgements", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.packetAcknowledgements(ibcTest.portId, ibcTest.channelId); + expect(response.acknowledgements).toEqual(ibcTest.packetAcknowledgements); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("allPacketAcknowledgements", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.allPacketAcknowledgements( + ibcTest.portId, + ibcTest.channelId, + ); + expect(response.acknowledgements).toEqual(ibcTest.packetAcknowledgements); + + tmClient.disconnect(); + }); + }); + + describe("unreceivedPackets", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.unreceivedPackets( + ibcTest.portId, + ibcTest.channelId, + [1, 2, 3], + ); + expect(response.sequences).toEqual([1, 2, 3].map((n) => Long.fromInt(n, true))); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("unreceivedAcks", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.unreceivedAcks( + ibcTest.portId, + ibcTest.channelId, + [1, 2, 3, 4, 5, 6, 7], + ); + expect(response.sequences).toEqual([Long.fromInt(ibcTest.commitment.sequence, true)]); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("nextSequenceReceive", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.channel.nextSequenceReceive(ibcTest.portId, ibcTest.channelId); + expect(response.nextSequenceReceive).toEqual(Long.fromInt(1, true)); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + }); + + describe("client", () => { + describe("state", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.state(ibcTest.clientId); + expect(response.clientState).toEqual({ + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array), + }); + + tmClient.disconnect(); + }); + }); + + describe("states", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.states(); + expect(response.clientStates).toEqual([ + { + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array), + }, + }, + ]); + expect(response.pagination).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("allStates", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.allStates(); + expect(response.clientStates).toEqual([ + { + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array), + }, + }, + ]); + + tmClient.disconnect(); + }); + }); + + describe("consensusState", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.consensusState(ibcTest.clientId); + expect(response.consensusState).toEqual({ + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array), + }); + + tmClient.disconnect(); + }); + }); + + describe("consensusStates", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.consensusStates(ibcTest.clientId); + expect(response.consensusStates).toEqual( + jasmine.arrayContaining([ + { + height: jasmine.anything(), + consensusState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array), + }, + }, + ]), + ); + + tmClient.disconnect(); + }); + }); + + describe("allConsensusStates", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.allConsensusStates(ibcTest.clientId); + expect(response.consensusStates).toEqual( + jasmine.arrayContaining([ + { + height: jasmine.anything(), + consensusState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array), + }, + }, + ]), + ); + + tmClient.disconnect(); + }); + }); + + describe("params", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.params(); + expect(response.params).toEqual({ + allowedClients: ["06-solomachine", "07-tendermint"], + }); + + tmClient.disconnect(); + }); + }); + + describe("stateTm", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.stateTm(ibcTest.clientId); + expect(response.chainId).toEqual("ibc-1"); + // TODO: Fill these expectations out + + tmClient.disconnect(); + }); + }); + + describe("statesTm", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.statesTm(); + expect(response).toEqual( + jasmine.arrayContaining([ + jasmine.objectContaining({ + chainId: "ibc-1", + }), + ]), + ); + + tmClient.disconnect(); + }); + }); + + describe("allStatesTm", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.allStatesTm(); + expect(response).toEqual( + jasmine.arrayContaining([ + jasmine.objectContaining({ + chainId: "ibc-1", + }), + ]), + ); + + tmClient.disconnect(); + }); + }); + + describe("consensusStateTm", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.client.consensusStateTm(ibcTest.clientId); + expect(response.nextValidatorsHash).toEqual(jasmine.any(Uint8Array)); + // TODO: Fill out these expectations + + tmClient.disconnect(); + }); + }); + }); + + describe("connection", () => { + describe("connection", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.connection.connection(ibcTest.connectionId); + expect(response.connection).toEqual(ibcTest.connection); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("connections", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.connection.connections(); + expect(response.connections).toEqual([ibcTest.identifiedConnection]); + expect(response.pagination).toBeDefined(); + expect(response.height).toBeDefined(); + + tmClient.disconnect(); + }); + }); + + describe("allConnections", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.connection.allConnections(); + expect(response.connections).toEqual([ibcTest.identifiedConnection]); + + tmClient.disconnect(); + }); + }); + + describe("clientConnections", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.connection.clientConnections(ibcTest.clientId); + expect(response.connectionPaths).toEqual([ibcTest.connectionId]); + expect(response.proofHeight).toBeDefined(); + expect(response.proofHeight).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("clientState", () => { + it("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + const response = await client.ibc.connection.clientState(ibcTest.connectionId); + expect(response.identifiedClientState).toEqual({ + clientId: ibcTest.clientId, + clientState: { + typeUrl: "/ibc.lightclients.tendermint.v1.ClientState", + value: jasmine.any(Uint8Array), + }, + }); + + tmClient.disconnect(); + }); + }); + + describe("consensusState", () => { + xit("works", async () => { + pendingWithoutSimapp42(); + const [client, tmClient] = await makeClientWithIbc(simapp.tendermintUrl); + + // TODO: Find valid values + const response = await client.ibc.connection.consensusState(ibcTest.connectionId, 1, 1); + expect(response.clientId).toEqual(ibcTest.clientId); + expect(response.consensusState).toEqual({ + typeUrl: "/ibc.lightclients.tendermint.v1.ConsensusState", + value: jasmine.any(Uint8Array), + }); + + tmClient.disconnect(); + }); + }); + }); +}); diff --git a/src/queries/ibc.ts b/src/queries/ibc.ts new file mode 100644 index 0000000..520b441 --- /dev/null +++ b/src/queries/ibc.ts @@ -0,0 +1,540 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { toAscii } from "@cosmjs/encoding"; +import { Uint64 } from "@cosmjs/math"; +import { Any } from "cosmjs-types/google/protobuf/any"; +import { + QueryClientImpl as TransferQuery, + QueryDenomTraceResponse, + QueryDenomTracesResponse, + QueryParamsResponse as QueryTransferParamsResponse, +} from "cosmjs-types/ibc/applications/transfer/v1/query"; +import { Channel } from "cosmjs-types/ibc/core/channel/v1/channel"; +import { + QueryChannelClientStateResponse, + QueryChannelConsensusStateResponse, + QueryChannelResponse, + QueryChannelsResponse, + QueryClientImpl as ChannelQuery, + QueryConnectionChannelsResponse, + QueryNextSequenceReceiveResponse, + QueryPacketAcknowledgementResponse, + QueryPacketAcknowledgementsResponse, + QueryPacketCommitmentResponse, + QueryPacketCommitmentsResponse, + QueryPacketReceiptResponse, + QueryUnreceivedAcksResponse, + QueryUnreceivedPacketsResponse, +} from "cosmjs-types/ibc/core/channel/v1/query"; +import { Height } from "cosmjs-types/ibc/core/client/v1/client"; +import { + QueryClientImpl as ClientQuery, + QueryClientParamsResponse, + QueryClientStateResponse, + QueryClientStatesResponse, + QueryConsensusStateRequest, + QueryConsensusStateResponse, + QueryConsensusStatesResponse, +} from "cosmjs-types/ibc/core/client/v1/query"; +import { + QueryClientConnectionsResponse, + QueryClientImpl as ConnectionQuery, + QueryConnectionClientStateResponse, + QueryConnectionConsensusStateRequest, + QueryConnectionConsensusStateResponse, + QueryConnectionResponse, + QueryConnectionsResponse, +} from "cosmjs-types/ibc/core/connection/v1/query"; +import { + ClientState as TendermintClientState, + ConsensusState as TendermintConsensusState, +} from "cosmjs-types/ibc/lightclients/tendermint/v1/tendermint"; +import Long from "long"; + +import { QueryClient } from "./queryclient"; +import { createPagination, createProtobufRpcClient } from "./utils"; + +function decodeTendermintClientStateAny(clientState: Any | undefined): TendermintClientState { + if (clientState?.typeUrl !== "/ibc.lightclients.tendermint.v1.ClientState") { + throw new Error(`Unexpected client state type: ${clientState?.typeUrl}`); + } + return TendermintClientState.decode(clientState.value); +} + +function decodeTendermintConsensusStateAny(clientState: Any | undefined): TendermintConsensusState { + if (clientState?.typeUrl !== "/ibc.lightclients.tendermint.v1.ConsensusState") { + throw new Error(`Unexpected client state type: ${clientState?.typeUrl}`); + } + return TendermintConsensusState.decode(clientState.value); +} + +export interface IbcExtension { + readonly ibc: { + readonly channel: { + readonly channel: (portId: string, channelId: string) => Promise; + readonly channels: (paginationKey?: Uint8Array) => Promise; + readonly allChannels: () => Promise; + readonly connectionChannels: ( + connection: string, + paginationKey?: Uint8Array, + ) => Promise; + readonly allConnectionChannels: (connection: string) => Promise; + readonly clientState: (portId: string, channelId: string) => Promise; + readonly consensusState: ( + portId: string, + channelId: string, + revisionNumber: number, + revisionHeight: number, + ) => Promise; + readonly packetCommitment: ( + portId: string, + channelId: string, + sequence: Long, + ) => Promise; + readonly packetCommitments: ( + portId: string, + channelId: string, + paginationKey?: Uint8Array, + ) => Promise; + readonly allPacketCommitments: ( + portId: string, + channelId: string, + ) => Promise; + readonly packetReceipt: ( + portId: string, + channelId: string, + sequence: number, + ) => Promise; + readonly packetAcknowledgement: ( + portId: string, + channelId: string, + sequence: number, + ) => Promise; + readonly packetAcknowledgements: ( + portId: string, + channelId: string, + paginationKey?: Uint8Array, + ) => Promise; + readonly allPacketAcknowledgements: ( + portId: string, + channelId: string, + ) => Promise; + readonly unreceivedPackets: ( + portId: string, + channelId: string, + packetCommitmentSequences: readonly number[], + ) => Promise; + readonly unreceivedAcks: ( + portId: string, + channelId: string, + packetAckSequences: readonly number[], + ) => Promise; + readonly nextSequenceReceive: ( + portId: string, + channelId: string, + ) => Promise; + }; + readonly client: { + readonly state: (clientId: string) => Promise; + readonly states: (paginationKey?: Uint8Array) => Promise; + readonly allStates: () => Promise; + readonly consensusState: (clientId: string, height?: number) => Promise; + readonly consensusStates: ( + clientId: string, + paginationKey?: Uint8Array, + ) => Promise; + readonly allConsensusStates: (clientId: string) => Promise; + readonly params: () => Promise; + readonly stateTm: (clientId: string) => Promise; + readonly statesTm: (paginationKey?: Uint8Array) => Promise; + readonly allStatesTm: () => Promise; + readonly consensusStateTm: (clientId: string, height?: Height) => Promise; + }; + readonly connection: { + readonly connection: (connectionId: string) => Promise; + readonly connections: (paginationKey?: Uint8Array) => Promise; + readonly allConnections: () => Promise; + readonly clientConnections: (clientId: string) => Promise; + readonly clientState: (connectionId: string) => Promise; + readonly consensusState: ( + connectionId: string, + revisionNumber: number, + revisionHeight: number, + ) => Promise; + }; + readonly transfer: { + readonly denomTrace: (hash: string) => Promise; + readonly denomTraces: (paginationKey?: Uint8Array) => Promise; + readonly allDenomTraces: () => Promise; + readonly params: () => Promise; + }; + readonly verified: { + readonly channel: { + readonly channel: (portId: string, channelId: string) => Promise; + readonly packetCommitment: ( + portId: string, + channelId: string, + sequence: number, + ) => Promise; + readonly packetAcknowledgement: ( + portId: string, + channelId: string, + sequence: number, + ) => Promise; + readonly nextSequenceReceive: (portId: string, channelId: string) => Promise; + }; + }; + }; +} + +export function setupIbcExtension(base: QueryClient): IbcExtension { + const rpc = createProtobufRpcClient(base); + // Use these services to get easy typed access to query methods + // These cannot be used for proof verification + const channelQueryService = new ChannelQuery(rpc); + const clientQueryService = new ClientQuery(rpc); + const connectionQueryService = new ConnectionQuery(rpc); + const transferQueryService = new TransferQuery(rpc); + + return { + ibc: { + channel: { + channel: async (portId: string, channelId: string) => + channelQueryService.Channel({ + portId: portId, + channelId: channelId, + }), + channels: async (paginationKey?: Uint8Array) => + channelQueryService.Channels({ + pagination: createPagination(paginationKey), + }), + allChannels: async () => { + const channels = []; + let response: QueryChannelsResponse; + let key: Uint8Array | undefined; + do { + response = await channelQueryService.Channels({ + pagination: createPagination(key), + }); + channels.push(...response.channels); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + channels: channels, + height: response.height, + }; + }, + connectionChannels: async (connection: string, paginationKey?: Uint8Array) => + channelQueryService.ConnectionChannels({ + connection: connection, + pagination: createPagination(paginationKey), + }), + allConnectionChannels: async (connection: string) => { + const channels = []; + let response: QueryConnectionChannelsResponse; + let key: Uint8Array | undefined; + do { + response = await channelQueryService.ConnectionChannels({ + connection: connection, + pagination: createPagination(key), + }); + channels.push(...response.channels); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + channels: channels, + height: response.height, + }; + }, + clientState: async (portId: string, channelId: string) => + channelQueryService.ChannelClientState({ + portId: portId, + channelId: channelId, + }), + consensusState: async ( + portId: string, + channelId: string, + revisionNumber: number, + revisionHeight: number, + ) => + channelQueryService.ChannelConsensusState({ + portId: portId, + channelId: channelId, + revisionNumber: Long.fromNumber(revisionNumber, true), + revisionHeight: Long.fromNumber(revisionHeight, true), + }), + packetCommitment: async (portId: string, channelId: string, sequence: Long) => + channelQueryService.PacketCommitment({ + portId: portId, + channelId: channelId, + sequence: sequence, + }), + packetCommitments: async (portId: string, channelId: string, paginationKey?: Uint8Array) => + channelQueryService.PacketCommitments({ + channelId: channelId, + portId: portId, + pagination: createPagination(paginationKey), + }), + allPacketCommitments: async (portId: string, channelId: string) => { + const commitments = []; + let response: QueryPacketCommitmentsResponse; + let key: Uint8Array | undefined; + do { + response = await channelQueryService.PacketCommitments({ + channelId: channelId, + portId: portId, + pagination: createPagination(key), + }); + commitments.push(...response.commitments); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + commitments: commitments, + height: response.height, + }; + }, + packetReceipt: async (portId: string, channelId: string, sequence: number) => + channelQueryService.PacketReceipt({ + portId: portId, + channelId: channelId, + sequence: Long.fromNumber(sequence, true), + }), + packetAcknowledgement: async (portId: string, channelId: string, sequence: number) => + channelQueryService.PacketAcknowledgement({ + portId: portId, + channelId: channelId, + sequence: Long.fromNumber(sequence, true), + }), + packetAcknowledgements: async (portId: string, channelId: string, paginationKey?: Uint8Array) => + channelQueryService.PacketAcknowledgements({ + portId: portId, + channelId: channelId, + pagination: createPagination(paginationKey), + }), + allPacketAcknowledgements: async (portId: string, channelId: string) => { + const acknowledgements = []; + let response: QueryPacketAcknowledgementsResponse; + let key: Uint8Array | undefined; + do { + response = await channelQueryService.PacketAcknowledgements({ + channelId: channelId, + portId: portId, + pagination: createPagination(key), + }); + acknowledgements.push(...response.acknowledgements); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + acknowledgements: acknowledgements, + height: response.height, + }; + }, + unreceivedPackets: async ( + portId: string, + channelId: string, + packetCommitmentSequences: readonly number[], + ) => + channelQueryService.UnreceivedPackets({ + portId: portId, + channelId: channelId, + packetCommitmentSequences: packetCommitmentSequences.map((s) => Long.fromNumber(s, true)), + }), + unreceivedAcks: async (portId: string, channelId: string, packetAckSequences: readonly number[]) => + channelQueryService.UnreceivedAcks({ + portId: portId, + channelId: channelId, + packetAckSequences: packetAckSequences.map((s) => Long.fromNumber(s, true)), + }), + nextSequenceReceive: async (portId: string, channelId: string) => + channelQueryService.NextSequenceReceive({ + portId: portId, + channelId: channelId, + }), + }, + client: { + state: async (clientId: string) => clientQueryService.ClientState({ clientId }), + states: async (paginationKey?: Uint8Array) => + clientQueryService.ClientStates({ + pagination: createPagination(paginationKey), + }), + allStates: async () => { + const clientStates = []; + let response: QueryClientStatesResponse; + let key: Uint8Array | undefined; + do { + response = await clientQueryService.ClientStates({ + pagination: createPagination(key), + }); + clientStates.push(...response.clientStates); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + clientStates: clientStates, + }; + }, + consensusState: async (clientId: string, consensusHeight?: number) => + clientQueryService.ConsensusState( + QueryConsensusStateRequest.fromPartial({ + clientId: clientId, + revisionHeight: + consensusHeight !== undefined ? Long.fromNumber(consensusHeight, true) : undefined, + latestHeight: consensusHeight === undefined, + }), + ), + consensusStates: async (clientId: string, paginationKey?: Uint8Array) => + clientQueryService.ConsensusStates({ + clientId: clientId, + pagination: createPagination(paginationKey), + }), + allConsensusStates: async (clientId: string) => { + const consensusStates = []; + let response: QueryConsensusStatesResponse; + let key: Uint8Array | undefined; + do { + response = await clientQueryService.ConsensusStates({ + clientId: clientId, + pagination: createPagination(key), + }); + consensusStates.push(...response.consensusStates); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + consensusStates: consensusStates, + }; + }, + params: async () => clientQueryService.ClientParams({}), + stateTm: async (clientId: string) => { + const response = await clientQueryService.ClientState({ clientId }); + return decodeTendermintClientStateAny(response.clientState); + }, + statesTm: async (paginationKey?: Uint8Array) => { + const { clientStates } = await clientQueryService.ClientStates({ + pagination: createPagination(paginationKey), + }); + return clientStates.map(({ clientState }) => decodeTendermintClientStateAny(clientState)); + }, + allStatesTm: async () => { + const clientStates = []; + let response: QueryClientStatesResponse; + let key: Uint8Array | undefined; + do { + response = await clientQueryService.ClientStates({ + pagination: createPagination(key), + }); + clientStates.push(...response.clientStates); + key = response.pagination?.nextKey; + } while (key && key.length); + return clientStates.map(({ clientState }) => decodeTendermintClientStateAny(clientState)); + }, + consensusStateTm: async (clientId: string, consensusHeight?: Height) => { + const response = await clientQueryService.ConsensusState( + QueryConsensusStateRequest.fromPartial({ + clientId: clientId, + revisionHeight: consensusHeight?.revisionHeight, + revisionNumber: consensusHeight?.revisionNumber, + latestHeight: consensusHeight === undefined, + }), + ); + return decodeTendermintConsensusStateAny(response.consensusState); + }, + }, + connection: { + connection: async (connectionId: string) => + connectionQueryService.Connection({ + connectionId: connectionId, + }), + connections: async (paginationKey?: Uint8Array) => + connectionQueryService.Connections({ + pagination: createPagination(paginationKey), + }), + allConnections: async () => { + const connections = []; + let response: QueryConnectionsResponse; + let key: Uint8Array | undefined; + do { + response = await connectionQueryService.Connections({ + pagination: createPagination(key), + }); + connections.push(...response.connections); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + connections: connections, + height: response.height, + }; + }, + clientConnections: async (clientId: string) => + connectionQueryService.ClientConnections({ + clientId: clientId, + }), + clientState: async (connectionId: string) => + connectionQueryService.ConnectionClientState({ + connectionId: connectionId, + }), + consensusState: async (connectionId: string, revisionHeight: number) => + connectionQueryService.ConnectionConsensusState( + QueryConnectionConsensusStateRequest.fromPartial({ + connectionId: connectionId, + revisionHeight: Long.fromNumber(revisionHeight, true), + }), + ), + }, + transfer: { + denomTrace: async (hash: string) => transferQueryService.DenomTrace({ hash: hash }), + denomTraces: async (paginationKey?: Uint8Array) => + transferQueryService.DenomTraces({ + pagination: createPagination(paginationKey), + }), + allDenomTraces: async () => { + const denomTraces = []; + let response: QueryDenomTracesResponse; + let key: Uint8Array | undefined; + do { + response = await transferQueryService.DenomTraces({ + pagination: createPagination(key), + }); + denomTraces.push(...response.denomTraces); + key = response.pagination?.nextKey; + } while (key && key.length); + return { + denomTraces: denomTraces, + }; + }, + params: async () => transferQueryService.Params({}), + }, + verified: { + channel: { + channel: async (portId: string, channelId: string) => { + // keeper: https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/ibc/04-channel/keeper/keeper.go#L55-L65 + // key: https://github.com/cosmos/cosmos-sdk/blob/ef0a7344af345882729598bc2958a21143930a6b/x/ibc/24-host/keys.go#L117-L120 + const key = toAscii(`channelEnds/ports/${portId}/channels/${channelId}`); + const responseData = await base.queryVerified("ibc", key); + return responseData.length ? Channel.decode(responseData) : null; + }, + packetCommitment: async (portId: string, channelId: string, sequence: number) => { + // keeper: https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/ibc/04-channel/keeper/keeper.go#L128-L133 + // key: https://github.com/cosmos/cosmos-sdk/blob/ef0a7344af345882729598bc2958a21143930a6b/x/ibc/24-host/keys.go#L183-L185 + const key = toAscii(`commitments/ports/${portId}/channels/${channelId}/packets/${sequence}`); + const responseData = await base.queryVerified("ibc", key); + // keeper code doesn't parse, but returns raw + return responseData; + }, + packetAcknowledgement: async (portId: string, channelId: string, sequence: number) => { + // keeper: https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/ibc/04-channel/keeper/keeper.go#L159-L166 + // key: https://github.com/cosmos/cosmos-sdk/blob/ef0a7344af345882729598bc2958a21143930a6b/x/ibc/24-host/keys.go#L153-L156 + const key = toAscii(`acks/ports/${portId}/channels/${channelId}/acknowledgements/${sequence}`); + const responseData = await base.queryVerified("ibc", key); + // keeper code doesn't parse, but returns raw + return responseData; + }, + nextSequenceReceive: async (portId: string, channelId: string) => { + // keeper: https://github.com/cosmos/cosmos-sdk/blob/3bafd8255a502e5a9cee07391cf8261538245dfd/x/ibc/04-channel/keeper/keeper.go#L92-L101 + // key: https://github.com/cosmos/cosmos-sdk/blob/ef0a7344af345882729598bc2958a21143930a6b/x/ibc/24-host/keys.go#L133-L136 + const key = toAscii(`seqAcks/ports/${portId}/channels/${channelId}/nextSequenceAck`); + const responseData = await base.queryVerified("ibc", key); + return responseData.length ? Uint64.fromBytes(responseData).toNumber() : null; + }, + }, + }, + }, + }; +} diff --git a/src/queries/ibctestdata.spec.ts b/src/queries/ibctestdata.spec.ts new file mode 100644 index 0000000..88a6aa0 --- /dev/null +++ b/src/queries/ibctestdata.spec.ts @@ -0,0 +1,112 @@ +import { fromBase64 } from "@cosmjs/encoding"; +import { + Channel, + Counterparty as ChannelCounterparty, + IdentifiedChannel, + Order, + PacketState, + State as ChannelState, +} from "cosmjs-types/ibc/core/channel/v1/channel"; +import { MerklePrefix } from "cosmjs-types/ibc/core/commitment/v1/commitment"; +import { + ConnectionEnd, + Counterparty as ConnectionCounterparty, + IdentifiedConnection, + State as ConnectionState, + Version, +} from "cosmjs-types/ibc/core/connection/v1/connection"; +import Long from "long"; + +// From scripts/simapp42/genesis-ibc.json + +export const portId = "transfer"; +export const channelId = "channel-0"; +export const connectionId = "connection-0"; +export const clientId = "07-tendermint-0"; + +export const channel = Channel.fromPartial({ + state: ChannelState.STATE_OPEN, + ordering: Order.ORDER_UNORDERED, + counterparty: ChannelCounterparty.fromPartial({ + portId: portId, + channelId: channelId, + }), + connectionHops: [connectionId], + version: "ics20-1", +}); + +export const identifiedChannel = IdentifiedChannel.fromPartial({ + state: ChannelState.STATE_OPEN, + ordering: Order.ORDER_UNORDERED, + counterparty: ChannelCounterparty.fromPartial({ + portId: portId, + channelId: "channel-0", + }), + connectionHops: [connectionId], + version: "ics20-1", + portId: portId, + channelId: channelId, +}); + +/** + * ``` + * jq ".channel_genesis.commitments[0]" scripts/simapp42/genesis-ibc.json + * ``` + */ +export const commitment = { + sequence: 1, + data: fromBase64("hYz5Dx6o09DcSEWZR6xlJYwLgYUnLithsXMGtujic4I="), +}; + +export const packetState = PacketState.fromPartial({ + portId: portId, + channelId: channelId, + sequence: Long.fromInt(commitment.sequence, true), + data: commitment.data, +}); + +/** + * Unfortunatly empty right now + * + * ``` + * jq ".channel_genesis.acknowledgements" scripts/simapp42/genesis-ibc.json + * ``` + */ +export const packetAcknowledgements: PacketState[] = []; + +export const connection = ConnectionEnd.fromPartial({ + clientId: clientId, + versions: [ + Version.fromPartial({ + identifier: "1", + features: ["ORDER_ORDERED", "ORDER_UNORDERED"], + }), + ], + state: ConnectionState.STATE_OPEN, + counterparty: ConnectionCounterparty.fromPartial({ + clientId: "07-tendermint-0", + connectionId: "connection-0", + prefix: MerklePrefix.fromPartial({ + keyPrefix: fromBase64("aWJj"), + }), + }), +}); + +export const identifiedConnection = IdentifiedConnection.fromPartial({ + id: connectionId, + clientId: clientId, + versions: [ + Version.fromPartial({ + identifier: "1", + features: ["ORDER_ORDERED", "ORDER_UNORDERED"], + }), + ], + state: ConnectionState.STATE_OPEN, + counterparty: ConnectionCounterparty.fromPartial({ + clientId: "07-tendermint-0", + connectionId: "connection-0", + prefix: MerklePrefix.fromPartial({ + keyPrefix: fromBase64("aWJj"), + }), + }), +}); diff --git a/src/queries/index.ts b/src/queries/index.ts new file mode 100644 index 0000000..f0cb2e7 --- /dev/null +++ b/src/queries/index.ts @@ -0,0 +1,20 @@ +// Base symbols + +export { QueryClient } from "./queryclient"; + +// Extensions + +export { AuthExtension, setupAuthExtension } from "./auth"; +export { BankExtension, setupBankExtension } from "./bank"; +export { DistributionExtension, setupDistributionExtension } from "./distribution"; +export { GovExtension, GovParamsType, GovProposalId, setupGovExtension } from "./gov"; +export { IbcExtension, setupIbcExtension } from "./ibc"; +export { MintExtension, MintParams, setupMintExtension } from "./mint"; +export { setupStakingExtension, StakingExtension } from "./staking"; +export { setupTxExtension, TxExtension } from "./tx"; +export { + createPagination, + createProtobufRpcClient, + decodeCosmosSdkDecFromProto, + ProtobufRpcClient, +} from "./utils"; diff --git a/src/queries/mint.spec.ts b/src/queries/mint.spec.ts new file mode 100644 index 0000000..ba9abfe --- /dev/null +++ b/src/queries/mint.spec.ts @@ -0,0 +1,58 @@ +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; + +import { QueryClient } from "../"; +import { pendingWithoutSimapp, simapp } from "../testutils.spec"; +import { MintExtension, setupMintExtension } from "./mint"; + +async function makeClientWithMint( + rpcUrl: string, +): Promise<[QueryClient & MintExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupMintExtension), tmClient]; +} + +describe("MintExtension", () => { + describe("params", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithMint(simapp.tendermintUrl); + + const params = await client.mint.params(); + expect(params.blocksPerYear.toNumber()).toBeGreaterThan(100_000); + expect(params.blocksPerYear.toNumber()).toBeLessThan(100_000_000); + expect(params.goalBonded.toString()).toEqual("0.67"); + expect(params.inflationMin.toString()).toEqual("0.07"); + expect(params.inflationMax.toString()).toEqual("0.2"); + expect(params.inflationRateChange.toString()).toEqual("0.13"); + expect(params.mintDenom).toEqual(simapp.denomStaking); + + tmClient.disconnect(); + }); + }); + + describe("inflation", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithMint(simapp.tendermintUrl); + + const inflation = await client.mint.inflation(); + expect(inflation.toFloatApproximation()).toBeGreaterThan(0.13); + expect(inflation.toFloatApproximation()).toBeLessThan(0.1301); + + tmClient.disconnect(); + }); + }); + + describe("annualProvisions", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithMint(simapp.tendermintUrl); + + const annualProvisions = await client.mint.annualProvisions(); + expect(annualProvisions.toFloatApproximation()).toBeGreaterThan(5_400_000_000); + expect(annualProvisions.toFloatApproximation()).toBeLessThan(5_500_000_000); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/mint.ts b/src/queries/mint.ts new file mode 100644 index 0000000..6928f06 --- /dev/null +++ b/src/queries/mint.ts @@ -0,0 +1,60 @@ +import { Decimal } from "@cosmjs/math"; +import { assert } from "@cosmjs/utils"; +import { Params } from "cosmjs-types/cosmos/mint/v1beta1/mint"; +import { QueryClientImpl } from "cosmjs-types/cosmos/mint/v1beta1/query"; + +import { createProtobufRpcClient } from "../"; +import { QueryClient } from "./queryclient"; +import { decodeCosmosSdkDecFromProto } from "./utils"; + +/** + * Like Params from "cosmjs-types/cosmos/mint/v1beta1/mint" + * but using decimal types. + */ +export interface MintParams extends Pick { + readonly goalBonded: Decimal; + readonly inflationMin: Decimal; + readonly inflationMax: Decimal; + readonly inflationRateChange: Decimal; +} + +export interface MintExtension { + readonly mint: { + readonly params: () => Promise; + readonly inflation: () => Promise; + readonly annualProvisions: () => Promise; + }; +} + +export function setupMintExtension(base: QueryClient): MintExtension { + const rpc = createProtobufRpcClient(base); + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const queryService = new QueryClientImpl(rpc); + + return { + mint: { + params: async (): Promise => { + const { params } = await queryService.Params({}); + assert(params); + + return { + blocksPerYear: params.blocksPerYear, + goalBonded: decodeCosmosSdkDecFromProto(params.goalBonded), + inflationMin: decodeCosmosSdkDecFromProto(params.inflationMin), + inflationMax: decodeCosmosSdkDecFromProto(params.inflationMax), + inflationRateChange: decodeCosmosSdkDecFromProto(params.inflationRateChange), + mintDenom: params.mintDenom, + }; + }, + inflation: async () => { + const { inflation } = await queryService.Inflation({}); + return decodeCosmosSdkDecFromProto(inflation); + }, + annualProvisions: async () => { + const { annualProvisions } = await queryService.AnnualProvisions({}); + return decodeCosmosSdkDecFromProto(annualProvisions); + }, + }, + }; +} diff --git a/src/queries/queryclient.spec.ts b/src/queries/queryclient.spec.ts new file mode 100644 index 0000000..db3f830 --- /dev/null +++ b/src/queries/queryclient.spec.ts @@ -0,0 +1,94 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { toAscii } from "@cosmjs/encoding"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { Metadata } from "cosmjs-types/cosmos/bank/v1beta1/bank"; +import { QueryAllBalancesRequest, QueryAllBalancesResponse } from "cosmjs-types/cosmos/bank/v1beta1/query"; + +import { pendingWithoutSimapp, simapp, unused } from "../testutils.spec"; +import { QueryClient } from "./queryclient"; + +async function makeClient(rpcUrl: string): Promise<[QueryClient, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient), tmClient]; +} + +/** + * See + * - https://github.com/cosmos/cosmos-sdk/blob/v0.42.10/x/bank/types/key.go#L27 + * - https://github.com/cosmos/cosmos-sdk/blob/v0.44.2/x/bank/types/key.go#L28 + */ +const denomMetadataPrefix = new Uint8Array([0x01]); + +describe("QueryClient", () => { + describe("queryVerified", () => { + it("works via WebSockets", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClient(simapp.tendermintUrlWs); + + // "keys before 0.45 had denom two times in the key" + // https://github.com/cosmos/cosmos-sdk/blob/10ad61a4dd/x/bank/migrations/v045/store_test.go#L91 + const key = Uint8Array.from([ + ...denomMetadataPrefix, + ...toAscii(simapp.denomFee), + ...toAscii(simapp.denomFee), + ]); + const data = await client.queryVerified("bank", key); + + const response = Metadata.decode(data); + expect(response.base).toEqual(simapp.denomFee); + expect(response.description).toEqual("The fee token of this test chain"); + + tmClient.disconnect(); + }); + + it("works via http", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClient(simapp.tendermintUrlHttp); + + // "keys before 0.45 had denom two times in the key" + // https://github.com/cosmos/cosmos-sdk/blob/10ad61a4dd/x/bank/migrations/v045/store_test.go#L91 + const key = Uint8Array.from([ + ...denomMetadataPrefix, + ...toAscii(simapp.denomFee), + ...toAscii(simapp.denomFee), + ]); + const data = await client.queryVerified("bank", key); + + const response = Metadata.decode(data); + expect(response.base).toEqual(simapp.denomFee); + expect(response.description).toEqual("The fee token of this test chain"); + + tmClient.disconnect(); + }); + }); + + describe("queryUnverified", () => { + it("works via WebSockets", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClient(simapp.tendermintUrlWs); + + const requestData = Uint8Array.from( + QueryAllBalancesRequest.encode({ address: unused.address }).finish(), + ); + const data = await client.queryUnverified(`/cosmos.bank.v1beta1.Query/AllBalances`, requestData); + const response = QueryAllBalancesResponse.decode(data); + expect(response.balances.length).toEqual(2); + + tmClient.disconnect(); + }); + + it("works via http", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClient(simapp.tendermintUrlHttp); + + const requestData = Uint8Array.from( + QueryAllBalancesRequest.encode({ address: unused.address }).finish(), + ); + const data = await client.queryUnverified(`/cosmos.bank.v1beta1.Query/AllBalances`, requestData); + const response = QueryAllBalancesResponse.decode(data); + expect(response.balances.length).toEqual(2); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/queryclient.ts b/src/queries/queryclient.ts new file mode 100644 index 0000000..5965cfa --- /dev/null +++ b/src/queries/queryclient.ts @@ -0,0 +1,627 @@ +/* eslint-disable no-dupe-class-members, @typescript-eslint/ban-types, @typescript-eslint/naming-convention */ +import { iavlSpec, ics23, tendermintSpec, verifyExistence, verifyNonExistence } from "@confio/ics23"; +import { toAscii, toHex } from "@cosmjs/encoding"; +import { firstEvent } from "@cosmjs/stream"; +import { tendermint34, Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { arrayContentEquals, assert, assertDefined, isNonNullObject, sleep } from "@cosmjs/utils"; +import { ProofOps } from "cosmjs-types/tendermint/crypto/proof"; +import { Stream } from "xstream"; + +type QueryExtensionSetup

= (base: QueryClient) => P; + +function checkAndParseOp(op: tendermint34.ProofOp, kind: string, key: Uint8Array): ics23.CommitmentProof { + if (op.type !== kind) { + throw new Error(`Op expected to be ${kind}, got "${op.type}`); + } + if (!arrayContentEquals(key, op.key)) { + throw new Error(`Proven key different than queried key.\nQuery: ${toHex(key)}\nProven: ${toHex(op.key)}`); + } + return ics23.CommitmentProof.decode(op.data); +} + +export interface ProvenQuery { + readonly key: Uint8Array; + readonly value: Uint8Array; + readonly proof: ProofOps; + readonly height: number; +} + +export class QueryClient { + /** Constructs a QueryClient with 0 extensions */ + public static withExtensions(tmClient: Tendermint34Client): QueryClient; + + /** Constructs a QueryClient with 1 extension */ + public static withExtensions( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + ): QueryClient & A; + + /** Constructs a QueryClient with 2 extensions */ + public static withExtensions( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + ): QueryClient & A & B; + + /** Constructs a QueryClient with 3 extensions */ + public static withExtensions( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + ): QueryClient & A & B & C; + + /** Constructs a QueryClient with 4 extensions */ + public static withExtensions( + tmClient: Tendermint34Client, + 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: Tendermint34Client, + 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: Tendermint34Client, + 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: Tendermint34Client, + 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: Tendermint34Client, + 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; + + /** Constructs a QueryClient with 9 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, + I extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I; + + /** Constructs a QueryClient with 10 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, + I extends object, + J extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J; + + /** Constructs a QueryClient with 11 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, + I extends object, + J extends object, + K extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K; + + /** Constructs a QueryClient with 12 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, + I extends object, + J extends object, + K extends object, + L extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L; + + /** Constructs a QueryClient with 13 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, + I extends object, + J extends object, + K extends object, + L extends object, + M extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + setupExtensionM: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L & M; + + /** Constructs a QueryClient with 14 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, + I extends object, + J extends object, + K extends object, + L extends object, + M extends object, + N extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + setupExtensionM: QueryExtensionSetup, + setupExtensionN: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L & M & N; + + /** Constructs a QueryClient with 15 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, + I extends object, + J extends object, + K extends object, + L extends object, + M extends object, + N extends object, + O extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + setupExtensionM: QueryExtensionSetup, + setupExtensionN: QueryExtensionSetup, + setupExtensionO: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L & M & N & O; + + /** Constructs a QueryClient with 16 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, + I extends object, + J extends object, + K extends object, + L extends object, + M extends object, + N extends object, + O extends object, + P extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + setupExtensionM: QueryExtensionSetup, + setupExtensionN: QueryExtensionSetup, + setupExtensionO: QueryExtensionSetup, + setupExtensionP: QueryExtensionSetup

, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P; + + /** Constructs a QueryClient with 17 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, + I extends object, + J extends object, + K extends object, + L extends object, + M extends object, + N extends object, + O extends object, + P extends object, + Q extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + setupExtensionM: QueryExtensionSetup, + setupExtensionN: QueryExtensionSetup, + setupExtensionO: QueryExtensionSetup, + setupExtensionP: QueryExtensionSetup

, + setupExtensionQ: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q; + + /** Constructs a QueryClient with 18 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, + I extends object, + J extends object, + K extends object, + L extends object, + M extends object, + N extends object, + O extends object, + P extends object, + Q extends object, + R extends object, + >( + tmClient: Tendermint34Client, + setupExtensionA: QueryExtensionSetup, + setupExtensionB: QueryExtensionSetup, + setupExtensionC: QueryExtensionSetup, + setupExtensionD: QueryExtensionSetup, + setupExtensionE: QueryExtensionSetup, + setupExtensionF: QueryExtensionSetup, + setupExtensionG: QueryExtensionSetup, + setupExtensionH: QueryExtensionSetup, + setupExtensionI: QueryExtensionSetup, + setupExtensionJ: QueryExtensionSetup, + setupExtensionK: QueryExtensionSetup, + setupExtensionL: QueryExtensionSetup, + setupExtensionM: QueryExtensionSetup, + setupExtensionN: QueryExtensionSetup, + setupExtensionO: QueryExtensionSetup, + setupExtensionP: QueryExtensionSetup

, + setupExtensionQ: QueryExtensionSetup, + setupExtensionR: QueryExtensionSetup, + ): QueryClient & A & B & C & D & E & F & G & H & I & J & K & L & M & N & O & P & Q & R; + + public static withExtensions( + tmClient: Tendermint34Client, + ...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: Tendermint34Client; + + public constructor(tmClient: Tendermint34Client) { + this.tmClient = tmClient; + } + + public async queryVerified(store: string, key: Uint8Array, desiredHeight?: number): Promise { + const { height, proof, value } = await this.queryRawProof(store, key, desiredHeight); + + const subProof = checkAndParseOp(proof.ops[0], "ics23:iavl", key); + const storeProof = checkAndParseOp(proof.ops[1], "ics23:simple", toAscii(store)); + + // this must always be existence, if the store is not a typo + assert(storeProof.exist); + assert(storeProof.exist.value); + + // this may be exist or non-exist, depends on response + if (!value || value.length === 0) { + // non-existence check + assert(subProof.nonexist); + // the subproof must map the desired key to the "value" of the storeProof + verifyNonExistence(subProof.nonexist, iavlSpec, storeProof.exist.value, key); + } else { + // existence check + assert(subProof.exist); + assert(subProof.exist.value); + // the subproof must map the desired key to the "value" of the storeProof + verifyExistence(subProof.exist, iavlSpec, storeProof.exist.value, key, value); + } + + // the store proof must map its declared value (root of subProof) to the appHash of the next block + const header = await this.getNextHeader(height); + verifyExistence(storeProof.exist, tendermintSpec, header.appHash, toAscii(store), storeProof.exist.value); + + return value; + } + + public async queryRawProof( + store: string, + queryKey: Uint8Array, + desiredHeight?: number, + ): Promise { + const { key, value, height, proof, code, log } = 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: queryKey, + prove: true, + height: desiredHeight, + }); + + if (code) { + throw new Error(`Query failed with (${code}): ${log}`); + } + + if (!arrayContentEquals(queryKey, key)) { + throw new Error(`Response key ${toHex(key)} doesn't match query key ${toHex(queryKey)}`); + } + + if (!height) { + throw new Error("No query height returned"); + } + if (!proof || proof.ops.length !== 2) { + throw new Error(`Expected 2 proof ops, got ${proof?.ops.length ?? 0}. Are you using stargate?`); + } + + // we don't need the results, but we can ensure the data is the proper format + checkAndParseOp(proof.ops[0], "ics23:iavl", key); + checkAndParseOp(proof.ops[1], "ics23:simple", toAscii(store)); + + return { + key: key, + value: value, + height: height, + // need to clone this: readonly input / writeable output + proof: { + ops: [...proof.ops], + }, + }; + } + + 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; + } + + // this must return the header for height+1 + // throws an error if height is 0 or undefined + private async getNextHeader(height?: number): Promise { + assertDefined(height); + if (height === 0) { + throw new Error("Query returned height 0, cannot prove it"); + } + + const searchHeight = height + 1; + let nextHeader: tendermint34.Header | undefined; + let headersSubscription: Stream | undefined; + try { + headersSubscription = this.tmClient.subscribeNewBlockHeader(); + } catch { + // Ignore exception caused by non-WebSocket Tendermint clients + } + + if (headersSubscription) { + const firstHeader = await firstEvent(headersSubscription); + // The first header we get might not be n+1 but n+2 or even higher. In such cases we fall back on a query. + if (firstHeader.height === searchHeight) { + nextHeader = firstHeader; + } + } + + while (!nextHeader) { + // start from current height to avoid backend error for minHeight in the future + const correctHeader = (await this.tmClient.blockchain(height, searchHeight)).blockMetas + .map((meta) => meta.header) + .find((h) => h.height === searchHeight); + if (correctHeader) { + nextHeader = correctHeader; + } else { + await sleep(1000); + } + } + + assert(nextHeader.height === searchHeight, "Got wrong header. This is a bug in the logic above."); + return nextHeader; + } +} diff --git a/src/queries/staking.spec.ts b/src/queries/staking.spec.ts new file mode 100644 index 0000000..ba5ad2d --- /dev/null +++ b/src/queries/staking.spec.ts @@ -0,0 +1,258 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { coin, coins, DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { sleep } from "@cosmjs/utils"; +import { MsgDelegate, MsgUndelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; + +import { MsgDelegateEncodeObject, MsgUndelegateEncodeObject } from "../encodeobjects"; +import { SigningStargateClient } from "../signingstargateclient"; +import { assertIsDeliverTxSuccess } from "../stargateclient"; +import { + defaultSigningClientOptions, + faucet, + pendingWithoutSimapp, + simapp, + simappEnabled, + validator, +} from "../testutils.spec"; +import { QueryClient } from "./queryclient"; +import { setupStakingExtension, StakingExtension } from "./staking"; + +async function makeClientWithStaking( + rpcUrl: string, +): Promise<[QueryClient & StakingExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupStakingExtension), tmClient]; +} + +describe("StakingExtension", () => { + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + + beforeAll(async () => { + if (simappEnabled()) { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + { + const msg: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(25000, "ustake"), + }; + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const memo = "Test delegation for Stargate"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], defaultFee, memo); + assertIsDeliverTxSuccess(result); + } + { + const msg: MsgUndelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(100, "ustake"), + }; + const msgAny: MsgUndelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: msg, + }; + const memo = "Test undelegation for Stargate"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], defaultFee, memo); + assertIsDeliverTxSuccess(result); + } + + await sleep(75); // wait until transactions are indexed + } + }); + + describe("delegation", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.delegation(faucet.address0, validator.validatorAddress); + expect(response.delegationResponse).toBeDefined(); + expect(response.delegationResponse).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegatorDelegations", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.delegatorDelegations(faucet.address0); + expect(response.delegationResponses).toBeDefined(); + expect(response.delegationResponses).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegatorUnbondingDelegations", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.delegatorUnbondingDelegations(faucet.address0); + expect(response.unbondingResponses).toBeDefined(); + expect(response.unbondingResponses).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegatorValidator", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.delegatorValidator(faucet.address0, validator.validatorAddress); + expect(response.validator).toBeDefined(); + expect(response.validator).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("delegatorValidators", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.delegatorValidators(faucet.address0); + expect(response.validators).toBeDefined(); + expect(response.validators).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("historicalInfo", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.historicalInfo(5); + expect(response.hist).toBeDefined(); + expect(response.hist).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("params", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.params(); + expect(response.params).toBeDefined(); + expect(response.params).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("pool", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.pool(); + expect(response.pool).toBeDefined(); + expect(response.pool).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("redelegations", () => { + it("works", async () => { + // TODO: Set up a result for this test + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + await expectAsync( + client.staking.redelegations(faucet.address0, validator.validatorAddress, validator.validatorAddress), + ).toBeRejectedWithError(/redelegation not found/i); + + tmClient.disconnect(); + }); + }); + + describe("unbondingDelegation", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.unbondingDelegation(faucet.address0, validator.validatorAddress); + expect(response.unbond).toBeDefined(); + expect(response.unbond).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validator", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.validator(validator.validatorAddress); + expect(response.validator).toBeDefined(); + expect(response.validator).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validatorDelegations", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.validatorDelegations(validator.validatorAddress); + expect(response.delegationResponses).toBeDefined(); + expect(response.delegationResponses).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validators", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.validators("BOND_STATUS_BONDED"); + expect(response.validators).toBeDefined(); + expect(response.validators).not.toBeNull(); + + tmClient.disconnect(); + }); + }); + + describe("validatorUnbondingDelegations", () => { + it("works", async () => { + pendingWithoutSimapp(); + const [client, tmClient] = await makeClientWithStaking(simapp.tendermintUrl); + + const response = await client.staking.validatorUnbondingDelegations(validator.validatorAddress); + expect(response.unbondingResponses).toBeDefined(); + expect(response.unbondingResponses).not.toBeNull(); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/staking.ts b/src/queries/staking.ts new file mode 100644 index 0000000..592f2b8 --- /dev/null +++ b/src/queries/staking.ts @@ -0,0 +1,177 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { + QueryClientImpl, + QueryDelegationResponse, + QueryDelegatorDelegationsResponse, + QueryDelegatorUnbondingDelegationsResponse, + QueryDelegatorValidatorResponse, + QueryDelegatorValidatorsResponse, + QueryHistoricalInfoResponse, + QueryParamsResponse, + QueryPoolResponse, + QueryRedelegationsResponse, + QueryUnbondingDelegationResponse, + QueryValidatorDelegationsResponse, + QueryValidatorResponse, + QueryValidatorsResponse, + QueryValidatorUnbondingDelegationsResponse, +} from "cosmjs-types/cosmos/staking/v1beta1/query"; +import { BondStatus } from "cosmjs-types/cosmos/staking/v1beta1/staking"; +import Long from "long"; + +import { QueryClient } from "./queryclient"; +import { createPagination, createProtobufRpcClient } from "./utils"; + +export type BondStatusString = Exclude; + +export interface StakingExtension { + readonly staking: { + delegation: (delegatorAddress: string, validatorAddress: string) => Promise; + delegatorDelegations: ( + delegatorAddress: string, + paginationKey?: Uint8Array, + ) => Promise; + delegatorUnbondingDelegations: ( + delegatorAddress: string, + paginationKey?: Uint8Array, + ) => Promise; + delegatorValidator: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + delegatorValidators: ( + delegatorAddress: string, + paginationKey?: Uint8Array, + ) => Promise; + historicalInfo: (height: number) => Promise; + params: () => Promise; + pool: () => Promise; + redelegations: ( + delegatorAddress: string, + sourceValidatorAddress: string, + destinationValidatorAddress: string, + paginationKey?: Uint8Array, + ) => Promise; + unbondingDelegation: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + validator: (validatorAddress: string) => Promise; + validatorDelegations: ( + validatorAddress: string, + paginationKey?: Uint8Array, + ) => Promise; + validators: (status: BondStatusString, paginationKey?: Uint8Array) => Promise; + validatorUnbondingDelegations: ( + validatorAddress: string, + paginationKey?: Uint8Array, + ) => Promise; + }; +} + +export function setupStakingExtension(base: QueryClient): StakingExtension { + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const rpc = createProtobufRpcClient(base); + const queryService = new QueryClientImpl(rpc); + + return { + staking: { + delegation: async (delegatorAddress: string, validatorAddress: string) => { + const response = await queryService.Delegation({ + delegatorAddr: delegatorAddress, + validatorAddr: validatorAddress, + }); + return response; + }, + delegatorDelegations: async (delegatorAddress: string, paginationKey?: Uint8Array) => { + const response = await queryService.DelegatorDelegations({ + delegatorAddr: delegatorAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + delegatorUnbondingDelegations: async (delegatorAddress: string, paginationKey?: Uint8Array) => { + const response = await queryService.DelegatorUnbondingDelegations({ + delegatorAddr: delegatorAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + delegatorValidator: async (delegatorAddress: string, validatorAddress: string) => { + const response = await queryService.DelegatorValidator({ + delegatorAddr: delegatorAddress, + validatorAddr: validatorAddress, + }); + return response; + }, + delegatorValidators: async (delegatorAddress: string, paginationKey?: Uint8Array) => { + const response = await queryService.DelegatorValidators({ + delegatorAddr: delegatorAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + historicalInfo: async (height: number) => { + const response = await queryService.HistoricalInfo({ + height: Long.fromNumber(height, true), + }); + return response; + }, + params: async () => { + const response = await queryService.Params({}); + return response; + }, + pool: async () => { + const response = await queryService.Pool({}); + return response; + }, + redelegations: async ( + delegatorAddress: string, + sourceValidatorAddress: string, + destinationValidatorAddress: string, + paginationKey?: Uint8Array, + ) => { + const response = await queryService.Redelegations({ + delegatorAddr: delegatorAddress, + srcValidatorAddr: sourceValidatorAddress, + dstValidatorAddr: destinationValidatorAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + unbondingDelegation: async (delegatorAddress: string, validatorAddress: string) => { + const response = await queryService.UnbondingDelegation({ + delegatorAddr: delegatorAddress, + validatorAddr: validatorAddress, + }); + return response; + }, + validator: async (validatorAddress: string) => { + const response = await queryService.Validator({ validatorAddr: validatorAddress }); + return response; + }, + validatorDelegations: async (validatorAddress: string, paginationKey?: Uint8Array) => { + const response = await queryService.ValidatorDelegations({ + validatorAddr: validatorAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + validators: async (status: BondStatusString, paginationKey?: Uint8Array) => { + const response = await queryService.Validators({ + status: status, + pagination: createPagination(paginationKey), + }); + return response; + }, + validatorUnbondingDelegations: async (validatorAddress: string, paginationKey?: Uint8Array) => { + const response = await queryService.ValidatorUnbondingDelegations({ + validatorAddr: validatorAddress, + pagination: createPagination(paginationKey), + }); + return response; + }, + }, + }; +} diff --git a/src/queries/tx.spec.ts b/src/queries/tx.spec.ts new file mode 100644 index 0000000..19e09a5 --- /dev/null +++ b/src/queries/tx.spec.ts @@ -0,0 +1,104 @@ +import { coin, coins, DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { assertDefined, sleep } from "@cosmjs/utils"; +import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import Long from "long"; + +import { defaultRegistryTypes, SigningStargateClient } from "../signingstargateclient"; +import { assertIsDeliverTxSuccess, StargateClient } from "../stargateclient"; +import { + defaultSigningClientOptions, + faucet, + makeRandomAddress, + pendingWithoutSimapp, + simapp, + simappEnabled, + validator, +} from "../testutils.spec"; +import { QueryClient } from "./queryclient"; +import { setupTxExtension, TxExtension } from "./tx"; +import { longify } from "./utils"; + +async function makeClientWithTx(rpcUrl: string): Promise<[QueryClient & TxExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupTxExtension), tmClient]; +} + +describe("TxExtension", () => { + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + let txHash: string | undefined; + let memo: string | undefined; + + beforeAll(async () => { + if (simappEnabled()) { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + { + const recipient = makeRandomAddress(); + memo = `Test tx ${Date.now()}`; + const result = await client.sendTokens( + faucet.address0, + recipient, + coins(25000, "ucosm"), + defaultFee, + memo, + ); + assertIsDeliverTxSuccess(result); + txHash = result.transactionHash; + } + + await sleep(75); // wait until transactions are indexed + } + }); + + describe("getTx", () => { + it("works", async () => { + pendingWithoutSimapp(); + assertDefined(txHash); + assertDefined(memo); + const [client, tmClient] = await makeClientWithTx(simapp.tendermintUrl); + + const response = await client.tx.getTx(txHash); + expect(response.tx?.body?.memo).toEqual(memo); + + tmClient.disconnect(); + }); + }); + + describe("simulate", () => { + it("works", async () => { + pendingWithoutSimapp(); + assertDefined(txHash); + assertDefined(memo); + const [client, tmClient] = await makeClientWithTx(simapp.tendermintUrl); + const sequenceClient = await StargateClient.connect(simapp.tendermintUrl); + + const registry = new Registry(defaultRegistryTypes); + const msg: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(25000, "ustake"), + }; + const msgAny = registry.encodeAsAny({ + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }); + + const { sequence } = await sequenceClient.getSequence(faucet.address0); + const response = await client.tx.simulate([msgAny], "foo", faucet.pubkey0, sequence); + expect(response.gasInfo?.gasUsed.toNumber()).toBeGreaterThanOrEqual(101_000); + expect(response.gasInfo?.gasUsed.toNumber()).toBeLessThanOrEqual(150_000); + expect(response.gasInfo?.gasWanted).toEqual(longify(Long.UZERO)); + + tmClient.disconnect(); + }); + }); +}); diff --git a/src/queries/tx.ts b/src/queries/tx.ts new file mode 100644 index 0000000..ca591d3 --- /dev/null +++ b/src/queries/tx.ts @@ -0,0 +1,81 @@ +import { Pubkey } from "@cosmjs/amino"; +import { encodePubkey } from "@cosmjs/proto-signing"; +import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; +import { + GetTxRequest, + GetTxResponse, + ServiceClientImpl, + SimulateRequest, + SimulateResponse, +} from "cosmjs-types/cosmos/tx/v1beta1/service"; +import { AuthInfo, Fee, Tx, TxBody } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import { Any } from "cosmjs-types/google/protobuf/any"; +import Long from "long"; + +import { QueryClient } from "./queryclient"; +import { createProtobufRpcClient } from "./utils"; + +export interface TxExtension { + readonly tx: { + getTx: (txId: string) => Promise; + simulate: ( + messages: readonly Any[], + memo: string | undefined, + signer: Pubkey, + sequence: number, + ) => Promise; + // Add here with tests: + // - broadcastTx + // - getTxsEvent + }; +} + +export function setupTxExtension(base: QueryClient): TxExtension { + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const rpc = createProtobufRpcClient(base); + const queryService = new ServiceClientImpl(rpc); + + return { + tx: { + getTx: async (txId: string) => { + const request: GetTxRequest = { + hash: txId, + }; + const response = await queryService.GetTx(request); + return response; + }, + simulate: async ( + messages: readonly Any[], + memo: string | undefined, + signer: Pubkey, + sequence: number, + ) => { + const request = SimulateRequest.fromPartial({ + tx: Tx.fromPartial({ + authInfo: AuthInfo.fromPartial({ + fee: Fee.fromPartial({}), + signerInfos: [ + { + publicKey: encodePubkey(signer), + sequence: Long.fromNumber(sequence, true), + modeInfo: { single: { mode: SignMode.SIGN_MODE_UNSPECIFIED } }, + }, + ], + }), + body: TxBody.fromPartial({ + messages: Array.from(messages), + memo: memo, + }), + signatures: [new Uint8Array()], + }), + // Sending serialized `txBytes` is the future. But + // this is not available in Comsos SDK 0.42. + txBytes: undefined, + }); + const response = await queryService.Simulate(request); + return response; + }, + }, + }; +} diff --git a/src/queries/utils.spec.ts b/src/queries/utils.spec.ts new file mode 100644 index 0000000..703efca --- /dev/null +++ b/src/queries/utils.spec.ts @@ -0,0 +1,21 @@ +import { fromHex } from "@cosmjs/encoding"; + +import { decodeCosmosSdkDecFromProto } from "./utils"; + +describe("utils", () => { + describe("decodeCosmosSdkDecFromProto", () => { + it("works for string inputs", () => { + expect(decodeCosmosSdkDecFromProto("0").toString()).toEqual("0"); + expect(decodeCosmosSdkDecFromProto("1").toString()).toEqual("0.000000000000000001"); + expect(decodeCosmosSdkDecFromProto("3000000").toString()).toEqual("0.000000000003"); + expect(decodeCosmosSdkDecFromProto("123456789123456789").toString()).toEqual("0.123456789123456789"); + expect(decodeCosmosSdkDecFromProto("1234567891234567890").toString()).toEqual("1.23456789123456789"); + }); + + it("works for byte inputs", () => { + expect(decodeCosmosSdkDecFromProto(fromHex("313330303033343138373830313631333938")).toString()).toEqual( + "0.130003418780161398", + ); + }); + }); +}); diff --git a/src/queries/utils.ts b/src/queries/utils.ts new file mode 100644 index 0000000..c931727 --- /dev/null +++ b/src/queries/utils.ts @@ -0,0 +1,66 @@ +import { Bech32, fromAscii } from "@cosmjs/encoding"; +import { Decimal, Uint64 } from "@cosmjs/math"; +import { PageRequest } from "cosmjs-types/cosmos/base/query/v1beta1/pagination"; +import Long from "long"; + +import { QueryClient } from "./queryclient"; + +/** + * 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; +} + +/** + * If paginationKey is set, return a `PageRequest` with the given key. + * If paginationKey is unset, return `undefined`. + * + * Use this with a query response's pagination next key to + * request the next page. + */ +export function createPagination(paginationKey?: Uint8Array): PageRequest | undefined { + return paginationKey + ? PageRequest.fromPartial({ + key: paginationKey, + offset: Long.fromNumber(0, true), + limit: Long.fromNumber(0, true), + countTotal: false, + }) + : undefined; +} + +export interface ProtobufRpcClient { + request(service: string, method: string, data: Uint8Array): Promise; +} + +export function createProtobufRpcClient(base: QueryClient): ProtobufRpcClient { + return { + request: (service: string, method: string, data: Uint8Array): Promise => { + const path = `/${service}/${method}`; + return base.queryUnverified(path, data); + }, + }; +} + +/** + * Takes a uint64 value as string, number, Long or Uint64 and returns an unsigned Long instance + * of it. + */ +export function longify(value: string | number | Long | Uint64): Long { + const checkedValue = Uint64.fromString(value.toString()); + return Long.fromBytesBE([...checkedValue.toBytesBigEndian()], true); +} + +/** + * Takes a string or binary encoded `github.com/cosmos/cosmos-sdk/types.Dec` from the + * protobuf API and converts it into a `Decimal` with 18 fractional digits. + * + * See https://github.com/cosmos/cosmos-sdk/issues/10863 for more context why this is needed. + */ +export function decodeCosmosSdkDecFromProto(input: string | Uint8Array): Decimal { + const asString = typeof input === "string" ? input : fromAscii(input); + return Decimal.fromAtomics(asString, 18); +} diff --git a/src/search.ts b/src/search.ts new file mode 100644 index 0000000..aae6150 --- /dev/null +++ b/src/search.ts @@ -0,0 +1,34 @@ +export interface SearchByHeightQuery { + readonly height: number; +} + +export interface SearchBySentFromOrToQuery { + readonly sentFromOrTo: string; +} + +/** + * This query type allows you to pass arbitrary key/value pairs to the backend. It is + * more powerful and slightly lower level than the other search options. + */ +export interface SearchByTagsQuery { + readonly tags: ReadonlyArray<{ readonly key: string; readonly value: string }>; +} + +export type SearchTxQuery = SearchByHeightQuery | SearchBySentFromOrToQuery | SearchByTagsQuery; + +export function isSearchByHeightQuery(query: SearchTxQuery): query is SearchByHeightQuery { + return (query as SearchByHeightQuery).height !== undefined; +} + +export function isSearchBySentFromOrToQuery(query: SearchTxQuery): query is SearchBySentFromOrToQuery { + return (query as SearchBySentFromOrToQuery).sentFromOrTo !== undefined; +} + +export function isSearchByTagsQuery(query: SearchTxQuery): query is SearchByTagsQuery { + return (query as SearchByTagsQuery).tags !== undefined; +} + +export interface SearchTxFilter { + readonly minHeight?: number; + readonly maxHeight?: number; +} diff --git a/src/signingstargateclient.spec.ts b/src/signingstargateclient.spec.ts new file mode 100644 index 0000000..67c0c97 --- /dev/null +++ b/src/signingstargateclient.spec.ts @@ -0,0 +1,875 @@ +/* eslint-disable @typescript-eslint/naming-convention,no-bitwise */ +import { Secp256k1HdWallet } from "@cosmjs/amino"; +import { coin, coins, decodeTxRaw, DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing"; +import { assert, sleep } from "@cosmjs/utils"; +import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; +import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; +import { DeepPartial, MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import { AuthInfo, TxBody, TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import Long from "long"; +import protobuf from "protobufjs/minimal"; + +import { AminoMsgDelegate } from "./aminomsgs"; +import { AminoTypes } from "./aminotypes"; +import { MsgDelegateEncodeObject, MsgSendEncodeObject } from "./encodeobjects"; +import { PrivateSigningStargateClient, SigningStargateClient } from "./signingstargateclient"; +import { assertIsDeliverTxFailure, assertIsDeliverTxSuccess, isDeliverTxFailure } from "./stargateclient"; +import { + defaultGasPrice, + defaultSendFee, + defaultSigningClientOptions, + faucet, + makeRandomAddress, + ModifyingDirectSecp256k1HdWallet, + ModifyingSecp256k1HdWallet, + pendingWithoutSimapp, + pendingWithoutSimapp42, + simapp, + validator, +} from "./testutils.spec"; + +describe("SigningStargateClient", () => { + describe("constructor", () => { + it("can be constructed with custom registry", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const registry = new Registry(); + registry.register("/custom.MsgCustom", MsgSend); + const options = { ...defaultSigningClientOptions, registry: registry }; + const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet, options); + const openedClient = client as unknown as PrivateSigningStargateClient; + expect(openedClient.registry.lookupType("/custom.MsgCustom")).toEqual(MsgSend); + }); + }); + + describe("simulate", () => { + it("works", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg = MsgDelegate.fromPartial({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const memo = "Use your power wisely"; + const gasUsed = await client.simulate(faucet.address0, [msgAny], memo); + expect(gasUsed).toBeGreaterThanOrEqual(101_000); + expect(gasUsed).toBeLessThanOrEqual(150_000); + + client.disconnect(); + }); + }); + + describe("sendTokens", () => { + it("works with direct signer", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const amount = coins(7890, "ucosm"); + const beneficiaryAddress = makeRandomAddress(); + const memo = "for dinner"; + + // no tokens here + const before = await client.getBalance(beneficiaryAddress, "ucosm"); + expect(before).toEqual({ + denom: "ucosm", + amount: "0", + }); + + // send + const result = await client.sendTokens( + faucet.address0, + beneficiaryAddress, + amount, + defaultSendFee, + memo, + ); + assertIsDeliverTxSuccess(result); + expect(result.rawLog).toBeTruthy(); + + // got tokens + const after = await client.getBalance(beneficiaryAddress, "ucosm"); + expect(after).toEqual(amount[0]); + }); + + it("works with legacy Amino signer", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const amount = coins(7890, "ucosm"); + const beneficiaryAddress = makeRandomAddress(); + const memo = "for dinner"; + + // no tokens here + const before = await client.getBalance(beneficiaryAddress, "ucosm"); + expect(before).toEqual({ + denom: "ucosm", + amount: "0", + }); + + // send + const result = await client.sendTokens( + faucet.address0, + beneficiaryAddress, + amount, + defaultSendFee, + memo, + ); + assertIsDeliverTxSuccess(result); + expect(result.rawLog).toBeTruthy(); + + // got tokens + const after = await client.getBalance(beneficiaryAddress, "ucosm"); + expect(after).toEqual(amount[0]); + }); + }); + + describe("sendIbcTokens", () => { + it("works with direct signing", async () => { + pendingWithoutSimapp42(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + const memo = "Cross-chain fun"; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + + // both timeouts set + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + { revisionHeight: Long.fromNumber(123), revisionNumber: Long.fromNumber(456) }, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isDeliverTxFailure(result)).toEqual(true); + } + + // no height timeout + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + undefined, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isDeliverTxFailure(result)).toEqual(true); + } + }); + + it("works with Amino signing", async () => { + pendingWithoutSimapp42(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + const memo = "Cross-chain fun"; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + + // both timeouts set + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + { revisionHeight: Long.fromNumber(123), revisionNumber: Long.fromNumber(456) }, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isDeliverTxFailure(result)).toEqual(true); + } + + // no height timeout + { + const result = await client.sendIbcTokens( + faucet.address0, + faucet.address1, + coin(1234, "ucosm"), + "fooPort", + "fooChannel", + undefined, + Math.floor(Date.now() / 1000) + 60, + fee, + memo, + ); + // CheckTx must pass but the execution must fail in DeliverTx due to invalid channel/port + expect(isDeliverTxFailure(result)).toEqual(true); + } + }); + }); + + describe("signAndBroadcast", () => { + describe("direct mode", () => { + it("works", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg = MsgDelegate.fromPartial({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + const memo = "Use your power wisely"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee, memo); + assertIsDeliverTxSuccess(result); + expect(result.code).toEqual(0); + expect(result.gasWanted).toEqual(180_000); + expect(result.gasUsed).toBeLessThanOrEqual(180_000); + expect(result.gasUsed).toBeGreaterThan(100_000); + }); + + it("returns DeliverTxFailure on DeliverTx failure", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg = MsgSend.fromPartial({ + fromAddress: faucet.address0, + toAddress: makeRandomAddress(), + amount: coins(Number.MAX_SAFE_INTEGER, "ustake"), + }); + const msgAny: MsgSendEncodeObject = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "99000", + }; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee); + assertIsDeliverTxFailure(result); + expect(result.code).toBeGreaterThan(0); + expect(result.gasWanted).toEqual(99_000); + expect(result.gasUsed).toBeLessThanOrEqual(99_000); + expect(result.gasUsed).toBeGreaterThan(40_000); + }); + + it("works with auto gas", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet, { + ...defaultSigningClientOptions, + gasPrice: defaultGasPrice, + }); + + const msg = MsgDelegate.fromPartial({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], "auto"); + assertIsDeliverTxSuccess(result); + }); + + it("works with a modifying signer", async () => { + pendingWithoutSimapp(); + const wallet = await ModifyingDirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg = MsgDelegate.fromPartial({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + const memo = "Use your power wisely"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee, memo); + assertIsDeliverTxSuccess(result); + + await sleep(1000); + + const searchResult = await client.getTx(result.transactionHash); + assert(searchResult, "Must find transaction"); + const tx = decodeTxRaw(searchResult.tx); + // From ModifyingDirectSecp256k1HdWallet + expect(tx.body.memo).toEqual("This was modified"); + expect({ ...tx.authInfo.fee!.amount[0] }).toEqual(coin(3000, "ucosm")); + expect(tx.authInfo.fee!.gasLimit.toNumber()).toEqual(333333); + }); + }); + + describe("legacy Amino mode", () => { + it("works with bank MsgSend", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msgSend: MsgSend = { + fromAddress: faucet.address0, + toAddress: makeRandomAddress(), + amount: coins(1234, "ucosm"), + }; + const msgAny: MsgSendEncodeObject = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msgSend, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const memo = "Use your tokens wisely"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee, memo); + assertIsDeliverTxSuccess(result); + }); + + it("works with staking MsgDelegate", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msgDelegate: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }; + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msgDelegate, + }; + const fee = { + amount: coins(2000, "ustake"), + gas: "200000", + }; + const memo = "Use your tokens wisely"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee, memo); + assertIsDeliverTxSuccess(result); + }); + + it("works with a custom registry and custom message", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + + const customRegistry = new Registry(); + const msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate"; + interface CustomMsgDelegate { + customDelegatorAddress?: string; + customValidatorAddress?: string; + customAmount?: Coin; + } + const baseCustomMsgDelegate: CustomMsgDelegate = { + customDelegatorAddress: "", + customValidatorAddress: "", + }; + const CustomMsgDelegate = { + // Adapted from autogenerated MsgDelegate implementation + encode( + message: CustomMsgDelegate, + writer: protobuf.Writer = protobuf.Writer.create(), + ): protobuf.Writer { + writer.uint32(10).string(message.customDelegatorAddress ?? ""); + writer.uint32(18).string(message.customValidatorAddress ?? ""); + if (message.customAmount !== undefined && message.customAmount !== undefined) { + Coin.encode(message.customAmount, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(): CustomMsgDelegate { + throw new Error("decode method should not be required"); + }, + + fromJSON(): CustomMsgDelegate { + throw new Error("fromJSON method should not be required"); + }, + + fromPartial(object: DeepPartial): CustomMsgDelegate { + const message = { ...baseCustomMsgDelegate } as CustomMsgDelegate; + if (object.customDelegatorAddress !== undefined && object.customDelegatorAddress !== null) { + message.customDelegatorAddress = object.customDelegatorAddress; + } else { + message.customDelegatorAddress = ""; + } + if (object.customValidatorAddress !== undefined && object.customValidatorAddress !== null) { + message.customValidatorAddress = object.customValidatorAddress; + } else { + message.customValidatorAddress = ""; + } + if (object.customAmount !== undefined && object.customAmount !== null) { + message.customAmount = Coin.fromPartial(object.customAmount); + } else { + message.customAmount = undefined; + } + return message; + }, + + toJSON(): unknown { + throw new Error("toJSON method should not be required"); + }, + }; + customRegistry.register(msgDelegateTypeUrl, CustomMsgDelegate); + const customAminoTypes = new AminoTypes({ + additions: { + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: ({ + customDelegatorAddress, + customValidatorAddress, + customAmount, + }: CustomMsgDelegate): AminoMsgDelegate["value"] => { + assert(customDelegatorAddress, "missing customDelegatorAddress"); + assert(customValidatorAddress, "missing validatorAddress"); + assert(customAmount, "missing amount"); + return { + delegator_address: customDelegatorAddress, + validator_address: customValidatorAddress, + amount: { + amount: customAmount.amount, + denom: customAmount.denom, + }, + }; + }, + fromAmino: ({ + delegator_address, + validator_address, + amount, + }: AminoMsgDelegate["value"]): CustomMsgDelegate => ({ + customDelegatorAddress: delegator_address, + customValidatorAddress: validator_address, + customAmount: Coin.fromPartial(amount), + }), + }, + }, + }); + const options = { + ...defaultSigningClientOptions, + registry: customRegistry, + aminoTypes: customAminoTypes, + }; + const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet, options); + + const msg: CustomMsgDelegate = { + customDelegatorAddress: faucet.address0, + customValidatorAddress: validator.validatorAddress, + customAmount: coin(1234, "ustake"), + }; + const msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const memo = "Use your power wisely"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee, memo); + assertIsDeliverTxSuccess(result); + }); + + it("works with a modifying signer", async () => { + pendingWithoutSimapp(); + const wallet = await ModifyingSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }; + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const memo = "Use your power wisely"; + const result = await client.signAndBroadcast(faucet.address0, [msgAny], fee, memo); + assertIsDeliverTxSuccess(result); + + await sleep(1000); + + const searchResult = await client.getTx(result.transactionHash); + assert(searchResult, "Must find transaction"); + const tx = decodeTxRaw(searchResult.tx); + // From ModifyingSecp256k1HdWallet + expect(tx.body.memo).toEqual("This was modified"); + expect({ ...tx.authInfo.fee!.amount[0] }).toEqual(coin(3000, "ucosm")); + expect(tx.authInfo.fee!.gasLimit.toNumber()).toEqual(333333); + }); + }); + }); + + describe("sign", () => { + describe("direct mode", () => { + it("works", async () => { + pendingWithoutSimapp(); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg = MsgDelegate.fromPartial({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + const memo = "Use your power wisely"; + const signed = await client.sign(faucet.address0, [msgAny], fee, memo); + + // ensure signature is valid + const result = await client.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish())); + assertIsDeliverTxSuccess(result); + }); + + it("works with a modifying signer", async () => { + pendingWithoutSimapp(); + const wallet = await ModifyingDirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg = MsgDelegate.fromPartial({ + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }); + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "180000", // 180k + }; + const memo = "Use your power wisely"; + const signed = await client.sign(faucet.address0, [msgAny], fee, memo); + + const body = TxBody.decode(signed.bodyBytes); + const authInfo = AuthInfo.decode(signed.authInfoBytes); + // From ModifyingDirectSecp256k1HdWallet + expect(body.memo).toEqual("This was modified"); + expect({ ...authInfo.fee!.amount[0] }).toEqual(coin(3000, "ucosm")); + expect(authInfo.fee!.gasLimit.toNumber()).toEqual(333333); + + // ensure signature is valid + const result = await client.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish())); + assertIsDeliverTxSuccess(result); + }); + }); + + describe("legacy Amino mode", () => { + it("works with bank MsgSend", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msgSend: MsgSend = { + fromAddress: faucet.address0, + toAddress: makeRandomAddress(), + amount: coins(1234, "ucosm"), + }; + const msgAny: MsgSendEncodeObject = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: msgSend, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const memo = "Use your tokens wisely"; + const signed = await client.sign(faucet.address0, [msgAny], fee, memo); + + // ensure signature is valid + const result = await client.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish())); + assertIsDeliverTxSuccess(result); + }); + + it("works with staking MsgDelegate", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msgDelegate: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }; + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msgDelegate, + }; + const fee = { + amount: coins(2000, "ustake"), + gas: "200000", + }; + const memo = "Use your tokens wisely"; + const signed = await client.sign(faucet.address0, [msgAny], fee, memo); + + // ensure signature is valid + const result = await client.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish())); + assertIsDeliverTxSuccess(result); + }); + + it("works with a custom registry and custom message", async () => { + pendingWithoutSimapp(); + const wallet = await Secp256k1HdWallet.fromMnemonic(faucet.mnemonic); + + const customRegistry = new Registry(); + const msgDelegateTypeUrl = "/cosmos.staking.v1beta1.MsgDelegate"; + interface CustomMsgDelegate { + customDelegatorAddress?: string; + customValidatorAddress?: string; + customAmount?: Coin; + } + const baseCustomMsgDelegate: CustomMsgDelegate = { + customDelegatorAddress: "", + customValidatorAddress: "", + }; + const CustomMsgDelegate = { + // Adapted from autogenerated MsgDelegate implementation + encode( + message: CustomMsgDelegate, + writer: protobuf.Writer = protobuf.Writer.create(), + ): protobuf.Writer { + writer.uint32(10).string(message.customDelegatorAddress ?? ""); + writer.uint32(18).string(message.customValidatorAddress ?? ""); + if (message.customAmount !== undefined && message.customAmount !== undefined) { + Coin.encode(message.customAmount, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(): CustomMsgDelegate { + throw new Error("decode method should not be required"); + }, + + fromJSON(): CustomMsgDelegate { + throw new Error("fromJSON method should not be required"); + }, + + fromPartial(object: DeepPartial): CustomMsgDelegate { + const message = { ...baseCustomMsgDelegate } as CustomMsgDelegate; + if (object.customDelegatorAddress !== undefined && object.customDelegatorAddress !== null) { + message.customDelegatorAddress = object.customDelegatorAddress; + } else { + message.customDelegatorAddress = ""; + } + if (object.customValidatorAddress !== undefined && object.customValidatorAddress !== null) { + message.customValidatorAddress = object.customValidatorAddress; + } else { + message.customValidatorAddress = ""; + } + if (object.customAmount !== undefined && object.customAmount !== null) { + message.customAmount = Coin.fromPartial(object.customAmount); + } else { + message.customAmount = undefined; + } + return message; + }, + + toJSON(): unknown { + throw new Error("toJSON method should not be required"); + }, + }; + customRegistry.register(msgDelegateTypeUrl, CustomMsgDelegate); + const customAminoTypes = new AminoTypes({ + additions: { + "/cosmos.staking.v1beta1.MsgDelegate": { + aminoType: "cosmos-sdk/MsgDelegate", + toAmino: ({ + customDelegatorAddress, + customValidatorAddress, + customAmount, + }: CustomMsgDelegate): AminoMsgDelegate["value"] => { + assert(customDelegatorAddress, "missing customDelegatorAddress"); + assert(customValidatorAddress, "missing validatorAddress"); + assert(customAmount, "missing amount"); + return { + delegator_address: customDelegatorAddress, + validator_address: customValidatorAddress, + amount: { + amount: customAmount.amount, + denom: customAmount.denom, + }, + }; + }, + fromAmino: ({ + delegator_address, + validator_address, + amount, + }: AminoMsgDelegate["value"]): CustomMsgDelegate => ({ + customDelegatorAddress: delegator_address, + customValidatorAddress: validator_address, + customAmount: Coin.fromPartial(amount), + }), + }, + }, + }); + const options = { + ...defaultSigningClientOptions, + registry: customRegistry, + aminoTypes: customAminoTypes, + }; + const client = await SigningStargateClient.connectWithSigner(simapp.tendermintUrl, wallet, options); + + const msg: CustomMsgDelegate = { + customDelegatorAddress: faucet.address0, + customValidatorAddress: validator.validatorAddress, + customAmount: coin(1234, "ustake"), + }; + const msgAny = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const memo = "Use your power wisely"; + const signed = await client.sign(faucet.address0, [msgAny], fee, memo); + + // ensure signature is valid + const result = await client.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish())); + assertIsDeliverTxSuccess(result); + }); + + it("works with a modifying signer", async () => { + pendingWithoutSimapp(); + const wallet = await ModifyingSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const msg: MsgDelegate = { + delegatorAddress: faucet.address0, + validatorAddress: validator.validatorAddress, + amount: coin(1234, "ustake"), + }; + const msgAny: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: msg, + }; + const fee = { + amount: coins(2000, "ucosm"), + gas: "200000", + }; + const memo = "Use your power wisely"; + const signed = await client.sign(faucet.address0, [msgAny], fee, memo); + + const body = TxBody.decode(signed.bodyBytes); + const authInfo = AuthInfo.decode(signed.authInfoBytes); + // From ModifyingSecp256k1HdWallet + expect(body.memo).toEqual("This was modified"); + expect({ ...authInfo.fee!.amount[0] }).toEqual(coin(3000, "ucosm")); + expect(authInfo.fee!.gasLimit.toNumber()).toEqual(333333); + + // ensure signature is valid + const result = await client.broadcastTx(Uint8Array.from(TxRaw.encode(signed).finish())); + assertIsDeliverTxSuccess(result); + }); + }); + }); +}); diff --git a/src/signingstargateclient.ts b/src/signingstargateclient.ts new file mode 100644 index 0000000..ff819c7 --- /dev/null +++ b/src/signingstargateclient.ts @@ -0,0 +1,438 @@ +import { encodeSecp256k1Pubkey, makeSignDoc as makeSignDocAmino, StdFee } from "@cosmjs/amino"; +import { fromBase64 } from "@cosmjs/encoding"; +import { Int53, Uint53 } from "@cosmjs/math"; +import { + EncodeObject, + encodePubkey, + GeneratedType, + isOfflineDirectSigner, + makeAuthInfoBytes, + makeSignDoc, + OfflineSigner, + Registry, + TxBodyEncodeObject, +} from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { assert, assertDefined } from "@cosmjs/utils"; +import { MsgMultiSend } from "cosmjs-types/cosmos/bank/v1beta1/tx"; +import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; +import { + MsgFundCommunityPool, + MsgSetWithdrawAddress, + MsgWithdrawDelegatorReward, + MsgWithdrawValidatorCommission, +} from "cosmjs-types/cosmos/distribution/v1beta1/tx"; +import { MsgDeposit, MsgSubmitProposal, MsgVote } from "cosmjs-types/cosmos/gov/v1beta1/tx"; +import { + MsgBeginRedelegate, + MsgCreateValidator, + MsgDelegate, + MsgEditValidator, + MsgUndelegate, +} from "cosmjs-types/cosmos/staking/v1beta1/tx"; +import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; +import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx"; +import { + MsgAcknowledgement, + MsgChannelCloseConfirm, + MsgChannelCloseInit, + MsgChannelOpenAck, + MsgChannelOpenConfirm, + MsgChannelOpenInit, + MsgChannelOpenTry, + MsgRecvPacket, + MsgTimeout, + MsgTimeoutOnClose, +} from "cosmjs-types/ibc/core/channel/v1/tx"; +import { Height } from "cosmjs-types/ibc/core/client/v1/client"; +import { + MsgCreateClient, + MsgSubmitMisbehaviour, + MsgUpdateClient, + MsgUpgradeClient, +} from "cosmjs-types/ibc/core/client/v1/tx"; +import { + MsgConnectionOpenAck, + MsgConnectionOpenConfirm, + MsgConnectionOpenInit, + MsgConnectionOpenTry, +} from "cosmjs-types/ibc/core/connection/v1/tx"; +import Long from "long"; + +import { AminoTypes } from "./aminotypes"; +import { + MsgDelegateEncodeObject, + MsgSendEncodeObject, + MsgTransferEncodeObject, + MsgUndelegateEncodeObject, + MsgWithdrawDelegatorRewardEncodeObject, +} from "./encodeobjects"; +import { calculateFee, GasPrice } from "./fee"; +import { DeliverTxResponse, StargateClient } from "./stargateclient"; + +export const defaultRegistryTypes: ReadonlyArray<[string, GeneratedType]> = [ + ["/cosmos.bank.v1beta1.MsgMultiSend", MsgMultiSend], + ["/cosmos.distribution.v1beta1.MsgFundCommunityPool", MsgFundCommunityPool], + ["/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", MsgSetWithdrawAddress], + ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", MsgWithdrawDelegatorReward], + ["/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission", MsgWithdrawValidatorCommission], + ["/cosmos.gov.v1beta1.MsgDeposit", MsgDeposit], + ["/cosmos.gov.v1beta1.MsgSubmitProposal", MsgSubmitProposal], + ["/cosmos.gov.v1beta1.MsgVote", MsgVote], + ["/cosmos.staking.v1beta1.MsgBeginRedelegate", MsgBeginRedelegate], + ["/cosmos.staking.v1beta1.MsgCreateValidator", MsgCreateValidator], + ["/cosmos.staking.v1beta1.MsgDelegate", MsgDelegate], + ["/cosmos.staking.v1beta1.MsgEditValidator", MsgEditValidator], + ["/cosmos.staking.v1beta1.MsgUndelegate", MsgUndelegate], + ["/ibc.core.channel.v1.MsgChannelOpenInit", MsgChannelOpenInit], + ["/ibc.core.channel.v1.MsgChannelOpenTry", MsgChannelOpenTry], + ["/ibc.core.channel.v1.MsgChannelOpenAck", MsgChannelOpenAck], + ["/ibc.core.channel.v1.MsgChannelOpenConfirm", MsgChannelOpenConfirm], + ["/ibc.core.channel.v1.MsgChannelCloseInit", MsgChannelCloseInit], + ["/ibc.core.channel.v1.MsgChannelCloseConfirm", MsgChannelCloseConfirm], + ["/ibc.core.channel.v1.MsgRecvPacket", MsgRecvPacket], + ["/ibc.core.channel.v1.MsgTimeout", MsgTimeout], + ["/ibc.core.channel.v1.MsgTimeoutOnClose", MsgTimeoutOnClose], + ["/ibc.core.channel.v1.MsgAcknowledgement", MsgAcknowledgement], + ["/ibc.core.client.v1.MsgCreateClient", MsgCreateClient], + ["/ibc.core.client.v1.MsgUpdateClient", MsgUpdateClient], + ["/ibc.core.client.v1.MsgUpgradeClient", MsgUpgradeClient], + ["/ibc.core.client.v1.MsgSubmitMisbehaviour", MsgSubmitMisbehaviour], + ["/ibc.core.connection.v1.MsgConnectionOpenInit", MsgConnectionOpenInit], + ["/ibc.core.connection.v1.MsgConnectionOpenTry", MsgConnectionOpenTry], + ["/ibc.core.connection.v1.MsgConnectionOpenAck", MsgConnectionOpenAck], + ["/ibc.core.connection.v1.MsgConnectionOpenConfirm", MsgConnectionOpenConfirm], + ["/ibc.applications.transfer.v1.MsgTransfer", MsgTransfer], +]; + +function createDefaultRegistry(): Registry { + return new Registry(defaultRegistryTypes); +} + +/** + * Signing information for a single signer that is not included in the transaction. + * + * @see https://github.com/cosmos/cosmos-sdk/blob/v0.42.2/x/auth/signing/sign_mode_handler.go#L23-L37 + */ +export interface SignerData { + readonly accountNumber: number; + readonly sequence: number; + readonly chainId: string; +} + +/** Use for testing only */ +export interface PrivateSigningStargateClient { + readonly registry: Registry; +} + +export interface SigningStargateClientOptions { + readonly registry?: Registry; + readonly aminoTypes?: AminoTypes; + readonly prefix?: string; + readonly broadcastTimeoutMs?: number; + readonly broadcastPollIntervalMs?: number; + readonly gasPrice?: GasPrice; +} + +export class SigningStargateClient extends StargateClient { + public readonly registry: Registry; + public readonly broadcastTimeoutMs: number | undefined; + public readonly broadcastPollIntervalMs: number | undefined; + + private readonly signer: OfflineSigner; + private readonly aminoTypes: AminoTypes; + private readonly gasPrice: GasPrice | undefined; + + public static async connectWithSigner( + endpoint: string, + signer: OfflineSigner, + options: SigningStargateClientOptions = {}, + ): Promise { + const tmClient = await Tendermint34Client.connect(endpoint); + return new SigningStargateClient(tmClient, signer, options); + } + + /** + * Creates a client in offline mode. + * + * This should only be used in niche cases where you know exactly what you're doing, + * e.g. when building an offline signing application. + * + * When you try to use online functionality with such a signer, an + * exception will be raised. + */ + public static async offline( + signer: OfflineSigner, + options: SigningStargateClientOptions = {}, + ): Promise { + return new SigningStargateClient(undefined, signer, options); + } + + protected constructor( + tmClient: Tendermint34Client | undefined, + signer: OfflineSigner, + options: SigningStargateClientOptions, + ) { + super(tmClient); + const { registry = createDefaultRegistry(), aminoTypes = new AminoTypes({ prefix: options.prefix }) } = + options; + this.registry = registry; + this.aminoTypes = aminoTypes; + this.signer = signer; + this.broadcastTimeoutMs = options.broadcastTimeoutMs; + this.broadcastPollIntervalMs = options.broadcastPollIntervalMs; + this.gasPrice = options.gasPrice; + } + + public async simulate( + signerAddress: string, + messages: readonly EncodeObject[], + memo: string | undefined, + ): Promise { + const anyMsgs = messages.map((m) => this.registry.encodeAsAny(m)); + const accountFromSigner = (await this.signer.getAccounts()).find( + (account) => account.address === signerAddress, + ); + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer"); + } + const pubkey = encodeSecp256k1Pubkey(accountFromSigner.pubkey); + const { sequence } = await this.getSequence(signerAddress); + const { gasInfo } = await this.forceGetQueryClient().tx.simulate(anyMsgs, memo, pubkey, sequence); + assertDefined(gasInfo); + return Uint53.fromString(gasInfo.gasUsed.toString()).toNumber(); + } + + public async sendTokens( + senderAddress: string, + recipientAddress: string, + amount: readonly Coin[], + fee: StdFee | "auto" | number, + memo = "", + ): Promise { + const sendMsg: MsgSendEncodeObject = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: senderAddress, + toAddress: recipientAddress, + amount: [...amount], + }, + }; + return this.signAndBroadcast(senderAddress, [sendMsg], fee, memo); + } + + public async delegateTokens( + delegatorAddress: string, + validatorAddress: string, + amount: Coin, + fee: StdFee | "auto" | number, + memo = "", + ): Promise { + const delegateMsg: MsgDelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgDelegate", + value: MsgDelegate.fromPartial({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress, + amount: amount, + }), + }; + return this.signAndBroadcast(delegatorAddress, [delegateMsg], fee, memo); + } + + public async undelegateTokens( + delegatorAddress: string, + validatorAddress: string, + amount: Coin, + fee: StdFee | "auto" | number, + memo = "", + ): Promise { + const undelegateMsg: MsgUndelegateEncodeObject = { + typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate", + value: MsgUndelegate.fromPartial({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress, + amount: amount, + }), + }; + return this.signAndBroadcast(delegatorAddress, [undelegateMsg], fee, memo); + } + + public async withdrawRewards( + delegatorAddress: string, + validatorAddress: string, + fee: StdFee | "auto" | number, + memo = "", + ): Promise { + const withdrawMsg: MsgWithdrawDelegatorRewardEncodeObject = { + typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", + value: MsgWithdrawDelegatorReward.fromPartial({ + delegatorAddress: delegatorAddress, + validatorAddress: validatorAddress, + }), + }; + return this.signAndBroadcast(delegatorAddress, [withdrawMsg], fee, memo); + } + + public async sendIbcTokens( + senderAddress: string, + recipientAddress: string, + transferAmount: Coin, + sourcePort: string, + sourceChannel: string, + timeoutHeight: Height | undefined, + /** timeout in seconds */ + timeoutTimestamp: number | undefined, + fee: StdFee | "auto" | number, + memo = "", + ): Promise { + const timeoutTimestampNanoseconds = timeoutTimestamp + ? Long.fromNumber(timeoutTimestamp).multiply(1_000_000_000) + : undefined; + const transferMsg: MsgTransferEncodeObject = { + typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", + value: MsgTransfer.fromPartial({ + sourcePort: sourcePort, + sourceChannel: sourceChannel, + sender: senderAddress, + receiver: recipientAddress, + token: transferAmount, + timeoutHeight: timeoutHeight, + timeoutTimestamp: timeoutTimestampNanoseconds, + }), + }; + return this.signAndBroadcast(senderAddress, [transferMsg], fee, memo); + } + + public async signAndBroadcast( + signerAddress: string, + messages: readonly EncodeObject[], + fee: StdFee | "auto" | number, + memo = "", + ): Promise { + let usedFee: StdFee; + if (fee == "auto" || typeof fee === "number") { + assertDefined(this.gasPrice, "Gas price must be set in the client options when auto gas is used."); + const gasEstimation = await this.simulate(signerAddress, messages, memo); + const muliplier = typeof fee === "number" ? fee : 1.3; + usedFee = calculateFee(Math.round(gasEstimation * muliplier), this.gasPrice); + } else { + usedFee = fee; + } + const txRaw = await this.sign(signerAddress, messages, usedFee, memo); + const txBytes = TxRaw.encode(txRaw).finish(); + return this.broadcastTx(txBytes, this.broadcastTimeoutMs, this.broadcastPollIntervalMs); + } + + /** + * Gets account number and sequence from the API, creates a sign doc, + * creates a single signature and assembles the signed transaction. + * + * The sign mode (SIGN_MODE_DIRECT or SIGN_MODE_LEGACY_AMINO_JSON) is determined by this client's signer. + * + * You can pass signer data (account number, sequence and chain ID) explicitly instead of querying them + * from the chain. This is needed when signing for a multisig account, but it also allows for offline signing + * (See the SigningStargateClient.offline constructor). + */ + public async sign( + signerAddress: string, + messages: readonly EncodeObject[], + fee: StdFee, + memo: string, + explicitSignerData?: SignerData, + ): Promise { + let signerData: SignerData; + if (explicitSignerData) { + signerData = explicitSignerData; + } else { + const { accountNumber, sequence } = await this.getSequence(signerAddress); + const chainId = await this.getChainId(); + signerData = { + accountNumber: accountNumber, + sequence: sequence, + chainId: chainId, + }; + } + + return isOfflineDirectSigner(this.signer) + ? this.signDirect(signerAddress, messages, fee, memo, signerData) + : this.signAmino(signerAddress, messages, fee, memo, signerData); + } + + private async signAmino( + signerAddress: string, + messages: readonly EncodeObject[], + fee: StdFee, + memo: string, + { accountNumber, sequence, chainId }: SignerData, + ): Promise { + assert(!isOfflineDirectSigner(this.signer)); + const accountFromSigner = (await this.signer.getAccounts()).find( + (account) => account.address === signerAddress, + ); + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer"); + } + const pubkey = encodePubkey(encodeSecp256k1Pubkey(accountFromSigner.pubkey)); + const signMode = SignMode.SIGN_MODE_LEGACY_AMINO_JSON; + const msgs = messages.map((msg) => this.aminoTypes.toAmino(msg)); + const signDoc = makeSignDocAmino(msgs, fee, chainId, memo, accountNumber, sequence); + const { signature, signed } = await this.signer.signAmino(signerAddress, signDoc); + const signedTxBody = { + messages: signed.msgs.map((msg) => this.aminoTypes.fromAmino(msg)), + memo: signed.memo, + }; + const signedTxBodyEncodeObject: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: signedTxBody, + }; + const signedTxBodyBytes = this.registry.encode(signedTxBodyEncodeObject); + const signedGasLimit = Int53.fromString(signed.fee.gas).toNumber(); + const signedSequence = Int53.fromString(signed.sequence).toNumber(); + const signedAuthInfoBytes = makeAuthInfoBytes( + [{ pubkey, sequence: signedSequence }], + signed.fee.amount, + signedGasLimit, + signMode, + ); + return TxRaw.fromPartial({ + bodyBytes: signedTxBodyBytes, + authInfoBytes: signedAuthInfoBytes, + signatures: [fromBase64(signature.signature)], + }); + } + + private async signDirect( + signerAddress: string, + messages: readonly EncodeObject[], + fee: StdFee, + memo: string, + { accountNumber, sequence, chainId }: SignerData, + ): Promise { + assert(isOfflineDirectSigner(this.signer)); + const accountFromSigner = (await this.signer.getAccounts()).find( + (account) => account.address === signerAddress, + ); + if (!accountFromSigner) { + throw new Error("Failed to retrieve account from signer"); + } + const pubkey = encodePubkey(encodeSecp256k1Pubkey(accountFromSigner.pubkey)); + const txBodyEncodeObject: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: messages, + memo: memo, + }, + }; + const txBodyBytes = this.registry.encode(txBodyEncodeObject); + const gasLimit = Int53.fromString(fee.gas).toNumber(); + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], fee.amount, gasLimit); + const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); + const { signature, signed } = await this.signer.signDirect(signerAddress, signDoc); + return TxRaw.fromPartial({ + bodyBytes: signed.bodyBytes, + authInfoBytes: signed.authInfoBytes, + signatures: [fromBase64(signature.signature)], + }); + } +} diff --git a/src/stargateclient.searchtx.spec.ts b/src/stargateclient.searchtx.spec.ts new file mode 100644 index 0000000..a2e748a --- /dev/null +++ b/src/stargateclient.searchtx.spec.ts @@ -0,0 +1,366 @@ +import { fromBase64, toBase64 } from "@cosmjs/encoding"; +import { + coins, + decodeTxRaw, + DirectSecp256k1HdWallet, + encodePubkey, + makeAuthInfoBytes, + makeSignDoc, + Registry, + TxBodyEncodeObject, +} from "@cosmjs/proto-signing"; +import { assert, sleep } from "@cosmjs/utils"; +import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; +import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; + +import { isMsgSendEncodeObject } from "./encodeobjects"; +import { DeliverTxResponse, isDeliverTxFailure, isDeliverTxSuccess, StargateClient } from "./stargateclient"; +import { + defaultSigningClientOptions, + faucet, + fromOneElementArray, + makeRandomAddress, + pendingWithoutSimapp, + simapp, + simappEnabled, +} from "./testutils.spec"; + +interface TestTxSend { + readonly sender: string; + readonly recipient: string; + readonly hash: string; + readonly height: number; + readonly tx: Uint8Array; +} + +async function sendTokens( + client: StargateClient, + registry: Registry, + wallet: DirectSecp256k1HdWallet, + recipient: string, + amount: readonly Coin[], + memo: string, +): Promise<{ + readonly broadcastResponse: DeliverTxResponse; + readonly tx: Uint8Array; +}> { + const [{ address: walletAddress, pubkey: pubkeyBytes }] = await wallet.getAccounts(); + const pubkey = encodePubkey({ + type: "tendermint/PubKeySecp256k1", + value: toBase64(pubkeyBytes), + }); + const txBodyFields: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: walletAddress, + toAddress: recipient, + amount: amount, + }, + }, + ], + memo: memo, + }, + }; + const txBodyBytes = registry.encode(txBodyFields); + const { accountNumber, sequence } = (await client.getSequence(walletAddress))!; + const feeAmount = [ + { + amount: "2000", + denom: "ucosm", + }, + ]; + const gasLimit = 200000; + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit); + + const chainId = await client.getChainId(); + const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); + const { signature } = await wallet.signDirect(walletAddress, signDoc); + const txRaw = TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes, + signatures: [fromBase64(signature.signature)], + }); + const txRawBytes = Uint8Array.from(TxRaw.encode(txRaw).finish()); + const broadcastResponse = await client.broadcastTx( + txRawBytes, + defaultSigningClientOptions.broadcastTimeoutMs, + defaultSigningClientOptions.broadcastPollIntervalMs, + ); + return { + broadcastResponse: broadcastResponse, + tx: txRawBytes, + }; +} + +describe("StargateClient.getTx and .searchTx", () => { + const registry = new Registry(); + + let sendUnsuccessful: TestTxSend | undefined; + let sendSuccessful: TestTxSend | undefined; + + beforeAll(async () => { + if (simappEnabled()) { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const client = await StargateClient.connect(simapp.tendermintUrl); + const unsuccessfulRecipient = makeRandomAddress(); + const successfulRecipient = makeRandomAddress(); + + const unsuccessfulResult = await sendTokens( + client, + registry, + wallet, + unsuccessfulRecipient, + coins(123456700000000, "ucosm"), + "Sending more than I can afford", + ); + if (isDeliverTxFailure(unsuccessfulResult.broadcastResponse)) { + sendUnsuccessful = { + sender: faucet.address0, + recipient: unsuccessfulRecipient, + hash: unsuccessfulResult.broadcastResponse.transactionHash, + height: unsuccessfulResult.broadcastResponse.height, + tx: unsuccessfulResult.tx, + }; + } + const successfulResult = await sendTokens( + client, + registry, + wallet, + successfulRecipient, + coins(1234567, "ucosm"), + "Something I can afford", + ); + if (isDeliverTxSuccess(successfulResult.broadcastResponse)) { + sendSuccessful = { + sender: faucet.address0, + recipient: successfulRecipient, + hash: successfulResult.broadcastResponse.transactionHash, + height: successfulResult.broadcastResponse.height, + tx: successfulResult.tx, + }; + } + + await sleep(75); // wait until transactions are indexed + } + }); + + describe("getTx", () => { + it("can get successful tx by ID", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const result = await client.getTx(sendSuccessful.hash); + expect(result).toEqual( + jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + code: 0, + tx: sendSuccessful.tx, + }), + ); + }); + + it("can get unsuccessful tx by ID", async () => { + pendingWithoutSimapp(); + assert(sendUnsuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const result = await client.getTx(sendUnsuccessful.hash); + expect(result).toEqual( + jasmine.objectContaining({ + height: sendUnsuccessful.height, + hash: sendUnsuccessful.hash, + code: 5, + tx: sendUnsuccessful.tx, + }), + ); + }); + + it("can get by ID (non existent)", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const nonExistentId = "0000000000000000000000000000000000000000000000000000000000000000"; + const result = await client.getTx(nonExistentId); + expect(result).toBeNull(); + }); + }); + + describe("with SearchByHeightQuery", () => { + it("can search successful tx by height", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const result = await client.searchTx({ height: sendSuccessful.height }); + expect(result.length).toBeGreaterThanOrEqual(1); + expect(result).toContain( + jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + code: 0, + tx: sendSuccessful.tx, + }), + ); + }); + + it("can search unsuccessful tx by height", async () => { + pendingWithoutSimapp(); + assert(sendUnsuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const result = await client.searchTx({ height: sendUnsuccessful.height }); + expect(result.length).toBeGreaterThanOrEqual(1); + expect(result).toContain( + jasmine.objectContaining({ + height: sendUnsuccessful.height, + hash: sendUnsuccessful.hash, + code: 5, + tx: sendUnsuccessful.tx, + }), + ); + }); + }); + + describe("with SearchBySentFromOrToQuery", () => { + it("can search by sender", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const results = await client.searchTx({ sentFromOrTo: sendSuccessful.sender }); + expect(results.length).toBeGreaterThanOrEqual(1); + + // Check basic structure of all results + for (const result of results) { + const tx = decodeTxRaw(result.tx); + const filteredMsgs = tx.body.messages.filter((msg) => { + if (!isMsgSendEncodeObject(msg)) return false; + const decoded = registry.decode(msg); + return decoded.fromAddress === sendSuccessful?.sender; + }); + expect(filteredMsgs.length).toBeGreaterThanOrEqual(1); + } + + // Check details of most recent result + expect(results[results.length - 1]).toEqual( + jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + tx: sendSuccessful.tx, + }), + ); + }); + + it("can search by recipient", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const results = await client.searchTx({ sentFromOrTo: sendSuccessful.recipient }); + expect(results.length).toBeGreaterThanOrEqual(1); + + // Check basic structure of all results + for (const result of results) { + const tx = decodeTxRaw(result.tx); + const filteredMsgs = tx.body.messages.filter((msg) => { + if (!isMsgSendEncodeObject(msg)) return false; + const decoded = registry.decode(msg); + return decoded.toAddress === sendSuccessful?.recipient; + }); + expect(filteredMsgs.length).toBeGreaterThanOrEqual(1); + } + + // Check details of most recent result + expect(results[results.length - 1]).toEqual( + jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + tx: sendSuccessful.tx, + }), + ); + }); + + it("can search by recipient and filter by minHeight", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful); + const client = await StargateClient.connect(simapp.tendermintUrl); + const query = { sentFromOrTo: sendSuccessful.recipient }; + + { + const result = await client.searchTx(query, { minHeight: 0 }); + expect(result.length).toEqual(1); + } + + { + const result = await client.searchTx(query, { minHeight: sendSuccessful.height - 1 }); + expect(result.length).toEqual(1); + } + + { + const result = await client.searchTx(query, { minHeight: sendSuccessful.height }); + expect(result.length).toEqual(1); + } + + { + const result = await client.searchTx(query, { minHeight: sendSuccessful.height + 1 }); + expect(result.length).toEqual(0); + } + }); + + it("can search by recipient and filter by maxHeight", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful); + const client = await StargateClient.connect(simapp.tendermintUrl); + const query = { sentFromOrTo: sendSuccessful.recipient }; + + { + const result = await client.searchTx(query, { maxHeight: 9999999999999 }); + expect(result.length).toEqual(1); + } + + { + const result = await client.searchTx(query, { maxHeight: sendSuccessful.height + 1 }); + expect(result.length).toEqual(1); + } + + { + const result = await client.searchTx(query, { maxHeight: sendSuccessful.height }); + expect(result.length).toEqual(1); + } + + { + const result = await client.searchTx(query, { maxHeight: sendSuccessful.height - 1 }); + expect(result.length).toEqual(0); + } + }); + }); + + describe("with SearchByTagsQuery", () => { + it("can search by transfer.recipient", async () => { + pendingWithoutSimapp(); + assert(sendSuccessful, "value must be set in beforeAll()"); + const client = await StargateClient.connect(simapp.tendermintUrl); + const results = await client.searchTx({ + tags: [{ key: "transfer.recipient", value: sendSuccessful.recipient }], + }); + expect(results.length).toBeGreaterThanOrEqual(1); + + // Check basic structure of all results + for (const result of results) { + const tx = decodeTxRaw(result.tx); + const msg = fromOneElementArray(tx.body.messages); + expect(msg.typeUrl).toEqual("/cosmos.bank.v1beta1.MsgSend"); + const decoded = registry.decode(msg); + expect(decoded.toAddress).toEqual(sendSuccessful.recipient); + } + + // Check details of most recent result + expect(results[results.length - 1]).toEqual( + jasmine.objectContaining({ + height: sendSuccessful.height, + hash: sendSuccessful.hash, + tx: sendSuccessful.tx, + }), + ); + }); + }); +}); diff --git a/src/stargateclient.spec.ts b/src/stargateclient.spec.ts new file mode 100644 index 0000000..593a4af --- /dev/null +++ b/src/stargateclient.spec.ts @@ -0,0 +1,495 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { fromBase64, toBase64 } from "@cosmjs/encoding"; +import { + coins, + DirectSecp256k1HdWallet, + encodePubkey, + makeAuthInfoBytes, + makeSignDoc, + Registry, + TxBodyEncodeObject, +} from "@cosmjs/proto-signing"; +import { assert, sleep } from "@cosmjs/utils"; +import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; +import { ReadonlyDate } from "readonly-date"; + +import { + assertIsDeliverTxSuccess, + isDeliverTxFailure, + isDeliverTxSuccess, + PrivateStargateClient, + StargateClient, + TimeoutError, +} from "./stargateclient"; +import { + faucet, + makeRandomAddress, + nonExistentAddress, + pendingWithoutSimapp, + pendingWithoutSlowSimapp, + simapp, + slowSimapp, + tendermintIdMatcher, + unused, + validator, +} from "./testutils.spec"; + +const resultFailure = { + code: 5, + height: 219901, + rawLog: + "failed to execute message; message index: 0: 1855527000ufct is smaller than 20000000000000000000000ufct: insufficient funds", + transactionHash: "FDC4FB701AABD465935F7D04AE490D1EF5F2BD4B227601C4E98B57EB077D9B7D", + gasUsed: 54396, + gasWanted: 200000, +}; +const resultSuccess = { + code: 0, + height: 219894, + rawLog: + '[{"events":[{"type":"message","attributes":[{"key":"action","value":"send"},{"key":"sender","value":"firma1trqyle9m2nvyafc2n25frkpwed2504y6avgfzr"},{"key":"module","value":"bank"}]},{"type":"transfer","attributes":[{"key":"recipient","value":"firma12er8ls2sf5zess3jgjxz59xat9xtf8hz0hk6n4"},{"key":"sender","value":"firma1trqyle9m2nvyafc2n25frkpwed2504y6avgfzr"},{"key":"amount","value":"2000000ufct"}]}]}]', + transactionHash: "C0B416CA868C55C2B8C1BBB8F3CFA233854F13A5CB15D3E9599F50CAF7B3D161", + gasUsed: 61556, + gasWanted: 200000, +}; + +describe("isDeliverTxFailure", () => { + it("works", () => { + expect(isDeliverTxFailure(resultFailure)).toEqual(true); + expect(isDeliverTxFailure(resultSuccess)).toEqual(false); + }); +}); + +describe("isDeliverTxSuccess", () => { + it("works", () => { + expect(isDeliverTxSuccess(resultFailure)).toEqual(false); + expect(isDeliverTxSuccess(resultSuccess)).toEqual(true); + }); +}); + +describe("StargateClient", () => { + describe("connect", () => { + it("works", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + expect(client).toBeTruthy(); + client.disconnect(); + }); + }); + + describe("getChainId", () => { + it("works", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + expect(await client.getChainId()).toEqual(simapp.chainId); + client.disconnect(); + }); + + it("caches chain ID", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const openedClient = client as unknown as PrivateStargateClient; + const getCodeSpy = spyOn(openedClient.tmClient!, "status").and.callThrough(); + + expect(await client.getChainId()).toEqual(simapp.chainId); // from network + expect(await client.getChainId()).toEqual(simapp.chainId); // from cache + + expect(getCodeSpy).toHaveBeenCalledTimes(1); + + client.disconnect(); + }); + }); + + describe("getHeight", () => { + it("works", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const height1 = await client.getHeight(); + expect(height1).toBeGreaterThan(0); + await sleep(simapp.blockTime * 1.4); // tolerate chain being 40% slower than expected + const height2 = await client.getHeight(); + expect(height2).toBeGreaterThanOrEqual(height1 + 1); + expect(height2).toBeLessThanOrEqual(height1 + 2); + + client.disconnect(); + }); + }); + + describe("getAccount", () => { + it("works for unused account", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const account = await client.getAccount(unused.address); + assert(account); + expect(account).toEqual({ + address: unused.address, + pubkey: null, + accountNumber: unused.accountNumber, + sequence: unused.sequence, + }); + + client.disconnect(); + }); + + it("works for account with pubkey and non-zero sequence", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const account = await client.getAccount(validator.delegatorAddress); + assert(account); + expect(account).toEqual({ + address: validator.delegatorAddress, + pubkey: validator.pubkey, + accountNumber: validator.accountNumber, + sequence: validator.sequence, + }); + + client.disconnect(); + }); + + it("returns null for non-existent address", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const account = await client.getAccount(nonExistentAddress); + expect(account).toBeNull(); + + client.disconnect(); + }); + }); + + describe("getSequence", () => { + it("works for unused account", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const account = await client.getSequence(unused.address); + assert(account); + expect(account).toEqual({ + accountNumber: unused.accountNumber, + sequence: unused.sequence, + }); + + client.disconnect(); + }); + + it("rejects for non-existent address", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + await expectAsync(client.getSequence(nonExistentAddress)).toBeRejectedWithError( + /account does not exist on chain/i, + ); + + client.disconnect(); + }); + }); + + describe("getBlock", () => { + it("works for latest block", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const response = await client.getBlock(); + + expect(response).toEqual( + jasmine.objectContaining({ + id: jasmine.stringMatching(tendermintIdMatcher), + header: jasmine.objectContaining({ + chainId: await client.getChainId(), + }), + txs: jasmine.arrayContaining([]), + }), + ); + + expect(response.header.height).toBeGreaterThanOrEqual(1); + expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( + ReadonlyDate.now() - 5_000, + ); + + client.disconnect(); + }); + + it("works for block by height", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const height = (await client.getBlock()).header.height; + const response = await client.getBlock(height - 1); + + expect(response).toEqual( + jasmine.objectContaining({ + id: jasmine.stringMatching(tendermintIdMatcher), + header: jasmine.objectContaining({ + height: height - 1, + chainId: await client.getChainId(), + }), + txs: jasmine.arrayContaining([]), + }), + ); + + expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); + expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( + ReadonlyDate.now() - 5_000, + ); + + client.disconnect(); + }); + }); + + describe("getBalance", () => { + it("works for different existing balances", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const response1 = await client.getBalance(unused.address, simapp.denomFee); + expect(response1).toEqual({ + amount: unused.balanceFee, + denom: simapp.denomFee, + }); + const response2 = await client.getBalance(unused.address, simapp.denomStaking); + expect(response2).toEqual({ + amount: unused.balanceStaking, + denom: simapp.denomStaking, + }); + + client.disconnect(); + }); + + it("returns 0 for non-existent balance", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const response = await client.getBalance(unused.address, "gintonic"); + expect(response).toEqual({ + denom: "gintonic", + amount: "0", + }); + + client.disconnect(); + }); + + it("returns 0 for non-existent address", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const response = await client.getBalance(nonExistentAddress, simapp.denomFee); + expect(response).toEqual({ + denom: simapp.denomFee, + amount: "0", + }); + + client.disconnect(); + }); + }); + + describe("getAllBalances", () => { + it("returns all balances for unused account", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const balances = await client.getAllBalances(unused.address); + expect(balances).toEqual([ + { + amount: unused.balanceFee, + denom: simapp.denomFee, + }, + { + amount: unused.balanceStaking, + denom: simapp.denomStaking, + }, + ]); + + client.disconnect(); + }); + + it("returns an empty list for non-existent account", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + + const balances = await client.getAllBalances(nonExistentAddress); + expect(balances).toEqual([]); + + client.disconnect(); + }); + }); + + describe("broadcastTx", () => { + it("broadcasts a transaction", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts(); + const pubkey = encodePubkey({ + type: "tendermint/PubKeySecp256k1", + value: toBase64(pubkeyBytes), + }); + const registry = new Registry(); + const txBodyFields: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: address, + toAddress: makeRandomAddress(), + amount: [ + { + denom: "ucosm", + amount: "1234567", + }, + ], + }, + }, + ], + }, + }; + const txBodyBytes = registry.encode(txBodyFields); + const { accountNumber, sequence } = (await client.getSequence(address))!; + const feeAmount = coins(2000, "ucosm"); + const gasLimit = 200000; + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit); + + const chainId = await client.getChainId(); + const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); + const { signature } = await wallet.signDirect(address, signDoc); + const txRaw = TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes, + signatures: [fromBase64(signature.signature)], + }); + const txRawBytes = Uint8Array.from(TxRaw.encode(txRaw).finish()); + const txResult = await client.broadcastTx(txRawBytes); + assertIsDeliverTxSuccess(txResult); + + const { gasUsed, rawLog, transactionHash } = txResult; + expect(gasUsed).toBeGreaterThan(0); + expect(rawLog).toMatch(/{"key":"amount","value":"1234567ucosm"}/); + expect(transactionHash).toMatch(/^[0-9A-F]{64}$/); + + client.disconnect(); + }); + + it("errors immediately for a CheckTx failure", async () => { + pendingWithoutSimapp(); + const client = await StargateClient.connect(simapp.tendermintUrl); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts(); + const pubkey = encodePubkey({ + type: "tendermint/PubKeySecp256k1", + value: toBase64(pubkeyBytes), + }); + const registry = new Registry(); + const invalidRecipientAddress = "tgrade1z363ulwcrxged4z5jswyt5dn5v3lzsemwz9ewj"; // wrong bech32 prefix + const txBodyFields: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: address, + toAddress: invalidRecipientAddress, + amount: [ + { + denom: "ucosm", + amount: "1234567", + }, + ], + }, + }, + ], + }, + }; + const txBodyBytes = registry.encode(txBodyFields); + const { accountNumber, sequence } = (await client.getSequence(address))!; + const feeAmount = coins(2000, "ucosm"); + const gasLimit = 200000; + const authInfoBytes = makeAuthInfoBytes([{ pubkey, sequence }], feeAmount, gasLimit, sequence); + + const chainId = await client.getChainId(); + const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, chainId, accountNumber); + const { signature } = await wallet.signDirect(address, signDoc); + const txRaw = TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes, + signatures: [fromBase64(signature.signature)], + }); + const txRawBytes = Uint8Array.from(TxRaw.encode(txRaw).finish()); + + await expectAsync(client.broadcastTx(txRawBytes)).toBeRejectedWithError(/invalid recipient address/i); + + client.disconnect(); + }); + + it("respects user timeouts rather than RPC timeouts", async () => { + pendingWithoutSlowSimapp(); + const client = await StargateClient.connect(slowSimapp.tendermintUrl); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic); + const [{ address, pubkey: pubkeyBytes }] = await wallet.getAccounts(); + const pubkey = encodePubkey({ + type: "tendermint/PubKeySecp256k1", + value: toBase64(pubkeyBytes), + }); + const registry = new Registry(); + const txBodyFields: TxBodyEncodeObject = { + typeUrl: "/cosmos.tx.v1beta1.TxBody", + value: { + messages: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress: address, + toAddress: makeRandomAddress(), + amount: [ + { + denom: "ucosm", + amount: "1234567", + }, + ], + }, + }, + ], + }, + }; + const txBodyBytes = registry.encode(txBodyFields); + const chainId = await client.getChainId(); + const feeAmount = coins(2000, "ucosm"); + const gasLimit = 200000; + + const { accountNumber: accountNumber1, sequence: sequence1 } = (await client.getSequence(address))!; + const authInfoBytes1 = makeAuthInfoBytes([{ pubkey, sequence: sequence1 }], feeAmount, gasLimit); + const signDoc1 = makeSignDoc(txBodyBytes, authInfoBytes1, chainId, accountNumber1); + const { signature: signature1 } = await wallet.signDirect(address, signDoc1); + const txRaw1 = TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes1, + signatures: [fromBase64(signature1.signature)], + }); + const txRawBytes1 = Uint8Array.from(TxRaw.encode(txRaw1).finish()); + const largeTimeoutMs = 30_000; + const txResult = await client.broadcastTx(txRawBytes1, largeTimeoutMs); + assertIsDeliverTxSuccess(txResult); + + const { accountNumber: accountNumber2, sequence: sequence2 } = (await client.getSequence(address))!; + const authInfoBytes2 = makeAuthInfoBytes([{ pubkey, sequence: sequence2 }], feeAmount, gasLimit); + const signDoc2 = makeSignDoc(txBodyBytes, authInfoBytes2, chainId, accountNumber2); + const { signature: signature2 } = await wallet.signDirect(address, signDoc2); + const txRaw2 = TxRaw.fromPartial({ + bodyBytes: txBodyBytes, + authInfoBytes: authInfoBytes2, + signatures: [fromBase64(signature2.signature)], + }); + const txRawBytes2 = Uint8Array.from(TxRaw.encode(txRaw2).finish()); + const smallTimeoutMs = 1_000; + await expectAsync(client.broadcastTx(txRawBytes2, smallTimeoutMs)).toBeRejectedWithError( + TimeoutError, + /transaction with id .+ was submitted but was not yet found on the chain/i, + ); + + client.disconnect(); + }, 30_000); + }); +}); diff --git a/src/stargateclient.ts b/src/stargateclient.ts new file mode 100644 index 0000000..3fc9ef7 --- /dev/null +++ b/src/stargateclient.ts @@ -0,0 +1,412 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { toHex } from "@cosmjs/encoding"; +import { Uint53 } from "@cosmjs/math"; +import { Tendermint34Client, toRfc3339WithNanoseconds } from "@cosmjs/tendermint-rpc"; +import { sleep } from "@cosmjs/utils"; +import { MsgData } from "cosmjs-types/cosmos/base/abci/v1beta1/abci"; +import { Coin } from "cosmjs-types/cosmos/base/v1beta1/coin"; + +import { Account, accountFromAny } from "./accounts"; +import { + AuthExtension, + BankExtension, + QueryClient, + setupAuthExtension, + setupBankExtension, + setupStakingExtension, + setupTxExtension, + StakingExtension, + TxExtension, +} from "./queries"; +import { + isSearchByHeightQuery, + isSearchBySentFromOrToQuery, + isSearchByTagsQuery, + SearchTxFilter, + SearchTxQuery, +} from "./search"; + +export class TimeoutError extends Error { + public readonly txId: string; + + public constructor(message: string, txId: string) { + super(message); + this.txId = txId; + } +} + +/** + * This is the same as BlockHeader from @cosmjs/launchpad but those might diverge in the future. + */ +export interface BlockHeader { + readonly version: { + readonly block: string; + readonly app: string; + }; + readonly height: number; + readonly chainId: string; + /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ + readonly time: string; +} + +/** + * This is the same as Block from @cosmjs/launchpad but those might diverge in the future. + */ +export interface Block { + /** The ID is a hash of the block header (uppercase hex) */ + readonly id: string; + readonly header: BlockHeader; + /** Array of raw transactions */ + readonly txs: readonly Uint8Array[]; +} + +/** A transaction that is indexed as part of the transaction history */ +export interface IndexedTx { + readonly height: number; + /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ + readonly hash: string; + /** Transaction execution error code. 0 on success. */ + readonly code: number; + readonly rawLog: string; + /** + * Raw transaction bytes stored in Tendermint. + * + * If you hash this, you get the transaction hash (= transaction ID): + * + * ```js + * import { sha256 } from "@cosmjs/crypto"; + * import { toHex } from "@cosmjs/encoding"; + * + * const transactionId = toHex(sha256(indexTx.tx)).toUpperCase(); + * ``` + * + * Use `decodeTxRaw` from @cosmjs/proto-signing to decode this. + */ + readonly tx: Uint8Array; + readonly gasUsed: number; + readonly gasWanted: number; +} + +export interface SequenceResponse { + readonly accountNumber: number; + readonly sequence: number; +} + +/** + * The response after successfully broadcasting a transaction. + * Success or failure refer to the execution result. + */ +export interface DeliverTxResponse { + readonly height: number; + /** Error code. The transaction suceeded iff code is 0. */ + readonly code: number; + readonly transactionHash: string; + readonly rawLog?: string; + readonly data?: readonly MsgData[]; + readonly gasUsed: number; + readonly gasWanted: number; +} + +export function isDeliverTxFailure(result: DeliverTxResponse): boolean { + return !!result.code; +} + +export function isDeliverTxSuccess(result: DeliverTxResponse): boolean { + return !isDeliverTxFailure(result); +} + +/** + * Ensures the given result is a success. Throws a detailed error message otherwise. + */ +export function assertIsDeliverTxSuccess(result: DeliverTxResponse): void { + if (isDeliverTxFailure(result)) { + throw new Error( + `Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`, + ); + } +} + +/** + * Ensures the given result is a failure. Throws a detailed error message otherwise. + */ +export function assertIsDeliverTxFailure(result: DeliverTxResponse): void { + if (isDeliverTxSuccess(result)) { + throw new Error( + `Transaction ${result.transactionHash} did not fail at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`, + ); + } +} + +/** Use for testing only */ +export interface PrivateStargateClient { + readonly tmClient: Tendermint34Client | undefined; +} + +export class StargateClient { + private readonly tmClient: Tendermint34Client | undefined; + private readonly queryClient: + | (QueryClient & AuthExtension & BankExtension & StakingExtension & TxExtension) + | undefined; + private chainId: string | undefined; + + public static async connect(endpoint: string): Promise { + const tmClient = await Tendermint34Client.connect(endpoint); + return new StargateClient(tmClient); + } + + protected constructor(tmClient: Tendermint34Client | undefined) { + if (tmClient) { + this.tmClient = tmClient; + this.queryClient = QueryClient.withExtensions( + tmClient, + setupAuthExtension, + setupBankExtension, + setupStakingExtension, + setupTxExtension, + ); + } + } + + protected getTmClient(): Tendermint34Client | undefined { + return this.tmClient; + } + + protected forceGetTmClient(): Tendermint34Client { + if (!this.tmClient) { + throw new Error( + "Tendermint client not available. You cannot use online functionality in offline mode.", + ); + } + return this.tmClient; + } + + protected getQueryClient(): + | (QueryClient & AuthExtension & BankExtension & StakingExtension & TxExtension) + | undefined { + return this.queryClient; + } + + protected forceGetQueryClient(): QueryClient & + AuthExtension & + BankExtension & + StakingExtension & + TxExtension { + if (!this.queryClient) { + throw new Error("Query client not available. You cannot use online functionality in offline mode."); + } + return this.queryClient; + } + + public async getChainId(): Promise { + if (!this.chainId) { + const response = await this.forceGetTmClient().status(); + const chainId = response.nodeInfo.network; + if (!chainId) throw new Error("Chain ID must not be empty"); + this.chainId = chainId; + } + + return this.chainId; + } + + public async getHeight(): Promise { + const status = await this.forceGetTmClient().status(); + return status.syncInfo.latestBlockHeight; + } + + public async getAccount(searchAddress: string): Promise { + try { + const account = await this.forceGetQueryClient().auth.account(searchAddress); + return account ? accountFromAny(account) : null; + } catch (error: any) { + if (/rpc error: code = NotFound/i.test(error.toString())) { + return null; + } + throw error; + } + } + + public async getSequence(address: string): Promise { + const account = await this.getAccount(address); + if (!account) { + throw new Error( + "Account does not exist on chain. Send some tokens there before trying to query sequence.", + ); + } + return { + accountNumber: account.accountNumber, + sequence: account.sequence, + }; + } + + public async getBlock(height?: number): Promise { + const response = await this.forceGetTmClient().block(height); + return { + id: toHex(response.blockId.hash).toUpperCase(), + header: { + version: { + block: new Uint53(response.block.header.version.block).toString(), + app: new Uint53(response.block.header.version.app).toString(), + }, + height: response.block.header.height, + chainId: response.block.header.chainId, + time: toRfc3339WithNanoseconds(response.block.header.time), + }, + txs: response.block.txs, + }; + } + + public async getBalance(address: string, searchDenom: string): Promise { + return this.forceGetQueryClient().bank.balance(address, searchDenom); + } + + /** + * Queries all balances for all denoms that belong to this address. + * + * Uses the grpc queries (which iterates over the store internally), and we cannot get + * proofs from such a method. + */ + public async getAllBalances(address: string): Promise { + return this.forceGetQueryClient().bank.allBalances(address); + } + + public async getDelegation(delegatorAddress: string, validatorAddress: string): Promise { + let delegatedAmount: Coin | undefined; + try { + delegatedAmount = ( + await this.forceGetQueryClient().staking.delegation(delegatorAddress, validatorAddress) + ).delegationResponse?.balance; + } catch (e: any) { + if (e.toString().includes("key not found")) { + // ignore, `delegatedAmount` remains undefined + } else { + throw e; + } + } + return delegatedAmount || null; + } + + public async getTx(id: string): Promise { + const results = await this.txsQuery(`tx.hash='${id}'`); + return results[0] ?? null; + } + + public async searchTx(query: SearchTxQuery, filter: SearchTxFilter = {}): Promise { + const minHeight = filter.minHeight || 0; + const maxHeight = filter.maxHeight || Number.MAX_SAFE_INTEGER; + + if (maxHeight < minHeight) return []; // optional optimization + + function withFilters(originalQuery: string): string { + return `${originalQuery} AND tx.height>=${minHeight} AND tx.height<=${maxHeight}`; + } + + let txs: readonly IndexedTx[]; + + if (isSearchByHeightQuery(query)) { + txs = + query.height >= minHeight && query.height <= maxHeight + ? await this.txsQuery(`tx.height=${query.height}`) + : []; + } else if (isSearchBySentFromOrToQuery(query)) { + const sentQuery = withFilters(`message.module='bank' AND transfer.sender='${query.sentFromOrTo}'`); + const receivedQuery = withFilters( + `message.module='bank' AND transfer.recipient='${query.sentFromOrTo}'`, + ); + const [sent, received] = await Promise.all( + [sentQuery, receivedQuery].map((rawQuery) => this.txsQuery(rawQuery)), + ); + const sentHashes = sent.map((t) => t.hash); + txs = [...sent, ...received.filter((t) => !sentHashes.includes(t.hash))]; + } else if (isSearchByTagsQuery(query)) { + const rawQuery = withFilters(query.tags.map((t) => `${t.key}='${t.value}'`).join(" AND ")); + txs = await this.txsQuery(rawQuery); + } else { + throw new Error("Unknown query type"); + } + + const filtered = txs.filter((tx) => tx.height >= minHeight && tx.height <= maxHeight); + return filtered; + } + + public disconnect(): void { + if (this.tmClient) this.tmClient.disconnect(); + } + + /** + * Broadcasts a signed transaction to the network and monitors its inclusion in a block. + * + * If broadcasting is rejected by the node for some reason (e.g. because of a CheckTx failure), + * an error is thrown. + * + * If the transaction is not included in a block before the provided timeout, this errors with a `TimeoutError`. + * + * If the transaction is included in a block, a `DeliverTxResponse` is returned. The caller then + * usually needs to check for execution success or failure. + */ + public async broadcastTx( + tx: Uint8Array, + timeoutMs = 60_000, + pollIntervalMs = 3_000, + ): Promise { + let timedOut = false; + const txPollTimeout = setTimeout(() => { + timedOut = true; + }, timeoutMs); + + const pollForTx = async (txId: string): Promise => { + if (timedOut) { + throw new TimeoutError( + `Transaction with ID ${txId} was submitted but was not yet found on the chain. You might want to check later.`, + txId, + ); + } + await sleep(pollIntervalMs); + const result = await this.getTx(txId); + return result + ? { + code: result.code, + height: result.height, + rawLog: result.rawLog, + transactionHash: txId, + gasUsed: result.gasUsed, + gasWanted: result.gasWanted, + } + : pollForTx(txId); + }; + + const broadcasted = await this.forceGetTmClient().broadcastTxSync({ tx }); + if (broadcasted.code) { + throw new Error( + `Broadcasting transaction failed with code ${broadcasted.code} (codespace: ${broadcasted.codeSpace}). Log: ${broadcasted.log}`, + ); + } + const transactionId = toHex(broadcasted.hash).toUpperCase(); + return new Promise((resolve, reject) => + pollForTx(transactionId).then( + (value) => { + clearTimeout(txPollTimeout); + resolve(value); + }, + (error) => { + clearTimeout(txPollTimeout); + reject(error); + }, + ), + ); + } + + private async txsQuery(query: string): Promise { + const results = await this.forceGetTmClient().txSearchAll({ query: query }); + return results.txs.map((tx) => { + return { + height: tx.height, + hash: toHex(tx.hash).toUpperCase(), + code: tx.result.code, + rawLog: tx.result.log || "", + tx: tx.tx, + gasUsed: tx.result.gasUsed, + gasWanted: tx.result.gasWanted, + }; + }); + } +} diff --git a/src/testutils.spec.ts b/src/testutils.spec.ts new file mode 100644 index 0000000..5970efb --- /dev/null +++ b/src/testutils.spec.ts @@ -0,0 +1,242 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { AminoSignResponse, Secp256k1HdWallet, Secp256k1HdWalletOptions, StdSignDoc } from "@cosmjs/amino"; +import { Bip39, EnglishMnemonic, Random } from "@cosmjs/crypto"; +import { Bech32 } from "@cosmjs/encoding"; +import { + coins, + DirectSecp256k1HdWallet, + DirectSecp256k1HdWalletOptions, + DirectSignResponse, + makeAuthInfoBytes, +} from "@cosmjs/proto-signing"; +import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing"; +import { AuthInfo, SignDoc, TxBody } from "cosmjs-types/cosmos/tx/v1beta1/tx"; + +import { calculateFee, GasPrice } from "./fee"; +import { SigningStargateClientOptions } from "./signingstargateclient"; + +export function simapp42Enabled(): boolean { + return !!process.env.SIMAPP42_ENABLED; +} + +export function simapp44Enabled(): boolean { + return !!process.env.SIMAPP44_ENABLED; +} + +export function simappEnabled(): boolean { + return simapp42Enabled() || simapp44Enabled(); +} + +export function pendingWithoutSimapp42(): void { + if (!simapp42Enabled()) { + return pending("Set SIMAPP44_ENABLED to enable Simapp based tests"); + } +} + +export function pendingWithoutSimapp(): void { + if (!simappEnabled()) { + return pending("Set SIMAPP42_ENABLED or SIMAPP44_ENABLED to enable Simapp based tests"); + } +} + +export function slowSimappEnabled(): boolean { + return !!process.env.SLOW_SIMAPP42_ENABLED || !!process.env.SLOW_SIMAPP44_ENABLED; +} + +export function pendingWithoutSlowSimapp(): void { + if (!slowSimappEnabled()) { + return pending("Set SLOW_SIMAPP42_ENABLED or SLOW_SIMAPP44_ENABLED to enable slow Simapp based tests"); + } +} + +export function makeRandomAddressBytes(): Uint8Array { + return Random.getBytes(20); +} + +export function makeRandomAddress(): string { + return Bech32.encode("cosmos", makeRandomAddressBytes()); +} + +/** Returns first element. Throws if array has a different length than 1. */ +export function fromOneElementArray(elements: ArrayLike): T { + if (elements.length !== 1) throw new Error(`Expected exactly one element but got ${elements.length}`); + return elements[0]; +} + +export const defaultGasPrice = GasPrice.fromString("0.025ucosm"); +export const defaultSendFee = calculateFee(80_000, defaultGasPrice); + +export const simapp = { + tendermintUrl: "localhost:26658", + tendermintUrlWs: "ws://localhost:26658", + tendermintUrlHttp: "http://localhost:26658", + chainId: "simd-testing", + denomStaking: "ustake", + denomFee: "ucosm", + blockTime: 1_000, // ms + totalSupply: 21000000000, // ucosm + govMinDeposit: coins(10000000, "ustake"), +}; + +export const slowSimapp = { + tendermintUrl: "localhost:26660", + tendermintUrlWs: "ws://localhost:26660", + tendermintUrlHttp: "http://localhost:26660", + chainId: "simd-testing", + denomStaking: "ustake", + denomFee: "ucosm", + blockTime: 10_000, // ms + totalSupply: 21000000000, // ucosm +}; + +/** Setting to speed up testing */ +export const defaultSigningClientOptions: SigningStargateClientOptions = { + broadcastPollIntervalMs: 300, + broadcastTimeoutMs: 8_000, +}; + +export const faucet = { + mnemonic: + "economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone", + pubkey0: { + type: "tendermint/PubKeySecp256k1", + value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", + }, + pubkey1: { + type: "tendermint/PubKeySecp256k1", + value: "AiDosfIbBi54XJ1QjCeApumcy/FjdtF+YhywPf3DKTx7", + }, + pubkey2: { + type: "tendermint/PubKeySecp256k1", + value: "AzQg33JZqH7vSsm09esZY5bZvmzYwE/SY78cA0iLxpD7", + }, + pubkey3: { + type: "tendermint/PubKeySecp256k1", + value: "A3gOAlB6aiRTCPvWMQg2+ZbGYNsLd8qlvV28m8p2UhY2", + }, + pubkey4: { + type: "tendermint/PubKeySecp256k1", + value: "Aum2063ub/ErUnIUB36sK55LktGUStgcbSiaAnL1wadu", + }, + address0: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + address1: "cosmos10dyr9899g6t0pelew4nvf4j5c3jcgv0r73qga5", + address2: "cosmos1xy4yqngt0nlkdcenxymg8tenrghmek4nmqm28k", + address3: "cosmos142u9fgcjdlycfcez3lw8x6x5h7rfjlnfhpw2lx", + address4: "cosmos1hsm76p4ahyhl5yh3ve9ur49r5kemhp2r0dcjvx", +}; + +/** Unused account */ +export const unused = { + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "ArkCaFUJ/IH+vKBmNRCdUVl3mCAhbopk9jjW4Ko4OfRQ", + }, + address: "cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u", + accountNumber: 16, + sequence: 0, + balanceStaking: "2000000000", // 2000 STAKE + balanceFee: "1000000000", // 1000 COSM +}; + +export const validator = { + /** + * From first gentx's auth_info.signer_infos in scripts/simapp42/template/.simapp/config/genesis.json + * + * ``` + * jq ".app_state.genutil.gen_txs[0].auth_info.signer_infos[0].public_key" scripts/simapp42/template/.simapp/config/genesis.json + * ``` + */ + pubkey: { + type: "tendermint/PubKeySecp256k1", + value: "AtDcuH4cX1eaxZrJ5shheLG3tXPAoV4awoIZmNQtQxmf", + }, + /** + * delegator_address from /cosmos.staking.v1beta1.MsgCreateValidator in scripts/simapp42/template/.simapp/config/genesis.json + * + * ``` + * jq ".app_state.genutil.gen_txs[0].body.messages[0].delegator_address" scripts/simapp42/template/.simapp/config/genesis.json + * ``` + */ + delegatorAddress: "cosmos1urk9gy7cfws0ak9x5nu7lx4un9n6gqkry79679", + /** + * validator_address from /cosmos.staking.v1beta1.MsgCreateValidator in scripts/simapp42/template/.simapp/config/genesis.json + * + * ``` + * jq ".app_state.genutil.gen_txs[0].body.messages[0].validator_address" scripts/simapp42/template/.simapp/config/genesis.json + * ``` + */ + validatorAddress: "cosmosvaloper1urk9gy7cfws0ak9x5nu7lx4un9n6gqkrp230jk", + accountNumber: 0, + sequence: 1, +}; + +export const nonExistentAddress = "cosmos1p79apjaufyphcmsn4g07cynqf0wyjuezqu84hd"; + +export const nonNegativeIntegerMatcher = /^[0-9]+$/; +export const tendermintIdMatcher = /^[0-9A-F]{64}$/; + +/** + * A class for testing clients using an Amino signer which modifies the transaction it receives before signing + */ +export class ModifyingSecp256k1HdWallet extends Secp256k1HdWallet { + public static override async fromMnemonic( + mnemonic: string, + options: Partial = {}, + ): Promise { + const mnemonicChecked = new EnglishMnemonic(mnemonic); + const seed = await Bip39.mnemonicToSeed(mnemonicChecked, options.bip39Password); + return new ModifyingSecp256k1HdWallet(mnemonicChecked, { ...options, seed: seed }); + } + + public override async signAmino(signerAddress: string, signDoc: StdSignDoc): Promise { + const modifiedSignDoc = { + ...signDoc, + fee: { + amount: coins(3000, "ucosm"), + gas: "333333", + }, + memo: "This was modified", + }; + return super.signAmino(signerAddress, modifiedSignDoc); + } +} + +/** + * A class for testing clients using a direct signer which modifies the transaction it receives before signing + */ +export class ModifyingDirectSecp256k1HdWallet extends DirectSecp256k1HdWallet { + public static override async fromMnemonic( + mnemonic: string, + options: Partial = {}, + ): Promise { + const mnemonicChecked = new EnglishMnemonic(mnemonic); + const seed = await Bip39.mnemonicToSeed(mnemonicChecked, options.bip39Password); + return new ModifyingDirectSecp256k1HdWallet(mnemonicChecked, { ...options, seed: seed }); + } + + public override async signDirect(address: string, signDoc: SignDoc): Promise { + const txBody = TxBody.decode(signDoc.bodyBytes); + const modifiedTxBody = TxBody.fromPartial({ + ...txBody, + memo: "This was modified", + }); + const authInfo = AuthInfo.decode(signDoc.authInfoBytes); + const signers = authInfo.signerInfos.map((signerInfo) => ({ + pubkey: signerInfo.publicKey!, + sequence: signerInfo.sequence.toNumber(), + })); + const modifiedFeeAmount = coins(3000, "ucosm"); + const modifiedGasLimit = 333333; + const modifiedSignDoc = { + ...signDoc, + bodyBytes: Uint8Array.from(TxBody.encode(modifiedTxBody).finish()), + authInfoBytes: makeAuthInfoBytes( + signers, + modifiedFeeAmount, + modifiedGasLimit, + SignMode.SIGN_MODE_DIRECT, + ), + }; + return super.signDirect(address, modifiedSignDoc); + } +} diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 0000000..9a9f3b5 --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,9 @@ +{ + // extend your base config so you don't have to redefine your compilerOptions + "extends": "./tsconfig.json", + "include": [ + "src/**/*", + "*.js", + ".eslintrc.js" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4840979 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "experimentalDecorators": true, + "rootDir": "src" + }, + "include": [ + "src/**/*" + ] +} diff --git a/typedoc.js b/typedoc.js new file mode 100644 index 0000000..ffe4be6 --- /dev/null +++ b/typedoc.js @@ -0,0 +1,11 @@ +const packageJson = require("./package.json"); + +module.exports = { + entryPoints: ["./src"], + out: "docs", + exclude: "**/*.spec.ts", + name: `${packageJson.name} Documentation`, + readme: "README.md", + excludeExternals: true, + excludePrivate: true, +}; diff --git a/webpack.web.config.js b/webpack.web.config.js new file mode 100644 index 0000000..838675a --- /dev/null +++ b/webpack.web.config.js @@ -0,0 +1,40 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +const glob = require("glob"); +const path = require("path"); +const webpack = require("webpack"); + +const target = "web"; +const distdir = path.join(__dirname, "dist", "web"); + +module.exports = [ + { + // bundle used for Karma tests + target: target, + entry: glob.sync("./build/**/*.spec.js"), + output: { + path: distdir, + filename: "tests.js", + }, + plugins: [ + new webpack.EnvironmentPlugin({ + SIMAPP42_ENABLED: "", + SLOW_SIMAPP42_ENABLED: "", + SIMAPP44_ENABLED: "", + SLOW_SIMAPP44_ENABLED: "", + }), + new webpack.ProvidePlugin({ + Buffer: ["buffer", "Buffer"], + }), + ], + resolve: { + fallback: { + buffer: false, + crypto: false, + events: false, + path: false, + stream: require.resolve("stream-browserify"), + string_decoder: false, + }, + }, + }, +];