From 0fe3e5eb4afe44131454792f85d1c622a370d5fd Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 2 Jun 2020 14:58:15 +0200 Subject: [PATCH] Remove @cosmwasm/sdk --- packages/sdk/.eslintignore | 1 - packages/sdk/.gitignore | 3 - packages/sdk/README.md | 12 - packages/sdk/jasmine-testrunner.js | 26 - packages/sdk/karma.conf.js | 54 - packages/sdk/nonces/1580975947 | 0 packages/sdk/nonces/1580980830 | 0 packages/sdk/nonces/1581790180 | 0 packages/sdk/nonces/1582043857 | 0 packages/sdk/nonces/1582062520 | 0 packages/sdk/nonces/1582198421 | 0 packages/sdk/nonces/1582208955 | 0 packages/sdk/nonces/1582291410 | 0 packages/sdk/nonces/1583183690 | 0 packages/sdk/nonces/1583495327 | 0 packages/sdk/nonces/1583509277 | 0 packages/sdk/nonces/1583541822 | 0 packages/sdk/nonces/1583854671 | 0 packages/sdk/nonces/1583941462 | 0 packages/sdk/nonces/1584541301 | 0 packages/sdk/nonces/1584959328 | 0 packages/sdk/nonces/1589983882 | 0 packages/sdk/nonces/1589986013 | 0 packages/sdk/nonces/1590408566 | 0 packages/sdk/nonces/README.txt | 1 - packages/sdk/package.json | 50 - packages/sdk/src/address.spec.ts | 27 - packages/sdk/src/address.ts | 42 - packages/sdk/src/builder.spec.ts | 63 - packages/sdk/src/builder.ts | 20 - packages/sdk/src/coins.ts | 14 - .../sdk/src/cosmwasmclient.searchtx.spec.ts | 467 ------ packages/sdk/src/cosmwasmclient.spec.ts | 467 ------ packages/sdk/src/cosmwasmclient.ts | 439 ------ packages/sdk/src/decoding.ts | 11 - packages/sdk/src/encoding.spec.ts | 1 - packages/sdk/src/encoding.ts | 59 - packages/sdk/src/index.ts | 41 - packages/sdk/src/logs.spec.ts | 165 -- packages/sdk/src/logs.ts | 86 - packages/sdk/src/pen.spec.ts | 56 - packages/sdk/src/pen.ts | 92 -- packages/sdk/src/pubkey.spec.ts | 57 - packages/sdk/src/pubkey.ts | 71 - packages/sdk/src/restclient.spec.ts | 1378 ----------------- packages/sdk/src/restclient.ts | 457 ------ packages/sdk/src/sequence.spec.ts | 30 - packages/sdk/src/sequence.ts | 46 - packages/sdk/src/signature.spec.ts | 69 - packages/sdk/src/signature.ts | 39 - .../sdk/src/signingcosmwasmclient.spec.ts | 230 --- packages/sdk/src/signingcosmwasmclient.ts | 284 ---- packages/sdk/src/testdata/contract.json | 4 - packages/sdk/src/testdata/cosmoshub.json | 44 - packages/sdk/src/testdata/txresponse1.json | 57 - packages/sdk/src/testdata/txresponse2.json | 57 - packages/sdk/src/testdata/txresponse3.json | 57 - packages/sdk/src/testutils.spec.ts | 77 - packages/sdk/src/types.ts | 174 --- packages/sdk/tsconfig.json | 12 - packages/sdk/typedoc.js | 14 - packages/sdk/types/address.d.ts | 3 - packages/sdk/types/builder.d.ts | 1 - packages/sdk/types/coins.d.ts | 8 - packages/sdk/types/cosmwasmclient.d.ts | 175 --- packages/sdk/types/decoding.d.ts | 2 - packages/sdk/types/encoding.d.ts | 10 - packages/sdk/types/index.d.ts | 40 - packages/sdk/types/logs.d.ts | 28 - packages/sdk/types/pen.d.ts | 33 - packages/sdk/types/pubkey.d.ts | 4 - packages/sdk/types/restclient.d.ts | 231 --- packages/sdk/types/sequence.d.ts | 19 - packages/sdk/types/signature.d.ts | 14 - packages/sdk/types/signingcosmwasmclient.d.ts | 89 -- packages/sdk/types/types.d.ts | 123 -- packages/sdk/webpack.web.config.js | 19 - 77 files changed, 6153 deletions(-) delete mode 120000 packages/sdk/.eslintignore delete mode 100644 packages/sdk/.gitignore delete mode 100644 packages/sdk/README.md delete mode 100755 packages/sdk/jasmine-testrunner.js delete mode 100644 packages/sdk/karma.conf.js delete mode 100644 packages/sdk/nonces/1580975947 delete mode 100644 packages/sdk/nonces/1580980830 delete mode 100644 packages/sdk/nonces/1581790180 delete mode 100644 packages/sdk/nonces/1582043857 delete mode 100644 packages/sdk/nonces/1582062520 delete mode 100644 packages/sdk/nonces/1582198421 delete mode 100644 packages/sdk/nonces/1582208955 delete mode 100644 packages/sdk/nonces/1582291410 delete mode 100644 packages/sdk/nonces/1583183690 delete mode 100644 packages/sdk/nonces/1583495327 delete mode 100644 packages/sdk/nonces/1583509277 delete mode 100644 packages/sdk/nonces/1583541822 delete mode 100644 packages/sdk/nonces/1583854671 delete mode 100644 packages/sdk/nonces/1583941462 delete mode 100644 packages/sdk/nonces/1584541301 delete mode 100644 packages/sdk/nonces/1584959328 delete mode 100644 packages/sdk/nonces/1589983882 delete mode 100644 packages/sdk/nonces/1589986013 delete mode 100644 packages/sdk/nonces/1590408566 delete mode 100644 packages/sdk/nonces/README.txt delete mode 100644 packages/sdk/package.json delete mode 100644 packages/sdk/src/address.spec.ts delete mode 100644 packages/sdk/src/address.ts delete mode 100644 packages/sdk/src/builder.spec.ts delete mode 100644 packages/sdk/src/builder.ts delete mode 100644 packages/sdk/src/coins.ts delete mode 100644 packages/sdk/src/cosmwasmclient.searchtx.spec.ts delete mode 100644 packages/sdk/src/cosmwasmclient.spec.ts delete mode 100644 packages/sdk/src/cosmwasmclient.ts delete mode 100644 packages/sdk/src/decoding.ts delete mode 100644 packages/sdk/src/encoding.spec.ts delete mode 100644 packages/sdk/src/encoding.ts delete mode 100644 packages/sdk/src/index.ts delete mode 100644 packages/sdk/src/logs.spec.ts delete mode 100644 packages/sdk/src/logs.ts delete mode 100644 packages/sdk/src/pen.spec.ts delete mode 100644 packages/sdk/src/pen.ts delete mode 100644 packages/sdk/src/pubkey.spec.ts delete mode 100644 packages/sdk/src/pubkey.ts delete mode 100644 packages/sdk/src/restclient.spec.ts delete mode 100644 packages/sdk/src/restclient.ts delete mode 100644 packages/sdk/src/sequence.spec.ts delete mode 100644 packages/sdk/src/sequence.ts delete mode 100644 packages/sdk/src/signature.spec.ts delete mode 100644 packages/sdk/src/signature.ts delete mode 100644 packages/sdk/src/signingcosmwasmclient.spec.ts delete mode 100644 packages/sdk/src/signingcosmwasmclient.ts delete mode 100644 packages/sdk/src/testdata/contract.json delete mode 100644 packages/sdk/src/testdata/cosmoshub.json delete mode 100644 packages/sdk/src/testdata/txresponse1.json delete mode 100644 packages/sdk/src/testdata/txresponse2.json delete mode 100644 packages/sdk/src/testdata/txresponse3.json delete mode 100644 packages/sdk/src/testutils.spec.ts delete mode 100644 packages/sdk/src/types.ts delete mode 100644 packages/sdk/tsconfig.json delete mode 100644 packages/sdk/typedoc.js delete mode 100644 packages/sdk/types/address.d.ts delete mode 100644 packages/sdk/types/builder.d.ts delete mode 100644 packages/sdk/types/coins.d.ts delete mode 100644 packages/sdk/types/cosmwasmclient.d.ts delete mode 100644 packages/sdk/types/decoding.d.ts delete mode 100644 packages/sdk/types/encoding.d.ts delete mode 100644 packages/sdk/types/index.d.ts delete mode 100644 packages/sdk/types/logs.d.ts delete mode 100644 packages/sdk/types/pen.d.ts delete mode 100644 packages/sdk/types/pubkey.d.ts delete mode 100644 packages/sdk/types/restclient.d.ts delete mode 100644 packages/sdk/types/sequence.d.ts delete mode 100644 packages/sdk/types/signature.d.ts delete mode 100644 packages/sdk/types/signingcosmwasmclient.d.ts delete mode 100644 packages/sdk/types/types.d.ts delete mode 100644 packages/sdk/webpack.web.config.js diff --git a/packages/sdk/.eslintignore b/packages/sdk/.eslintignore deleted file mode 120000 index 86039baf..00000000 --- a/packages/sdk/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -../../.eslintignore \ No newline at end of file diff --git a/packages/sdk/.gitignore b/packages/sdk/.gitignore deleted file mode 100644 index 68bf3735..00000000 --- a/packages/sdk/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -build/ -dist/ -docs/ diff --git a/packages/sdk/README.md b/packages/sdk/README.md deleted file mode 100644 index 763ef5e6..00000000 --- a/packages/sdk/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# @cosmwasm/sdk - -[![npm version](https://img.shields.io/npm/v/@cosmwasm/sdk.svg)](https://www.npmjs.com/package/@cosmwasm/sdk) - -An SDK to build CosmWasm clients. - -## License - -This package is part of the cosmwasm-js repository, licensed under the Apache -License 2.0 (see -[NOTICE](https://github.com/confio/cosmwasm-js/blob/master/NOTICE) and -[LICENSE](https://github.com/confio/cosmwasm-js/blob/master/LICENSE)). diff --git a/packages/sdk/jasmine-testrunner.js b/packages/sdk/jasmine-testrunner.js deleted file mode 100755 index 9fada59b..00000000 --- a/packages/sdk/jasmine-testrunner.js +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env node - -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 }); - -// initialize and execute -jasmine.env.clearReporters(); -jasmine.addReporter(reporter); -jasmine.execute(); diff --git a/packages/sdk/karma.conf.js b/packages/sdk/karma.conf.js deleted file mode 100644 index e68db403..00000000 --- a/packages/sdk/karma.conf.js +++ /dev/null @@ -1,54 +0,0 @@ -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: ".", - - // 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, - - customLaunchers: { - ChromeHeadlessInsecure: { - base: "ChromeHeadless", - flags: ["--disable-web-security"], - }, - }, - }); -}; diff --git a/packages/sdk/nonces/1580975947 b/packages/sdk/nonces/1580975947 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1580980830 b/packages/sdk/nonces/1580980830 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1581790180 b/packages/sdk/nonces/1581790180 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1582043857 b/packages/sdk/nonces/1582043857 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1582062520 b/packages/sdk/nonces/1582062520 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1582198421 b/packages/sdk/nonces/1582198421 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1582208955 b/packages/sdk/nonces/1582208955 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1582291410 b/packages/sdk/nonces/1582291410 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1583183690 b/packages/sdk/nonces/1583183690 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1583495327 b/packages/sdk/nonces/1583495327 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1583509277 b/packages/sdk/nonces/1583509277 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1583541822 b/packages/sdk/nonces/1583541822 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1583854671 b/packages/sdk/nonces/1583854671 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1583941462 b/packages/sdk/nonces/1583941462 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1584541301 b/packages/sdk/nonces/1584541301 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1584959328 b/packages/sdk/nonces/1584959328 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1589983882 b/packages/sdk/nonces/1589983882 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1589986013 b/packages/sdk/nonces/1589986013 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/1590408566 b/packages/sdk/nonces/1590408566 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/sdk/nonces/README.txt b/packages/sdk/nonces/README.txt deleted file mode 100644 index 092fe732..00000000 --- a/packages/sdk/nonces/README.txt +++ /dev/null @@ -1 +0,0 @@ -Directory used to trigger lerna package updates for all packages diff --git a/packages/sdk/package.json b/packages/sdk/package.json deleted file mode 100644 index 8b5a4f04..00000000 --- a/packages/sdk/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cosmwasm/sdk", - "version": "0.8.0", - "description": "CosmWasm SDK", - "author": "Ethan Frey ", - "license": "Apache-2.0", - "main": "build/index.js", - "types": "types/index.d.ts", - "files": [ - "build/", - "types/", - "*.md", - "!*.spec.*", - "!**/testdata/" - ], - "repository": { - "type": "git", - "url": "https://github.com/confio/cosmwasm-js/tree/master/packages/sdk" - }, - "publishConfig": { - "access": "public" - }, - "scripts": { - "docs": "shx rm -rf docs && typedoc --options typedoc.js", - "format": "prettier --write --loglevel warn \"./src/**/*.ts\"", - "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", - "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", - "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", - "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", - "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", - "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", - "test-node": "node jasmine-testrunner.js", - "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", - "test-chrome": "yarn pack-web && karma start --single-run --browsers ChromeHeadlessInsecure", - "test": "yarn build-or-skip && yarn test-node", - "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" - }, - "dependencies": { - "@iov/crypto": "^2.1.0", - "@iov/encoding": "^2.1.0", - "@iov/utils": "^2.0.2", - "axios": "^0.19.0", - "fast-deep-equal": "^3.1.1", - "pako": "^1.0.11" - }, - "devDependencies": { - "@types/pako": "^1.0.1", - "readonly-date": "^1.0.0" - } -} diff --git a/packages/sdk/src/address.spec.ts b/packages/sdk/src/address.spec.ts deleted file mode 100644 index 713ffd03..00000000 --- a/packages/sdk/src/address.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { pubkeyToAddress } from "./address"; - -const { toBase64, fromHex } = Encoding; - -describe("address", () => { - describe("pubkeyToAddress", () => { - it("works for Secp256k1 compressed", () => { - const prefix = "cosmos"; - const pubkey = { - type: "tendermint/PubKeySecp256k1", - value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", - }; - expect(pubkeyToAddress(pubkey, prefix)).toEqual("cosmos1h806c7khnvmjlywdrkdgk2vrayy2mmvf9rxk2r"); - }); - - it("works for Ed25519", () => { - const prefix = "cosmos"; - const pubkey = { - type: "tendermint/PubKeyEd25519", - value: toBase64(fromHex("12ee6f581fe55673a1e9e1382a0829e32075a0aa4763c968bc526e1852e78c95")), - }; - expect(pubkeyToAddress(pubkey, prefix)).toEqual("cosmos1pfq05em6sfkls66ut4m2257p7qwlk448h8mysz"); - }); - }); -}); diff --git a/packages/sdk/src/address.ts b/packages/sdk/src/address.ts deleted file mode 100644 index 126d8fb8..00000000 --- a/packages/sdk/src/address.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Ripemd160, Sha256 } from "@iov/crypto"; -import { Bech32, Encoding } from "@iov/encoding"; - -import { PubKey, pubkeyType } from "./types"; - -const { fromBase64 } = Encoding; - -export function rawSecp256k1PubkeyToAddress(pubkeyRaw: Uint8Array, prefix: string): string { - if (pubkeyRaw.length !== 33) { - throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyRaw.length}`); - } - const hash1 = new Sha256(pubkeyRaw).digest(); - const hash2 = new Ripemd160(hash1).digest(); - return Bech32.encode(prefix, hash2); -} - -// See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography -// This assumes we already have a cosmos-compressed pubkey -export function pubkeyToAddress(pubkey: PubKey, prefix: string): string { - const pubkeyBytes = fromBase64(pubkey.value); - switch (pubkey.type) { - case pubkeyType.secp256k1: { - return rawSecp256k1PubkeyToAddress(pubkeyBytes, prefix); - } - case pubkeyType.ed25519: { - if (pubkeyBytes.length !== 32) { - throw new Error(`Invalid Ed25519 pubkey length: ${pubkeyBytes.length}`); - } - const hash = new Sha256(pubkeyBytes).digest(); - return Bech32.encode(prefix, hash.slice(0, 20)); - } - case pubkeyType.sr25519: { - if (pubkeyBytes.length !== 32) { - throw new Error(`Invalid Sr25519 pubkey length: ${pubkeyBytes.length}`); - } - const hash = new Sha256(pubkeyBytes).digest(); - return Bech32.encode(prefix, hash.slice(0, 20)); - } - default: - throw new Error("Unrecognized public key algorithm"); - } -} diff --git a/packages/sdk/src/builder.spec.ts b/packages/sdk/src/builder.spec.ts deleted file mode 100644 index 20926f4c..00000000 --- a/packages/sdk/src/builder.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { isValidBuilder } from "./builder"; - -describe("builder", () => { - describe("isValidBuilder", () => { - // Valid cases - - it("returns true for simple examples", () => { - expect(isValidBuilder("myorg/super-optimizer:0.1.2")).toEqual(true); - expect(isValidBuilder("myorg/super-optimizer:42")).toEqual(true); - }); - - it("supports images with multi level names", () => { - expect(isValidBuilder("myorg/department-x/office-y/technology-z/super-optimizer:0.1.2")).toEqual(true); - }); - - it("returns true for tags with lower and upper chars", () => { - expect(isValidBuilder("myorg/super-optimizer:0.1.2-alpha")).toEqual(true); - expect(isValidBuilder("myorg/super-optimizer:0.1.2-Alpha")).toEqual(true); - }); - - // Invalid cases - - it("returns false for missing or empty tag", () => { - expect(isValidBuilder("myorg/super-optimizer")).toEqual(false); - expect(isValidBuilder("myorg/super-optimizer:")).toEqual(false); - }); - - it("returns false for name components starting or ending with a separator", () => { - expect(isValidBuilder(".myorg/super-optimizer:42")).toEqual(false); - expect(isValidBuilder("-myorg/super-optimizer:42")).toEqual(false); - expect(isValidBuilder("_myorg/super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg./super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg-/super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg_/super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg/.super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg/-super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg/_super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg/super-optimizer.:42")).toEqual(false); - expect(isValidBuilder("myorg/super-optimizer-:42")).toEqual(false); - expect(isValidBuilder("myorg/super-optimizer_:42")).toEqual(false); - }); - - it("returns false for upper case character in name component", () => { - expect(isValidBuilder("mYorg/super-optimizer:42")).toEqual(false); - expect(isValidBuilder("myorg/super-Optimizer:42")).toEqual(false); - }); - - it("returns false for long images", () => { - expect( - isValidBuilder( - "myorgisnicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenice/super-optimizer:42", - ), - ).toEqual(false); - }); - - it("returns false for images with no organization", () => { - // Those are valid dockerhub images from https://hub.docker.com/_/ubuntu and https://hub.docker.com/_/rust - // but not valid in the context of CosmWasm Verify - expect(isValidBuilder("ubuntu:xenial-20200212")).toEqual(false); - expect(isValidBuilder("rust:1.40.0")).toEqual(false); - }); - }); -}); diff --git a/packages/sdk/src/builder.ts b/packages/sdk/src/builder.ts deleted file mode 100644 index 31a790c7..00000000 --- a/packages/sdk/src/builder.ts +++ /dev/null @@ -1,20 +0,0 @@ -// A docker image regexp. We remove support for non-standard registries for simplicity. -// https://docs.docker.com/engine/reference/commandline/tag/#extended-description -// -// An image name is made up of slash-separated name components (optionally prefixed by a registry hostname). -// Name components may contain lowercase characters, digits and separators. -// A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator. -// -// A tag name must be valid ASCII and may contain lowercase and uppercase letters, digits, underscores, periods and dashes. -// A tag name may not start with a period or a dash and may contain a maximum of 128 characters. -const dockerImagePattern = new RegExp( - "^[a-z0-9][a-z0-9._-]*[a-z0-9](/[a-z0-9][a-z0-9._-]*[a-z0-9])+:[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$", -); - -/** Max length in bytes/characters (regexp enforces all ASCII, even if that is not required by the standard) */ -const builderMaxLength = 128; - -export function isValidBuilder(builder: string): boolean { - if (builder.length > builderMaxLength) return false; - return !!builder.match(dockerImagePattern); -} diff --git a/packages/sdk/src/coins.ts b/packages/sdk/src/coins.ts deleted file mode 100644 index 62f5f9ce..00000000 --- a/packages/sdk/src/coins.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface Coin { - readonly denom: string; - readonly amount: string; -} - -/** Creates a coin */ -export function coin(amount: number, denom: string): Coin { - return { amount: amount.toString(), denom: denom }; -} - -/** Creates a list of coins with one element */ -export function coins(amount: number, denom: string): Coin[] { - return [coin(amount, denom)]; -} diff --git a/packages/sdk/src/cosmwasmclient.searchtx.spec.ts b/packages/sdk/src/cosmwasmclient.searchtx.spec.ts deleted file mode 100644 index cfe91678..00000000 --- a/packages/sdk/src/cosmwasmclient.searchtx.spec.ts +++ /dev/null @@ -1,467 +0,0 @@ -/* eslint-disable @typescript-eslint/camelcase */ -import { assert, sleep } from "@iov/utils"; - -import { Coin } from "./coins"; -import { CosmWasmClient } from "./cosmwasmclient"; -import { makeSignBytes } from "./encoding"; -import { Secp256k1Pen } from "./pen"; -import { RestClient } from "./restclient"; -import { SigningCosmWasmClient } from "./signingcosmwasmclient"; -import { - deployedErc20, - faucet, - fromOneElementArray, - makeRandomAddress, - pendingWithoutWasmd, - wasmd, - wasmdEnabled, -} from "./testutils.spec"; -import { CosmosSdkTx, isMsgExecuteContract, isMsgInstantiateContract, isMsgSend, MsgSend } from "./types"; - -describe("CosmWasmClient.searchTx", () => { - let sendSuccessful: - | { - readonly sender: string; - readonly recipient: string; - readonly hash: string; - readonly height: number; - readonly tx: CosmosSdkTx; - } - | undefined; - let sendUnsuccessful: - | { - readonly sender: string; - readonly recipient: string; - readonly hash: string; - readonly height: number; - readonly tx: CosmosSdkTx; - } - | undefined; - let postedExecute: - | { - readonly sender: string; - readonly contract: string; - readonly hash: string; - readonly height: number; - readonly tx: CosmosSdkTx; - } - | undefined; - - beforeAll(async () => { - if (wasmdEnabled()) { - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(wasmd.endpoint, faucet.address, (signBytes) => - pen.sign(signBytes), - ); - - { - const recipient = makeRandomAddress(); - const transferAmount: Coin = { - denom: "ucosm", - amount: "1234567", - }; - const result = await client.sendTokens(recipient, [transferAmount]); - await sleep(50); // wait until tx is indexed - const txDetails = await new RestClient(wasmd.endpoint).txById(result.transactionHash); - sendSuccessful = { - sender: faucet.address, - recipient: recipient, - hash: result.transactionHash, - height: Number.parseInt(txDetails.height, 10), - tx: txDetails.tx, - }; - } - - { - const memo = "Sending more than I can afford"; - const recipient = makeRandomAddress(); - const transferAmount = [ - { - denom: "ucosm", - amount: "123456700000000", - }, - ]; - const sendMsg: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - // eslint-disable-next-line @typescript-eslint/camelcase - from_address: faucet.address, - // eslint-disable-next-line @typescript-eslint/camelcase - to_address: recipient, - amount: transferAmount, - }, - }; - const fee = { - amount: [ - { - denom: "ucosm", - amount: "2000", - }, - ], - gas: "80000", // 80k - }; - const { accountNumber, sequence } = await client.getNonce(); - const chainId = await client.getChainId(); - const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence); - const signature = await pen.sign(signBytes); - const tx: CosmosSdkTx = { - type: "cosmos-sdk/StdTx", - value: { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }, - }; - const transactionId = await client.getIdentifier(tx); - const heightBeforeThis = await client.getHeight(); - try { - await client.postTx(tx.value); - } catch (error) { - // postTx() throws on execution failures, which is a questionable design. Ignore for now. - // console.log(error); - } - sendUnsuccessful = { - sender: faucet.address, - recipient: recipient, - hash: transactionId, - height: heightBeforeThis + 1, - tx: tx, - }; - } - - { - const hashInstance = deployedErc20.instances[0]; - const msg = { - approve: { - spender: makeRandomAddress(), - amount: "12", - }, - }; - const result = await client.execute(hashInstance, msg); - await sleep(50); // wait until tx is indexed - const txDetails = await new RestClient(wasmd.endpoint).txById(result.transactionHash); - postedExecute = { - sender: faucet.address, - contract: hashInstance, - hash: result.transactionHash, - height: Number.parseInt(txDetails.height, 10), - tx: txDetails.tx, - }; - } - } - }); - - describe("with SearchByIdQuery", () => { - it("can search successful tx by ID", async () => { - pendingWithoutWasmd(); - assert(sendSuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.searchTx({ id: sendSuccessful.hash }); - expect(result.length).toEqual(1); - expect(result[0]).toEqual( - jasmine.objectContaining({ - height: sendSuccessful.height, - hash: sendSuccessful.hash, - code: 0, - tx: sendSuccessful.tx, - }), - ); - }); - - it("can search unsuccessful tx by ID", async () => { - pendingWithoutWasmd(); - assert(sendUnsuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.searchTx({ id: sendUnsuccessful.hash }); - expect(result.length).toEqual(1); - expect(result[0]).toEqual( - jasmine.objectContaining({ - height: sendUnsuccessful.height, - hash: sendUnsuccessful.hash, - code: 5, - tx: sendUnsuccessful.tx, - }), - ); - }); - - it("can search by ID (non existent)", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const nonExistentId = "0000000000000000000000000000000000000000000000000000000000000000"; - const result = await client.searchTx({ id: nonExistentId }); - expect(result.length).toEqual(0); - }); - - it("can search by ID and filter by minHeight", async () => { - pendingWithoutWasmd(); - assert(sendSuccessful); - const client = new CosmWasmClient(wasmd.endpoint); - const query = { id: sendSuccessful.hash }; - - { - 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); - } - }); - }); - - describe("with SearchByHeightQuery", () => { - it("can search successful tx by height", async () => { - pendingWithoutWasmd(); - assert(sendSuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.searchTx({ height: sendSuccessful.height }); - expect(result.length).toEqual(1); - expect(result[0]).toEqual( - jasmine.objectContaining({ - height: sendSuccessful.height, - hash: sendSuccessful.hash, - code: 0, - tx: sendSuccessful.tx, - }), - ); - }); - - it("can search unsuccessful tx by height", async () => { - pendingWithoutWasmd(); - assert(sendUnsuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.searchTx({ height: sendUnsuccessful.height }); - expect(result.length).toEqual(1); - expect(result[0]).toEqual( - jasmine.objectContaining({ - height: sendUnsuccessful.height, - hash: sendUnsuccessful.hash, - code: 5, - tx: sendUnsuccessful.tx, - }), - ); - }); - }); - - describe("with SearchBySentFromOrToQuery", () => { - it("can search by sender", async () => { - pendingWithoutWasmd(); - assert(sendSuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - 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 containsMsgWithSender = !!result.tx.value.msg.find( - (msg) => isMsgSend(msg) && msg.value.from_address == sendSuccessful!.sender, - ); - const containsMsgWithRecipient = !!result.tx.value.msg.find( - (msg) => isMsgSend(msg) && msg.value.to_address === sendSuccessful!.sender, - ); - expect(containsMsgWithSender || containsMsgWithRecipient).toEqual(true); - } - - // 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 () => { - pendingWithoutWasmd(); - assert(sendSuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - 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 msg = fromOneElementArray(result.tx.value.msg); - assert(isMsgSend(msg), `${result.hash} (height ${result.height}) is not a bank send transaction`); - expect( - msg.value.to_address === sendSuccessful.recipient || - msg.value.from_address == sendSuccessful.recipient, - ).toEqual(true); - } - - // 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 () => { - pendingWithoutWasmd(); - assert(sendSuccessful); - const client = new CosmWasmClient(wasmd.endpoint); - 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 () => { - pendingWithoutWasmd(); - assert(sendSuccessful); - const client = new CosmWasmClient(wasmd.endpoint); - 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 () => { - pendingWithoutWasmd(); - assert(sendSuccessful, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - 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 msg = fromOneElementArray(result.tx.value.msg); - assert(isMsgSend(msg), `${result.hash} (height ${result.height}) is not a bank send transaction`); - expect(msg.value.to_address).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, - }), - ); - }); - - it("can search by message.contract_address", async () => { - pendingWithoutWasmd(); - assert(postedExecute, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - const results = await client.searchTx({ - tags: [{ key: "message.contract_address", value: postedExecute.contract }], - }); - expect(results.length).toBeGreaterThanOrEqual(1); - - // Check basic structure of all results - for (const result of results) { - const msg = fromOneElementArray(result.tx.value.msg); - assert( - isMsgExecuteContract(msg) || isMsgInstantiateContract(msg), - `${result.hash} (at ${result.height}) not an execute or instantiate msg`, - ); - } - - // Check that the first result is the instantiation - const first = fromOneElementArray(results[0].tx.value.msg); - assert(isMsgInstantiateContract(first), "First contract search result must be an instantiation"); - expect(first).toEqual({ - type: "wasm/instantiate", - value: { - sender: faucet.address, - code_id: deployedErc20.codeId.toString(), - label: "HASH", - init_msg: jasmine.objectContaining({ symbol: "HASH" }), - init_funds: [], - }, - }); - - // Check details of most recent result - expect(results[results.length - 1]).toEqual( - jasmine.objectContaining({ - height: postedExecute.height, - hash: postedExecute.hash, - tx: postedExecute.tx, - }), - ); - }); - - it("can search by message.contract_address + message.action", async () => { - pendingWithoutWasmd(); - assert(postedExecute, "value must be set in beforeAll()"); - const client = new CosmWasmClient(wasmd.endpoint); - const results = await client.searchTx({ - tags: [ - { key: "message.contract_address", value: postedExecute.contract }, - { key: "message.action", value: "execute" }, - ], - }); - expect(results.length).toBeGreaterThanOrEqual(1); - - // Check basic structure of all results - for (const result of results) { - const msg = fromOneElementArray(result.tx.value.msg); - assert(isMsgExecuteContract(msg), `${result.hash} (at ${result.height}) not an execute msg`); - expect(msg.value.contract).toEqual(postedExecute.contract); - } - - // Check details of most recent result - expect(results[results.length - 1]).toEqual( - jasmine.objectContaining({ - height: postedExecute.height, - hash: postedExecute.hash, - tx: postedExecute.tx, - }), - ); - }); - }); -}); diff --git a/packages/sdk/src/cosmwasmclient.spec.ts b/packages/sdk/src/cosmwasmclient.spec.ts deleted file mode 100644 index 2980df89..00000000 --- a/packages/sdk/src/cosmwasmclient.spec.ts +++ /dev/null @@ -1,467 +0,0 @@ -/* eslint-disable @typescript-eslint/camelcase */ -import { Sha256 } from "@iov/crypto"; -import { Bech32, Encoding } from "@iov/encoding"; -import { assert, sleep } from "@iov/utils"; -import { ReadonlyDate } from "readonly-date"; - -import { Code, CosmWasmClient, PrivateCosmWasmClient } from "./cosmwasmclient"; -import { makeSignBytes } from "./encoding"; -import { findAttribute } from "./logs"; -import { Secp256k1Pen } from "./pen"; -import { SigningCosmWasmClient } from "./signingcosmwasmclient"; -import cosmoshub from "./testdata/cosmoshub.json"; -import { - deployedErc20, - faucet, - getHackatom, - makeRandomAddress, - pendingWithoutWasmd, - tendermintIdMatcher, - unused, - wasmd, - wasmdEnabled, -} from "./testutils.spec"; -import { MsgSend, StdFee } from "./types"; - -const { fromHex, fromUtf8, toAscii, toBase64 } = Encoding; - -const guest = { - address: "cosmos17d0jcz59jf68g52vq38tuuncmwwjk42u6mcxej", -}; - -interface HackatomInstance { - readonly initMsg: { - readonly verifier: string; - readonly beneficiary: string; - }; - readonly address: string; -} - -describe("CosmWasmClient", () => { - describe("makeReadOnly", () => { - it("can be constructed", () => { - const client = new CosmWasmClient(wasmd.endpoint); - expect(client).toBeTruthy(); - }); - }); - - describe("getChainId", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - expect(await client.getChainId()).toEqual(wasmd.chainId); - }); - - it("caches chain ID", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const openedClient = (client as unknown) as PrivateCosmWasmClient; - const getCodeSpy = spyOn(openedClient.restClient, "nodeInfo").and.callThrough(); - - expect(await client.getChainId()).toEqual(wasmd.chainId); // from network - expect(await client.getChainId()).toEqual(wasmd.chainId); // from cache - - expect(getCodeSpy).toHaveBeenCalledTimes(1); - }); - }); - - describe("getHeight", () => { - it("gets height via last block", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const openedClient = (client as unknown) as PrivateCosmWasmClient; - const blockLatestSpy = spyOn(openedClient.restClient, "blocksLatest").and.callThrough(); - - const height1 = await client.getHeight(); - expect(height1).toBeGreaterThan(0); - await sleep(1_000); - const height2 = await client.getHeight(); - expect(height2).toEqual(height1 + 1); - - expect(blockLatestSpy).toHaveBeenCalledTimes(2); - }); - - it("gets height via authAccount once an address is known", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - - const openedClient = (client as unknown) as PrivateCosmWasmClient; - const blockLatestSpy = spyOn(openedClient.restClient, "blocksLatest").and.callThrough(); - const authAccountsSpy = spyOn(openedClient.restClient, "authAccounts").and.callThrough(); - - const height1 = await client.getHeight(); - expect(height1).toBeGreaterThan(0); - - await client.getCodes(); // warm up the client - - const height2 = await client.getHeight(); - expect(height2).toBeGreaterThan(0); - await sleep(1_000); - const height3 = await client.getHeight(); - expect(height3).toEqual(height2 + 1); - - expect(blockLatestSpy).toHaveBeenCalledTimes(1); - expect(authAccountsSpy).toHaveBeenCalledTimes(2); - }); - }); - - describe("getNonce", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - expect(await client.getNonce(unused.address)).toEqual({ - accountNumber: unused.accountNumber, - sequence: unused.sequence, - }); - }); - - it("throws for missing accounts", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const missing = makeRandomAddress(); - await client.getNonce(missing).then( - () => fail("this must not succeed"), - (error) => expect(error).toMatch(/account does not exist on chain/i), - ); - }); - }); - - describe("getAccount", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - expect(await client.getAccount(unused.address)).toEqual({ - address: unused.address, - accountNumber: unused.accountNumber, - sequence: unused.sequence, - pubkey: undefined, - balance: [ - { denom: "ucosm", amount: "1000000000" }, - { denom: "ustake", amount: "1000000000" }, - ], - }); - }); - - it("returns undefined for missing accounts", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const missing = makeRandomAddress(); - expect(await client.getAccount(missing)).toBeUndefined(); - }); - }); - - describe("getBlock", () => { - it("works for latest block", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const response = await client.getBlock(); - - // id - expect(response.id).toMatch(tendermintIdMatcher); - - // header - expect(response.header.height).toBeGreaterThanOrEqual(1); - expect(response.header.chainId).toEqual(await client.getChainId()); - expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); - expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( - ReadonlyDate.now() - 5_000, - ); - - // txs - expect(Array.isArray(response.txs)).toEqual(true); - }); - - it("works for block by height", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const height = (await client.getBlock()).header.height; - const response = await client.getBlock(height - 1); - - // id - expect(response.id).toMatch(tendermintIdMatcher); - - // header - expect(response.header.height).toEqual(height - 1); - expect(response.header.chainId).toEqual(await client.getChainId()); - expect(new ReadonlyDate(response.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); - expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( - ReadonlyDate.now() - 5_000, - ); - - // txs - expect(Array.isArray(response.txs)).toEqual(true); - }); - }); - - describe("getIdentifier", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - expect(await client.getIdentifier(cosmoshub.tx)).toEqual(cosmoshub.id); - }); - }); - - describe("postTx", () => { - it("works", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new CosmWasmClient(wasmd.endpoint); - - const memo = "My first contract on chain"; - const sendMsg: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: faucet.address, - to_address: makeRandomAddress(), - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const chainId = await client.getChainId(); - const { accountNumber, sequence } = await client.getNonce(faucet.address); - const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence); - const signature = await pen.sign(signBytes); - const signedTx = { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; - const { logs, transactionHash } = await client.postTx(signedTx); - const amountAttr = findAttribute(logs, "transfer", "amount"); - expect(amountAttr.value).toEqual("1234567ucosm"); - expect(transactionHash).toMatch(/^[0-9A-F]{64}$/); - }); - }); - - describe("getCodes", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.getCodes(); - expect(result.length).toBeGreaterThanOrEqual(1); - const [first] = result; - expect(first).toEqual({ - id: deployedErc20.codeId, - source: deployedErc20.source, - builder: deployedErc20.builder, - checksum: deployedErc20.checksum, - creator: faucet.address, - }); - }); - }); - - describe("getCodeDetails", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.getCodeDetails(1); - - const expectedInfo: Code = { - id: deployedErc20.codeId, - source: deployedErc20.source, - builder: deployedErc20.builder, - checksum: deployedErc20.checksum, - creator: faucet.address, - }; - - // check info - expect(result).toEqual(jasmine.objectContaining(expectedInfo)); - // check data - expect(new Sha256(result.data).digest()).toEqual(fromHex(expectedInfo.checksum)); - }); - - it("caches downloads", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const openedClient = (client as unknown) as PrivateCosmWasmClient; - const getCodeSpy = spyOn(openedClient.restClient, "getCode").and.callThrough(); - - const result1 = await client.getCodeDetails(deployedErc20.codeId); // from network - const result2 = await client.getCodeDetails(deployedErc20.codeId); // from cache - expect(result2).toEqual(result1); - - expect(getCodeSpy).toHaveBeenCalledTimes(1); - }); - }); - - describe("getContracts", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const result = await client.getContracts(1); - expect(result.length).toBeGreaterThanOrEqual(3); - const [hash, isa, jade] = result; - expect(hash).toEqual({ - address: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - codeId: 1, - creator: faucet.address, - label: "HASH", - }); - expect(isa).toEqual({ - address: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", - codeId: 1, - creator: faucet.address, - label: "ISA", - }); - expect(jade).toEqual({ - address: "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c", - codeId: 1, - creator: faucet.address, - label: "JADE", - }); - }); - }); - - describe("getContract", () => { - it("works for HASH instance", async () => { - pendingWithoutWasmd(); - const client = new CosmWasmClient(wasmd.endpoint); - const hash = await client.getContract("cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5"); - expect(hash).toEqual({ - address: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - codeId: 1, - creator: faucet.address, - label: "HASH", - initMsg: { - decimals: 5, - name: "Hash token", - symbol: "HASH", - initial_balances: jasmine.arrayContaining([ - { - address: faucet.address, - amount: "11", - }, - { - address: unused.address, - amount: "12812345", - }, - { - address: guest.address, - amount: "22004000000", - }, - ]), - }, - }); - }); - }); - - describe("queryContractRaw", () => { - const configKey = toAscii("config"); - const otherKey = toAscii("this_does_not_exist"); - let contract: HackatomInstance | undefined; - - beforeAll(async () => { - if (wasmdEnabled()) { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(wasmd.endpoint, faucet.address, (signBytes) => - pen.sign(signBytes), - ); - const { codeId } = await client.upload(getHackatom()); - const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() }; - const { contractAddress } = await client.instantiate(codeId, initMsg, "random hackatom"); - contract = { initMsg: initMsg, address: contractAddress }; - } - }); - - it("can query existing key", async () => { - pendingWithoutWasmd(); - assert(contract); - - const client = new CosmWasmClient(wasmd.endpoint); - const raw = await client.queryContractRaw(contract.address, configKey); - assert(raw, "must get result"); - expect(JSON.parse(fromUtf8(raw))).toEqual({ - verifier: toBase64(Bech32.decode(contract.initMsg.verifier).data), - beneficiary: toBase64(Bech32.decode(contract.initMsg.beneficiary).data), - funder: toBase64(Bech32.decode(faucet.address).data), - }); - }); - - it("can query non-existent key", async () => { - pendingWithoutWasmd(); - assert(contract); - - const client = new CosmWasmClient(wasmd.endpoint); - const raw = await client.queryContractRaw(contract.address, otherKey); - expect(raw).toBeNull(); - }); - - it("errors for non-existent contract", async () => { - pendingWithoutWasmd(); - assert(contract); - - const nonExistentAddress = makeRandomAddress(); - const client = new CosmWasmClient(wasmd.endpoint); - await client.queryContractRaw(nonExistentAddress, configKey).then( - () => fail("must not succeed"), - (error) => expect(error).toMatch(`No contract found at address "${nonExistentAddress}"`), - ); - }); - }); - - describe("queryContractSmart", () => { - let contract: HackatomInstance | undefined; - - beforeAll(async () => { - if (wasmdEnabled()) { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(wasmd.endpoint, faucet.address, (signBytes) => - pen.sign(signBytes), - ); - const { codeId } = await client.upload(getHackatom()); - const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() }; - const { contractAddress } = await client.instantiate(codeId, initMsg, "a different hackatom"); - contract = { initMsg: initMsg, address: contractAddress }; - } - }); - - it("works", async () => { - pendingWithoutWasmd(); - assert(contract); - - const client = new CosmWasmClient(wasmd.endpoint); - const resultDocument = await client.queryContractSmart(contract.address, { verifier: {} }); - expect(resultDocument).toEqual({ verifier: contract.initMsg.verifier }); - }); - - it("errors for malformed query message", async () => { - pendingWithoutWasmd(); - assert(contract); - - const client = new CosmWasmClient(wasmd.endpoint); - await client.queryContractSmart(contract.address, { broken: {} }).then( - () => fail("must not succeed"), - (error) => expect(error).toMatch(/query wasm contract failed: parsing hackatom::contract::QueryMsg/i), - ); - }); - - it("errors for non-existent contract", async () => { - pendingWithoutWasmd(); - - const nonExistentAddress = makeRandomAddress(); - const client = new CosmWasmClient(wasmd.endpoint); - await client.queryContractSmart(nonExistentAddress, { verifier: {} }).then( - () => fail("must not succeed"), - (error) => expect(error).toMatch(`No contract found at address "${nonExistentAddress}"`), - ); - }); - }); -}); diff --git a/packages/sdk/src/cosmwasmclient.ts b/packages/sdk/src/cosmwasmclient.ts deleted file mode 100644 index 73d81a45..00000000 --- a/packages/sdk/src/cosmwasmclient.ts +++ /dev/null @@ -1,439 +0,0 @@ -import { Sha256 } from "@iov/crypto"; -import { Encoding } from "@iov/encoding"; - -import { Coin } from "./coins"; -import { Log, parseLogs } from "./logs"; -import { decodeBech32Pubkey } from "./pubkey"; -import { BroadcastMode, RestClient } from "./restclient"; -import { CosmosSdkTx, JsonObject, PubKey, StdTx } from "./types"; - -export interface GetNonceResult { - readonly accountNumber: number; - readonly sequence: number; -} - -export interface Account { - /** Bech32 account address */ - readonly address: string; - readonly balance: ReadonlyArray; - readonly pubkey: PubKey | undefined; - readonly accountNumber: number; - readonly sequence: number; -} - -export interface PostTxResult { - readonly logs: readonly Log[]; - readonly rawLog: string; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} - -export interface SearchByIdQuery { - readonly id: string; -} - -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: readonly { readonly key: string; readonly value: string }[]; -} - -export type SearchTxQuery = - | SearchByIdQuery - | SearchByHeightQuery - | SearchBySentFromOrToQuery - | SearchByTagsQuery; - -function isSearchByIdQuery(query: SearchTxQuery): query is SearchByIdQuery { - return (query as SearchByIdQuery).id !== undefined; -} - -function isSearchByHeightQuery(query: SearchTxQuery): query is SearchByHeightQuery { - return (query as SearchByHeightQuery).height !== undefined; -} - -function isSearchBySentFromOrToQuery(query: SearchTxQuery): query is SearchBySentFromOrToQuery { - return (query as SearchBySentFromOrToQuery).sentFromOrTo !== undefined; -} - -function isSearchByTagsQuery(query: SearchTxQuery): query is SearchByTagsQuery { - return (query as SearchByTagsQuery).tags !== undefined; -} - -export interface SearchTxFilter { - readonly minHeight?: number; - readonly maxHeight?: number; -} - -export interface Code { - readonly id: number; - /** Bech32 account address */ - readonly creator: string; - /** Hex-encoded sha256 hash of the code stored here */ - readonly checksum: string; - readonly source?: string; - readonly builder?: string; -} - -export interface CodeDetails extends Code { - /** The original wasm bytes */ - readonly data: Uint8Array; -} - -export interface Contract { - readonly address: string; - readonly codeId: number; - /** Bech32 account address */ - readonly creator: string; - readonly label: string; -} - -export interface ContractDetails extends Contract { - /** Argument passed on initialization of the contract */ - readonly initMsg: object; -} - -/** 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; - readonly logs: readonly Log[]; - readonly tx: CosmosSdkTx; - /** The gas limit as set by the user */ - readonly gasWanted?: number; - /** The gas used by the execution */ - readonly gasUsed?: number; - /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ - readonly timestamp: string; -} - -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; -} - -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: ReadonlyArray; -} - -/** Use for testing only */ -export interface PrivateCosmWasmClient { - readonly restClient: RestClient; -} - -export class CosmWasmClient { - protected readonly restClient: RestClient; - /** Any address the chain considers valid (valid bech32 with proper prefix) */ - protected anyValidAddress: string | undefined; - - private readonly codesCache = new Map(); - private chainId: string | undefined; - - /** - * Creates a new client to interact with a CosmWasm blockchain. - * - * This instance does a lot of caching. In order to benefit from that you should try to use one instance - * for the lifetime of your application. When switching backends, a new instance must be created. - * - * @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API) - * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns - */ - public constructor(apiUrl: string, broadcastMode = BroadcastMode.Block) { - this.restClient = new RestClient(apiUrl, broadcastMode); - } - - public async getChainId(): Promise { - if (!this.chainId) { - const response = await this.restClient.nodeInfo(); - const chainId = response.node_info.network; - if (!chainId) throw new Error("Chain ID must not be empty"); - this.chainId = chainId; - } - - return this.chainId; - } - - public async getHeight(): Promise { - if (this.anyValidAddress) { - const { height } = await this.restClient.authAccounts(this.anyValidAddress); - return parseInt(height, 10); - } else { - // Note: this gets inefficient when blocks contain a lot of transactions since it - // requires downloading and deserializing all transactions in the block. - const latest = await this.restClient.blocksLatest(); - return parseInt(latest.block.header.height, 10); - } - } - - /** - * Returns a 32 byte upper-case hex transaction hash (typically used as the transaction ID) - */ - public async getIdentifier(tx: CosmosSdkTx): Promise { - // We consult the REST API because we don't have a local amino encoder - const bytes = await this.restClient.encodeTx(tx); - const hash = new Sha256(bytes).digest(); - return Encoding.toHex(hash).toUpperCase(); - } - - /** - * Returns account number and sequence. - * - * Throws if the account does not exist on chain. - * - * @param address returns data for this address. When unset, the client's sender adddress is used. - */ - public async getNonce(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 nonces.", - ); - } - return { - accountNumber: account.accountNumber, - sequence: account.sequence, - }; - } - - public async getAccount(address: string): Promise { - const account = await this.restClient.authAccounts(address); - const value = account.result.value; - if (value.address === "") { - return undefined; - } else { - this.anyValidAddress = value.address; - return { - address: value.address, - balance: value.coins, - pubkey: value.public_key ? decodeBech32Pubkey(value.public_key) : undefined, - accountNumber: value.account_number, - sequence: value.sequence, - }; - } - } - - /** - * Gets block header and meta - * - * @param height The height of the block. If undefined, the latest height is used. - */ - public async getBlock(height?: number): Promise { - const response = - height !== undefined ? await this.restClient.blocks(height) : await this.restClient.blocksLatest(); - - return { - id: response.block_id.hash, - header: { - version: response.block.header.version, - time: response.block.header.time, - height: parseInt(response.block.header.height, 10), - chainId: response.block.header.chain_id, - }, - txs: (response.block.data.txs || []).map((encoded) => Encoding.fromBase64(encoded)), - }; - } - - 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}&tx.minheight=${minHeight}&tx.maxheight=${maxHeight}`; - } - - let txs: readonly IndexedTx[]; - if (isSearchByIdQuery(query)) { - txs = await this.txsQuery(`tx.hash=${query.id}`); - } else if (isSearchByHeightQuery(query)) { - // optional optimization to avoid network request - if (query.height < minHeight || query.height > maxHeight) { - txs = []; - } else { - txs = await this.txsQuery(`tx.height=${query.height}`); - } - } else if (isSearchBySentFromOrToQuery(query)) { - // We cannot get both in one request (see https://github.com/cosmos/gaia/issues/75) - const sentQuery = withFilters(`message.module=bank&message.sender=${query.sentFromOrTo}`); - const receivedQuery = withFilters(`message.module=bank&transfer.recipient=${query.sentFromOrTo}`); - const sent = await this.txsQuery(sentQuery); - const received = await this.txsQuery(receivedQuery); - - 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("&")); - txs = await this.txsQuery(rawQuery); - } else { - throw new Error("Unknown query type"); - } - - // backend sometimes messes up with min/max height filtering - const filtered = txs.filter((tx) => tx.height >= minHeight && tx.height <= maxHeight); - - return filtered; - } - - public async postTx(tx: StdTx): Promise { - const result = await this.restClient.postTx(tx); - if (!result.txhash.match(/^([0-9A-F][0-9A-F])+$/)) { - throw new Error("Received ill-formatted txhash. Must be non-empty upper-case hex"); - } - - if (result.code) { - throw new Error( - `Error when posting tx ${result.txhash}. Code: ${result.code}; Raw log: ${result.raw_log}`, - ); - } - - return { - logs: result.logs ? parseLogs(result.logs) : [], - rawLog: result.raw_log || "", - transactionHash: result.txhash, - }; - } - - public async getCodes(): Promise { - const result = await this.restClient.listCodeInfo(); - return result.map( - (entry): Code => { - this.anyValidAddress = entry.creator; - return { - id: entry.id, - creator: entry.creator, - checksum: Encoding.toHex(Encoding.fromHex(entry.data_hash)), - source: entry.source || undefined, - builder: entry.builder || undefined, - }; - }, - ); - } - - public async getCodeDetails(codeId: number): Promise { - const cached = this.codesCache.get(codeId); - if (cached) return cached; - - const getCodeResult = await this.restClient.getCode(codeId); - const codeDetails: CodeDetails = { - id: getCodeResult.id, - creator: getCodeResult.creator, - checksum: Encoding.toHex(Encoding.fromHex(getCodeResult.data_hash)), - source: getCodeResult.source || undefined, - builder: getCodeResult.builder || undefined, - data: Encoding.fromBase64(getCodeResult.data), - }; - this.codesCache.set(codeId, codeDetails); - return codeDetails; - } - - public async getContracts(codeId: number): Promise { - const result = await this.restClient.listContractsByCodeId(codeId); - return result.map( - (entry): Contract => ({ - address: entry.address, - codeId: entry.code_id, - creator: entry.creator, - label: entry.label, - }), - ); - } - - /** - * Throws an error if no contract was found at the address - */ - public async getContract(address: string): Promise { - const result = await this.restClient.getContractInfo(address); - if (!result) throw new Error(`No contract found at address "${address}"`); - return { - address: result.address, - codeId: result.code_id, - creator: result.creator, - label: result.label, - initMsg: result.init_msg, - }; - } - - /** - * Returns the data at the key if present (raw contract dependent storage data) - * or null if no data at this key. - * - * Promise is rejected when contract does not exist. - */ - public async queryContractRaw(address: string, key: Uint8Array): Promise { - // just test contract existence - const _info = await this.getContract(address); - - return this.restClient.queryContractRaw(address, key); - } - - /** - * Makes a smart query on the contract, returns the parsed JSON document. - * - * Promise is rejected when contract does not exist. - * Promise is rejected for invalid query format. - * Promise is rejected for invalid response format. - */ - public async queryContractSmart(address: string, queryMsg: object): Promise { - try { - return await this.restClient.queryContractSmart(address, queryMsg); - } catch (error) { - if (error instanceof Error) { - if (error.message.startsWith("not found: contract")) { - throw new Error(`No contract found at address "${address}"`); - } else { - throw error; - } - } else { - throw error; - } - } - } - - private async txsQuery(query: string): Promise { - // TODO: we need proper pagination support - const limit = 100; - const result = await this.restClient.txsQuery(`${query}&limit=${limit}`); - const pages = parseInt(result.page_total, 10); - if (pages > 1) { - throw new Error( - `Found more results on the backend than we can process currently. Results: ${result.total_count}, supported: ${limit}`, - ); - } - return result.txs.map( - (restItem): IndexedTx => ({ - height: parseInt(restItem.height, 10), - hash: restItem.txhash, - code: restItem.code || 0, - rawLog: restItem.raw_log, - logs: parseLogs(restItem.logs || []), - tx: restItem.tx, - timestamp: restItem.timestamp, - }), - ); - } -} diff --git a/packages/sdk/src/decoding.ts b/packages/sdk/src/decoding.ts deleted file mode 100644 index 78286018..00000000 --- a/packages/sdk/src/decoding.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { isStdTx, StdTx } from "./types"; - -export function unmarshalTx(data: Uint8Array): StdTx { - const decoded = JSON.parse(Encoding.fromUtf8(data)); - if (!isStdTx(decoded)) { - throw new Error("Must be json encoded StdTx"); - } - return decoded; -} diff --git a/packages/sdk/src/encoding.spec.ts b/packages/sdk/src/encoding.spec.ts deleted file mode 100644 index ccdb8a4a..00000000 --- a/packages/sdk/src/encoding.spec.ts +++ /dev/null @@ -1 +0,0 @@ -describe("encoding", () => {}); diff --git a/packages/sdk/src/encoding.ts b/packages/sdk/src/encoding.ts deleted file mode 100644 index 8a782944..00000000 --- a/packages/sdk/src/encoding.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { Msg, StdFee, StdTx } from "./types"; - -const { toUtf8 } = Encoding; - -function sortJson(json: any): any { - if (typeof json !== "object" || json === null) { - return json; - } - if (Array.isArray(json)) { - return json.map(sortJson); - } - const sortedKeys = Object.keys(json).sort(); - const result = sortedKeys.reduce( - (accumulator, key) => ({ - ...accumulator, - [key]: sortJson(json[key]), - }), - {}, - ); - return result; -} - -export function marshalTx(tx: StdTx): Uint8Array { - const json = JSON.stringify(tx); - return Encoding.toUtf8(json); -} - -interface SignJson { - readonly account_number: string; - readonly chain_id: string; - readonly fee: StdFee; - readonly memo: string; - readonly msgs: readonly Msg[]; - readonly sequence: string; -} - -export function makeSignBytes( - msgs: readonly Msg[], - fee: StdFee, - chainId: string, - memo: string, - accountNumber: number, - sequence: number, -): Uint8Array { - const signJson: SignJson = { - // eslint-disable-next-line @typescript-eslint/camelcase - account_number: accountNumber.toString(), - // eslint-disable-next-line @typescript-eslint/camelcase - chain_id: chainId, - fee: fee, - memo: memo, - msgs: msgs, - sequence: sequence.toString(), - }; - const signMsg = sortJson(signJson); - return toUtf8(JSON.stringify(signMsg)); -} diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts deleted file mode 100644 index 5162bdab..00000000 --- a/packages/sdk/src/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as logs from "./logs"; -import * as types from "./types"; -export { logs, types }; - -export { pubkeyToAddress } from "./address"; -export { Coin, coin, coins } from "./coins"; -export { unmarshalTx } from "./decoding"; -export { makeSignBytes, marshalTx } from "./encoding"; -export { BroadcastMode, RestClient, TxsResponse } from "./restclient"; -export { - Account, - Block, - BlockHeader, - Code, - CodeDetails, - Contract, - ContractDetails, - CosmWasmClient, - GetNonceResult, - IndexedTx, - PostTxResult, - SearchByHeightQuery, - SearchByIdQuery, - SearchBySentFromOrToQuery, - SearchByTagsQuery, - SearchTxQuery, - SearchTxFilter, -} from "./cosmwasmclient"; -export { makeCosmoshubPath, Pen, PrehashType, Secp256k1Pen } from "./pen"; -export { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey"; -export { findSequenceForSignedTx } from "./sequence"; -export { encodeSecp256k1Signature, decodeSignature } from "./signature"; -export { - ExecuteResult, - FeeTable, - InstantiateResult, - SigningCallback, - SigningCosmWasmClient, - UploadMeta, - UploadResult, -} from "./signingcosmwasmclient"; diff --git a/packages/sdk/src/logs.spec.ts b/packages/sdk/src/logs.spec.ts deleted file mode 100644 index 584d9ef2..00000000 --- a/packages/sdk/src/logs.spec.ts +++ /dev/null @@ -1,165 +0,0 @@ -/* eslint-disable @typescript-eslint/camelcase */ -import { parseAttribute, parseEvent, parseLog, parseLogs } from "./logs"; - -describe("logs", () => { - describe("parseAttribute", () => { - it("works", () => { - const attr = parseAttribute({ key: "a", value: "b" }); - expect(attr).toEqual({ key: "a", value: "b" }); - }); - - it("works for empty value", () => { - const attr = parseAttribute({ key: "foobar", value: "" }); - expect(attr).toEqual({ key: "foobar", value: "" }); - }); - - it("normalized unset value to empty string", () => { - const attr = parseAttribute({ key: "amount" }); - expect(attr).toEqual({ key: "amount", value: "" }); - }); - }); - - describe("parseEvent", () => { - it("works", () => { - const original = { - type: "message", - attributes: [ - { - key: "action", - value: "store-code", - }, - { - key: "module", - value: "wasm", - }, - { - key: "action", - value: "store-code", - }, - { - key: "sender", - value: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - }, - { - key: "code_id", - value: "1", - }, - ], - } as const; - - const event = parseEvent(original); - expect(event).toEqual(original); - }); - - it("works for transfer event", () => { - const original = { - type: "transfer", - attributes: [ - { - key: "recipient", - value: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - }, - { - key: "amount", - }, - ], - } as const; - const expected = { - type: "transfer", - attributes: [ - { - key: "recipient", - value: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", - }, - { - key: "amount", - value: "", - }, - ], - } as const; - - const event = parseEvent(original); - expect(event).toEqual(expected); - }); - }); - - describe("parseLog", () => { - it("works", () => { - const original = { - msg_index: 0, - log: "", - events: [ - { - type: "message", - attributes: [ - { - key: "action", - value: "store-code", - }, - { - key: "module", - value: "wasm", - }, - { - key: "action", - value: "store-code", - }, - { - key: "sender", - value: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - }, - { - key: "code_id", - value: "1", - }, - ], - }, - ], - } as const; - - const log = parseLog(original); - expect(log).toEqual(original); - }); - }); - - describe("parseLogs", () => { - it("works", () => { - const original = [ - { - msg_index: 0, - log: "", - events: [ - { - type: "message", - attributes: [ - { - key: "action", - value: "store-code", - }, - { - key: "module", - value: "wasm", - }, - { - key: "action", - value: "store-code", - }, - { - key: "sender", - value: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - }, - { - key: "code_id", - value: "1", - }, - ], - }, - ], - }, - ] as const; - - const logs = parseLogs(original); - expect(logs).toEqual(original); - }); - }); -}); diff --git a/packages/sdk/src/logs.ts b/packages/sdk/src/logs.ts deleted file mode 100644 index e1eaa1cb..00000000 --- a/packages/sdk/src/logs.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* eslint-disable @typescript-eslint/camelcase */ -import { isNonNullObject } from "@iov/encoding"; - -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); -} - -/** - * 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: "message" | "transfer", - 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/packages/sdk/src/pen.spec.ts b/packages/sdk/src/pen.spec.ts deleted file mode 100644 index 549177a8..00000000 --- a/packages/sdk/src/pen.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Secp256k1, Secp256k1Signature, Sha256 } from "@iov/crypto"; -import { Encoding } from "@iov/encoding"; - -import { Secp256k1Pen } from "./pen"; -import { decodeSignature } from "./signature"; - -const { fromHex } = Encoding; - -describe("Sec256k1Pen", () => { - it("can be constructed", async () => { - const pen = await Secp256k1Pen.fromMnemonic( - "zebra slush diet army arrest purpose hawk source west glimpse custom record", - ); - expect(pen).toBeTruthy(); - }); - - describe("pubkey", () => { - it("returns compressed pubkey", async () => { - // special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling - // m/44'/118'/0'/0/0 - // pubkey: 02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6 - const pen = await Secp256k1Pen.fromMnemonic( - "special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling", - ); - expect(pen.pubkey).toEqual( - fromHex("02baa4ef93f2ce84592a49b1d729c074eab640112522a7a89f7d03ebab21ded7b6"), - ); - }); - }); - - describe("sign", () => { - it("creates correct signatures", async () => { - const pen = await Secp256k1Pen.fromMnemonic( - "special sign fit simple patrol salute grocery chicken wheat radar tonight ceiling", - ); - const data = Encoding.toAscii("foo bar"); - const { pubkey, signature } = decodeSignature(await pen.sign(data)); - - const valid = await Secp256k1.verifySignature( - Secp256k1Signature.fromFixedLength(signature), - new Sha256(data).digest(), - pubkey, - ); - expect(valid).toEqual(true); - }); - }); - - describe("address", () => { - it("creates same address as Go imlementation", async () => { - const pen = await Secp256k1Pen.fromMnemonic( - "oyster design unusual machine spread century engine gravity focus cave carry slot", - ); - expect(pen.address("cosmos")).toEqual("cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u"); - }); - }); -}); diff --git a/packages/sdk/src/pen.ts b/packages/sdk/src/pen.ts deleted file mode 100644 index 936abc0e..00000000 --- a/packages/sdk/src/pen.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { - Bip39, - EnglishMnemonic, - Secp256k1, - Sha256, - Sha512, - Slip10, - Slip10Curve, - Slip10RawIndex, -} from "@iov/crypto"; - -import { rawSecp256k1PubkeyToAddress } from "./address"; -import { encodeSecp256k1Signature } from "./signature"; -import { StdSignature } from "./types"; - -export type PrehashType = "sha256" | "sha512" | null; - -/** - * A pen is the most basic tool you can think of for signing. It works - * everywhere and can be used intuitively by everyone. However, it does not - * come with a great amount of features. End of semi suitable metaphor. - * - * This wraps a single keypair and allows for signing. - * - * Non-goals of this types are: multi account support, persistency, data migrations, - * obfuscation of sensitive data. - */ -export interface Pen { - readonly pubkey: Uint8Array; - readonly sign: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise; -} - -function prehash(bytes: Uint8Array, type: PrehashType): Uint8Array { - switch (type) { - case null: - return new Uint8Array([...bytes]); - case "sha256": - return new Sha256(bytes).digest(); - case "sha512": - return new Sha512(bytes).digest(); - default: - throw new Error("Unknown prehash type"); - } -} - -/** - * The Cosmoshub derivation path in the form `m/44'/118'/0'/0/a` - * with 0-based account index `a`. - */ -export function makeCosmoshubPath(a: number): readonly Slip10RawIndex[] { - return [ - Slip10RawIndex.hardened(44), - Slip10RawIndex.hardened(118), - Slip10RawIndex.hardened(0), - Slip10RawIndex.normal(0), - Slip10RawIndex.normal(a), - ]; -} - -export class Secp256k1Pen implements Pen { - public static async fromMnemonic( - mnemonic: string, - hdPath: readonly Slip10RawIndex[] = makeCosmoshubPath(0), - ): Promise { - const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic)); - const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath); - const uncompressed = (await Secp256k1.makeKeypair(privkey)).pubkey; - return new Secp256k1Pen(privkey, Secp256k1.compressPubkey(uncompressed)); - } - - public readonly pubkey: Uint8Array; - private readonly privkey: Uint8Array; - - private constructor(privkey: Uint8Array, pubkey: Uint8Array) { - this.privkey = privkey; - this.pubkey = pubkey; - } - - /** - * Creates and returns a signature - */ - public async sign(signBytes: Uint8Array, prehashType: PrehashType = "sha256"): Promise { - const message = prehash(signBytes, prehashType); - const signature = await Secp256k1.createSignature(message, this.privkey); - const fixedLengthSignature = new Uint8Array([...signature.r(32), ...signature.s(32)]); - return encodeSecp256k1Signature(this.pubkey, fixedLengthSignature); - } - - public address(prefix: string): string { - return rawSecp256k1PubkeyToAddress(this.pubkey, prefix); - } -} diff --git a/packages/sdk/src/pubkey.spec.ts b/packages/sdk/src/pubkey.spec.ts deleted file mode 100644 index cb344f7b..00000000 --- a/packages/sdk/src/pubkey.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey"; -import { PubKey } from "./types"; - -const { fromBase64 } = Encoding; - -describe("pubkey", () => { - describe("encodeSecp256k1Pubkey", () => { - it("encodes a compresed pubkey", () => { - const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); - expect(encodeSecp256k1Pubkey(pubkey)).toEqual({ - type: "tendermint/PubKeySecp256k1", - value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", - }); - }); - - it("throws for uncompressed public keys", () => { - const pubkey = fromBase64( - "BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=", - ); - expect(() => encodeSecp256k1Pubkey(pubkey)).toThrowError(/public key must be compressed secp256k1/i); - }); - }); - - describe("decodeBech32Pubkey", () => { - it("works", () => { - expect( - decodeBech32Pubkey("cosmospub1addwnpepqd8sgxq7aw348ydctp3n5ajufgxp395hksxjzc6565yfp56scupfqhlgyg5"), - ).toEqual({ - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }); - }); - - it("works for enigma pubkey", () => { - expect( - decodeBech32Pubkey("enigmapub1addwnpepqw5k9p439nw0zpg2aundx4umwx4nw233z5prpjqjv5anl5grmnchzp2xwvv"), - ).toEqual({ - type: "tendermint/PubKeySecp256k1", - value: "A6lihrEs3PEFCu8m01ebcas3KjEVAjDIEmU7P9ED3PFx", - }); - }); - }); - - describe("encodeBech32Pubkey", () => { - it("works for secp256k1", () => { - const pubkey: PubKey = { - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }; - expect(encodeBech32Pubkey(pubkey, "cosmospub")).toEqual( - "cosmospub1addwnpepqd8sgxq7aw348ydctp3n5ajufgxp395hksxjzc6565yfp56scupfqhlgyg5", - ); - }); - }); -}); diff --git a/packages/sdk/src/pubkey.ts b/packages/sdk/src/pubkey.ts deleted file mode 100644 index 8835b97a..00000000 --- a/packages/sdk/src/pubkey.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Bech32, Encoding } from "@iov/encoding"; -import equal from "fast-deep-equal"; - -import { PubKey, pubkeyType } from "./types"; - -export function encodeSecp256k1Pubkey(pubkey: Uint8Array): PubKey { - if (pubkey.length !== 33 || (pubkey[0] !== 0x02 && pubkey[0] !== 0x03)) { - throw new Error("Public key must be compressed secp256k1, i.e. 33 bytes starting with 0x02 or 0x03"); - } - return { - type: pubkeyType.secp256k1, - value: Encoding.toBase64(pubkey), - }; -} - -// As discussed in https://github.com/binance-chain/javascript-sdk/issues/163 -// Prefixes listed here: https://github.com/tendermint/tendermint/blob/d419fffe18531317c28c29a292ad7d253f6cafdf/docs/spec/blockchain/encoding.md#public-key-cryptography -// Last bytes is varint-encoded length prefix -const pubkeyAminoPrefixSecp256k1 = Encoding.fromHex("eb5ae98721"); -const pubkeyAminoPrefixEd25519 = Encoding.fromHex("1624de6420"); -const pubkeyAminoPrefixSr25519 = Encoding.fromHex("0dfb1005"); -const pubkeyAminoPrefixLength = pubkeyAminoPrefixSecp256k1.length; - -export function decodeBech32Pubkey(bechEncoded: string): PubKey { - const { data } = Bech32.decode(bechEncoded); - - const aminoPrefix = data.slice(0, pubkeyAminoPrefixLength); - const rest = data.slice(pubkeyAminoPrefixLength); - if (equal(aminoPrefix, pubkeyAminoPrefixSecp256k1)) { - if (rest.length !== 33) { - throw new Error("Invalid rest data length. Expected 33 bytes (compressed secp256k1 pubkey)."); - } - return { - type: pubkeyType.secp256k1, - value: Encoding.toBase64(rest), - }; - } else if (equal(aminoPrefix, pubkeyAminoPrefixEd25519)) { - if (rest.length !== 32) { - throw new Error("Invalid rest data length. Expected 32 bytes (Ed25519 pubkey)."); - } - return { - type: pubkeyType.ed25519, - value: Encoding.toBase64(rest), - }; - } else if (equal(aminoPrefix, pubkeyAminoPrefixSr25519)) { - if (rest.length !== 32) { - throw new Error("Invalid rest data length. Expected 32 bytes (Sr25519 pubkey)."); - } - return { - type: pubkeyType.sr25519, - value: Encoding.toBase64(rest), - }; - } else { - throw new Error("Unsupported Pubkey type. Amino prefix: " + Encoding.toHex(aminoPrefix)); - } -} - -export function encodeBech32Pubkey(pubkey: PubKey, prefix: string): string { - let aminoPrefix: Uint8Array; - switch (pubkey.type) { - // Note: please don't add cases here without writing additional unit tests - case pubkeyType.secp256k1: - aminoPrefix = pubkeyAminoPrefixSecp256k1; - break; - default: - throw new Error("Unsupported pubkey type"); - } - - const data = new Uint8Array([...aminoPrefix, ...Encoding.fromBase64(pubkey.value)]); - return Bech32.encode(prefix, data); -} diff --git a/packages/sdk/src/restclient.spec.ts b/packages/sdk/src/restclient.spec.ts deleted file mode 100644 index b65a9d90..00000000 --- a/packages/sdk/src/restclient.spec.ts +++ /dev/null @@ -1,1378 +0,0 @@ -/* eslint-disable @typescript-eslint/camelcase */ -import { Sha256 } from "@iov/crypto"; -import { Encoding } from "@iov/encoding"; -import { assert, sleep } from "@iov/utils"; -import { ReadonlyDate } from "readonly-date"; - -import { rawSecp256k1PubkeyToAddress } from "./address"; -import { Coin } from "./coins"; -import { makeSignBytes } from "./encoding"; -import { findAttribute, parseLogs } from "./logs"; -import { makeCosmoshubPath, Pen, Secp256k1Pen } from "./pen"; -import { encodeBech32Pubkey } from "./pubkey"; -import { PostTxsResponse, RestClient, TxsResponse } from "./restclient"; -import { SigningCosmWasmClient } from "./signingcosmwasmclient"; -import cosmoshub from "./testdata/cosmoshub.json"; -import { - bech32AddressMatcher, - deployedErc20, - faucet, - fromOneElementArray, - getHackatom, - makeRandomAddress, - nonNegativeIntegerMatcher, - pendingWithoutWasmd, - semverMatcher, - tendermintAddressMatcher, - tendermintIdMatcher, - tendermintOptionalIdMatcher, - tendermintShortHashMatcher, - unused, - wasmd, - wasmdEnabled, -} from "./testutils.spec"; -import { - isMsgInstantiateContract, - isMsgStoreCode, - Msg, - MsgExecuteContract, - MsgInstantiateContract, - MsgSend, - MsgStoreCode, - StdFee, - StdSignature, - StdTx, -} from "./types"; - -const { fromAscii, fromBase64, fromHex, toAscii, toBase64, toHex } = Encoding; - -const emptyAddress = "cosmos1ltkhnmdcqemmd2tkhnx7qx66tq7e0wykw2j85k"; - -function makeSignedTx(firstMsg: Msg, fee: StdFee, memo: string, firstSignature: StdSignature): StdTx { - return { - msg: [firstMsg], - fee: fee, - memo: memo, - signatures: [firstSignature], - }; -} - -async function uploadCustomContract( - client: RestClient, - pen: Pen, - wasmCode: Uint8Array, -): Promise { - const memo = "My first contract on chain"; - const theMsg: MsgStoreCode = { - type: "wasm/store-code", - value: { - sender: faucet.address, - wasm_byte_code: toBase64(wasmCode), - source: "https://github.com/confio/cosmwasm/raw/0.7/lib/vm/testdata/contract_0.6.wasm", - builder: "confio/cosmwasm-opt:0.6.2", - }, - }; - const fee: StdFee = { - amount: [ - { - amount: "5000000", - denom: "ucosm", - }, - ], - gas: "89000000", - }; - - const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; - const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence); - const signature = await pen.sign(signBytes); - const signedTx = makeSignedTx(theMsg, fee, memo, signature); - return client.postTx(signedTx); -} - -async function uploadContract(client: RestClient, pen: Pen): Promise { - return uploadCustomContract(client, pen, getHackatom()); -} - -async function instantiateContract( - client: RestClient, - pen: Pen, - codeId: number, - beneficiaryAddress: string, - transferAmount?: readonly Coin[], -): Promise { - const memo = "Create an escrow instance"; - const theMsg: MsgInstantiateContract = { - type: "wasm/instantiate", - value: { - sender: faucet.address, - code_id: codeId.toString(), - label: "my escrow", - init_msg: { - verifier: faucet.address, - beneficiary: beneficiaryAddress, - }, - init_funds: transferAmount || [], - }, - }; - const fee: StdFee = { - amount: [ - { - amount: "5000000", - denom: "ucosm", - }, - ], - gas: "89000000", - }; - - const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; - const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence); - const signature = await pen.sign(signBytes); - const signedTx = makeSignedTx(theMsg, fee, memo, signature); - return client.postTx(signedTx); -} - -async function executeContract( - client: RestClient, - pen: Pen, - contractAddress: string, -): Promise { - const memo = "Time for action"; - const theMsg: MsgExecuteContract = { - type: "wasm/execute", - value: { - sender: faucet.address, - contract: contractAddress, - msg: { release: {} }, - sent_funds: [], - }, - }; - const fee: StdFee = { - amount: [ - { - amount: "5000000", - denom: "ucosm", - }, - ], - gas: "89000000", - }; - - const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; - const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence); - const signature = await pen.sign(signBytes); - const signedTx = makeSignedTx(theMsg, fee, memo, signature); - return client.postTx(signedTx); -} - -describe("RestClient", () => { - it("can be constructed", () => { - const client = new RestClient(wasmd.endpoint); - expect(client).toBeTruthy(); - }); - - // The /auth endpoints - - describe("authAccounts", () => { - it("works for unused account without pubkey", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - const { height, result } = await client.authAccounts(unused.address); - expect(height).toMatch(nonNegativeIntegerMatcher); - expect(result).toEqual({ - type: "cosmos-sdk/Account", - value: { - address: unused.address, - public_key: "", // not known to the chain - coins: [ - { - amount: "1000000000", - denom: "ucosm", - }, - { - amount: "1000000000", - denom: "ustake", - }, - ], - account_number: unused.accountNumber, - sequence: 0, - }, - }); - }); - - // This fails in the first test run if you forget to run `./scripts/wasmd/init.sh` - it("has correct pubkey for faucet", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - const { result } = await client.authAccounts(faucet.address); - expect(result.value).toEqual( - jasmine.objectContaining({ - public_key: encodeBech32Pubkey(faucet.pubkey, "cosmospub"), - }), - ); - }); - - // This property is used by CosmWasmClient.getAccount - it("returns empty address for non-existent account", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - const nonExistentAccount = makeRandomAddress(); - const { result } = await client.authAccounts(nonExistentAccount); - expect(result).toEqual({ - type: "cosmos-sdk/Account", - value: jasmine.objectContaining({ address: "" }), - }); - }); - }); - - // The /blocks endpoints - - describe("blocksLatest", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - const response = await client.blocksLatest(); - - // id - expect(response.block_id.hash).toMatch(tendermintIdMatcher); - - // header - expect(response.block.header.version).toEqual({ block: "10", app: "0" }); - expect(parseInt(response.block.header.height, 10)).toBeGreaterThanOrEqual(1); - expect(response.block.header.chain_id).toEqual(wasmd.chainId); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeGreaterThanOrEqual( - ReadonlyDate.now() - 5_000, - ); - expect(response.block.header.last_commit_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.last_block_id.hash).toMatch(tendermintIdMatcher); - expect(response.block.header.data_hash).toMatch(tendermintOptionalIdMatcher); - expect(response.block.header.validators_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.next_validators_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.consensus_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.app_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.last_results_hash).toMatch(tendermintOptionalIdMatcher); - expect(response.block.header.evidence_hash).toMatch(tendermintOptionalIdMatcher); - expect(response.block.header.proposer_address).toMatch(tendermintAddressMatcher); - - // data - expect(response.block.data.txs === null || Array.isArray(response.block.data.txs)).toEqual(true); - }); - }); - - describe("blocks", () => { - it("works for block by height", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - const height = parseInt((await client.blocksLatest()).block.header.height, 10); - const response = await client.blocks(height - 1); - - // id - expect(response.block_id.hash).toMatch(tendermintIdMatcher); - - // header - expect(response.block.header.version).toEqual({ block: "10", app: "0" }); - expect(response.block.header.height).toEqual(`${height - 1}`); - expect(response.block.header.chain_id).toEqual(wasmd.chainId); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeLessThan(ReadonlyDate.now()); - expect(new ReadonlyDate(response.block.header.time).getTime()).toBeGreaterThanOrEqual( - ReadonlyDate.now() - 5_000, - ); - expect(response.block.header.last_commit_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.last_block_id.hash).toMatch(tendermintIdMatcher); - expect(response.block.header.data_hash).toMatch(tendermintOptionalIdMatcher); - expect(response.block.header.validators_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.next_validators_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.consensus_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.app_hash).toMatch(tendermintIdMatcher); - expect(response.block.header.last_results_hash).toMatch(tendermintOptionalIdMatcher); - expect(response.block.header.evidence_hash).toMatch(tendermintOptionalIdMatcher); - expect(response.block.header.proposer_address).toMatch(tendermintAddressMatcher); - - // data - expect(response.block.data.txs === null || Array.isArray(response.block.data.txs)).toEqual(true); - }); - }); - - // The /node_info endpoint - - describe("nodeInfo", () => { - it("works", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - const { node_info, application_version } = await client.nodeInfo(); - - expect(node_info).toEqual({ - protocol_version: { p2p: "7", block: "10", app: "0" }, - id: jasmine.stringMatching(tendermintShortHashMatcher), - listen_addr: "tcp://0.0.0.0:26656", - network: wasmd.chainId, - version: jasmine.stringMatching(/^0\.33\.[0-9]+$/), - channels: "4020212223303800", - moniker: wasmd.chainId, - other: { tx_index: "on", rpc_address: "tcp://0.0.0.0:26657" }, - }); - expect(application_version).toEqual({ - name: "wasm", - server_name: "wasmd", - client_name: "wasmcli", - version: jasmine.stringMatching(semverMatcher), - commit: jasmine.stringMatching(tendermintShortHashMatcher), - build_tags: "netgo,ledger", - go: jasmine.stringMatching(/^go version go1\.[0-9]+\.[0-9]+ linux\/amd64$/), - }); - }); - }); - - // The /txs endpoints - - describe("txById", () => { - let successful: - | { - readonly sender: string; - readonly recipient: string; - readonly hash: string; - } - | undefined; - let unsuccessful: - | { - readonly sender: string; - readonly recipient: string; - readonly hash: string; - } - | undefined; - - beforeAll(async () => { - if (wasmdEnabled()) { - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(wasmd.endpoint, faucet.address, (signBytes) => - pen.sign(signBytes), - ); - - { - const recipient = makeRandomAddress(); - const transferAmount = { - denom: "ucosm", - amount: "1234567", - }; - const result = await client.sendTokens(recipient, [transferAmount]); - successful = { - sender: faucet.address, - recipient: recipient, - hash: result.transactionHash, - }; - } - - { - const memo = "Sending more than I can afford"; - const recipient = makeRandomAddress(); - const transferAmount = [ - { - denom: "ucosm", - amount: "123456700000000", - }, - ]; - const sendMsg: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - // eslint-disable-next-line @typescript-eslint/camelcase - from_address: faucet.address, - // eslint-disable-next-line @typescript-eslint/camelcase - to_address: recipient, - amount: transferAmount, - }, - }; - const fee = { - amount: [ - { - denom: "ucosm", - amount: "2000", - }, - ], - gas: "80000", // 80k - }; - const { accountNumber, sequence } = await client.getNonce(); - const chainId = await client.getChainId(); - const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence); - const signature = await pen.sign(signBytes); - const signedTx = { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; - const transactionId = await client.getIdentifier({ type: "cosmos-sdk/StdTx", value: signedTx }); - try { - await client.postTx(signedTx); - } catch (error) { - // postTx() throws on execution failures, which is a questionable design. Ignore for now. - // console.log(error); - } - unsuccessful = { - sender: faucet.address, - recipient: recipient, - hash: transactionId, - }; - } - - await sleep(50); // wait until transactions are indexed - } - }); - - it("works for successful transaction", async () => { - pendingWithoutWasmd(); - assert(successful); - const client = new RestClient(wasmd.endpoint); - const result = await client.txById(successful.hash); - expect(result.height).toBeGreaterThanOrEqual(1); - expect(result.txhash).toEqual(successful.hash); - expect(result.codespace).toBeUndefined(); - expect(result.code).toBeUndefined(); - const logs = parseLogs(result.logs); - expect(logs).toEqual([ - { - msg_index: 0, - log: "", - events: [ - { - type: "message", - attributes: [ - { key: "action", value: "send" }, - { key: "sender", value: successful.sender }, - { key: "module", value: "bank" }, - ], - }, - { - type: "transfer", - attributes: [ - { key: "recipient", value: successful.recipient }, - { key: "sender", value: successful.sender }, - { key: "amount", value: "1234567ucosm" }, - ], - }, - ], - }, - ]); - }); - - it("works for unsuccessful transaction", async () => { - pendingWithoutWasmd(); - assert(unsuccessful); - const client = new RestClient(wasmd.endpoint); - const result = await client.txById(unsuccessful.hash); - expect(result.height).toBeGreaterThanOrEqual(1); - expect(result.txhash).toEqual(unsuccessful.hash); - expect(result.codespace).toEqual("sdk"); - expect(result.code).toEqual(5); - expect(result.logs).toBeUndefined(); - expect(result.raw_log).toContain("insufficient funds"); - }); - }); - - describe("txsQuery", () => { - let posted: - | { - readonly sender: string; - readonly recipient: string; - readonly hash: string; - readonly height: number; - readonly tx: TxsResponse; - } - | undefined; - - beforeAll(async () => { - if (wasmdEnabled()) { - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(wasmd.endpoint, faucet.address, (signBytes) => - pen.sign(signBytes), - ); - - const recipient = makeRandomAddress(); - const transferAmount = [ - { - denom: "ucosm", - amount: "1234567", - }, - ]; - const result = await client.sendTokens(recipient, transferAmount); - - await sleep(50); // wait until tx is indexed - const txDetails = await new RestClient(wasmd.endpoint).txById(result.transactionHash); - posted = { - sender: faucet.address, - recipient: recipient, - hash: result.transactionHash, - height: Number.parseInt(txDetails.height, 10), - tx: txDetails, - }; - } - }); - - it("can query transactions by height", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const result = await client.txsQuery(`tx.height=${posted.height}&limit=26`); - expect(result).toEqual({ - count: "1", - limit: "26", - page_number: "1", - page_total: "1", - total_count: "1", - txs: [posted.tx], - }); - }); - - it("can query transactions by ID", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const result = await client.txsQuery(`tx.hash=${posted.hash}&limit=26`); - expect(result).toEqual({ - count: "1", - limit: "26", - page_number: "1", - page_total: "1", - total_count: "1", - txs: [posted.tx], - }); - }); - - it("can query transactions by sender", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const result = await client.txsQuery(`message.sender=${posted.sender}&limit=200`); - expect(parseInt(result.count, 10)).toBeGreaterThanOrEqual(1); - expect(parseInt(result.limit, 10)).toEqual(200); - expect(parseInt(result.page_number, 10)).toEqual(1); - expect(parseInt(result.page_total, 10)).toEqual(1); - expect(parseInt(result.total_count, 10)).toBeGreaterThanOrEqual(1); - expect(result.txs.length).toBeGreaterThanOrEqual(1); - expect(result.txs[result.txs.length - 1]).toEqual(posted.tx); - }); - - it("can query transactions by recipient", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const result = await client.txsQuery(`transfer.recipient=${posted.recipient}&limit=200`); - expect(parseInt(result.count, 10)).toEqual(1); - expect(parseInt(result.limit, 10)).toEqual(200); - expect(parseInt(result.page_number, 10)).toEqual(1); - expect(parseInt(result.page_total, 10)).toEqual(1); - expect(parseInt(result.total_count, 10)).toEqual(1); - expect(result.txs.length).toBeGreaterThanOrEqual(1); - expect(result.txs[result.txs.length - 1]).toEqual(posted.tx); - }); - - it("can filter by tx.hash and tx.minheight", async () => { - pending("This combination is broken 🤷‍♂️. Handle client-side at higher level."); - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const hashQuery = `tx.hash=${posted.hash}`; - - { - const { count } = await client.txsQuery(`${hashQuery}&tx.minheight=0`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${hashQuery}&tx.minheight=${posted.height - 1}`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${hashQuery}&tx.minheight=${posted.height}`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${hashQuery}&tx.minheight=${posted.height + 1}`); - expect(count).toEqual("0"); - } - }); - - it("can filter by recipient and tx.minheight", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const recipientQuery = `transfer.recipient=${posted.recipient}`; - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.minheight=0`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.minheight=${posted.height - 1}`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.minheight=${posted.height}`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.minheight=${posted.height + 1}`); - expect(count).toEqual("0"); - } - }); - - it("can filter by recipient and tx.maxheight", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const recipientQuery = `transfer.recipient=${posted.recipient}`; - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.maxheight=9999999999999`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.maxheight=${posted.height + 1}`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.maxheight=${posted.height}`); - expect(count).toEqual("1"); - } - - { - const { count } = await client.txsQuery(`${recipientQuery}&tx.maxheight=${posted.height - 1}`); - expect(count).toEqual("0"); - } - }); - - it("can query by tags (module + code_id)", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - const result = await client.txsQuery(`message.module=wasm&message.code_id=${deployedErc20.codeId}`); - expect(parseInt(result.count, 10)).toBeGreaterThanOrEqual(4); - - // Check first 4 results - const [store, hash, isa, jade] = result.txs.map((tx) => fromOneElementArray(tx.tx.value.msg)); - assert(isMsgStoreCode(store)); - assert(isMsgInstantiateContract(hash)); - assert(isMsgInstantiateContract(isa)); - assert(isMsgInstantiateContract(jade)); - expect(store.value).toEqual( - jasmine.objectContaining({ - sender: faucet.address, - source: deployedErc20.source, - builder: deployedErc20.builder, - }), - ); - expect(hash.value).toEqual({ - code_id: deployedErc20.codeId.toString(), - init_funds: [], - init_msg: jasmine.objectContaining({ - symbol: "HASH", - }), - label: "HASH", - sender: faucet.address, - }); - expect(isa.value).toEqual({ - code_id: deployedErc20.codeId.toString(), - init_funds: [], - init_msg: jasmine.objectContaining({ symbol: "ISA" }), - label: "ISA", - sender: faucet.address, - }); - expect(jade.value).toEqual({ - code_id: deployedErc20.codeId.toString(), - init_funds: [], - init_msg: jasmine.objectContaining({ symbol: "JADE" }), - label: "JADE", - sender: faucet.address, - }); - }); - - // Like previous test but filtered by message.action=store-code and message.action=instantiate - it("can query by tags (module + code_id + action)", async () => { - pendingWithoutWasmd(); - assert(posted); - const client = new RestClient(wasmd.endpoint); - - { - const uploads = await client.txsQuery( - `message.module=wasm&message.code_id=${deployedErc20.codeId}&message.action=store-code`, - ); - expect(parseInt(uploads.count, 10)).toEqual(1); - const store = fromOneElementArray(uploads.txs[0].tx.value.msg); - assert(isMsgStoreCode(store)); - expect(store.value).toEqual( - jasmine.objectContaining({ - sender: faucet.address, - source: deployedErc20.source, - builder: deployedErc20.builder, - }), - ); - } - - { - const instantiations = await client.txsQuery( - `message.module=wasm&message.code_id=${deployedErc20.codeId}&message.action=instantiate`, - ); - expect(parseInt(instantiations.count, 10)).toBeGreaterThanOrEqual(3); - const [hash, isa, jade] = instantiations.txs.map((tx) => fromOneElementArray(tx.tx.value.msg)); - assert(isMsgInstantiateContract(hash)); - assert(isMsgInstantiateContract(isa)); - assert(isMsgInstantiateContract(jade)); - expect(hash.value).toEqual({ - code_id: deployedErc20.codeId.toString(), - init_funds: [], - init_msg: jasmine.objectContaining({ - symbol: "HASH", - }), - label: "HASH", - sender: faucet.address, - }); - expect(isa.value).toEqual({ - code_id: deployedErc20.codeId.toString(), - init_funds: [], - init_msg: jasmine.objectContaining({ symbol: "ISA" }), - label: "ISA", - sender: faucet.address, - }); - expect(jade.value).toEqual({ - code_id: deployedErc20.codeId.toString(), - init_funds: [], - init_msg: jasmine.objectContaining({ symbol: "JADE" }), - label: "JADE", - sender: faucet.address, - }); - } - }); - }); - - describe("encodeTx", () => { - it("works for cosmoshub example", async () => { - pendingWithoutWasmd(); - const client = new RestClient(wasmd.endpoint); - expect(await client.encodeTx(cosmoshub.tx)).toEqual(fromBase64(cosmoshub.tx_data)); - }); - }); - - describe("postTx", () => { - it("can send tokens", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - - const memo = "My first contract on chain"; - const theMsg: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: faucet.address, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const client = new RestClient(wasmd.endpoint); - const { account_number, sequence } = (await client.authAccounts(faucet.address)).result.value; - - const signBytes = makeSignBytes([theMsg], fee, wasmd.chainId, memo, account_number, sequence); - const signature = await pen.sign(signBytes); - const signedTx = makeSignedTx(theMsg, fee, memo, signature); - const result = await client.postTx(signedTx); - expect(result.code).toBeUndefined(); - expect(result).toEqual({ - height: jasmine.stringMatching(nonNegativeIntegerMatcher), - txhash: jasmine.stringMatching(tendermintIdMatcher), - // code is not set - raw_log: jasmine.stringMatching(/^\[.+\]$/i), - logs: jasmine.any(Array), - gas_wanted: jasmine.stringMatching(nonNegativeIntegerMatcher), - gas_used: jasmine.stringMatching(nonNegativeIntegerMatcher), - }); - }); - - it("can't send transaction with additional signatures", async () => { - pendingWithoutWasmd(); - const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0)); - const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1)); - const account3 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(2)); - const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos"); - const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos"); - const address3 = rawSecp256k1PubkeyToAddress(account3.pubkey, "cosmos"); - - const memo = "My first contract on chain"; - const theMsg: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address1, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const client = new RestClient(wasmd.endpoint); - const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value; - const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value; - const { account_number: an3, sequence: sequence3 } = (await client.authAccounts(address3)).result.value; - - const signBytes1 = makeSignBytes([theMsg], fee, wasmd.chainId, memo, an1, sequence1); - const signBytes2 = makeSignBytes([theMsg], fee, wasmd.chainId, memo, an2, sequence2); - const signBytes3 = makeSignBytes([theMsg], fee, wasmd.chainId, memo, an3, sequence3); - const signature1 = await account1.sign(signBytes1); - const signature2 = await account2.sign(signBytes2); - const signature3 = await account3.sign(signBytes3); - const signedTx = { - msg: [theMsg], - fee: fee, - memo: memo, - signatures: [signature1, signature2, signature3], - }; - const postResult = await client.postTx(signedTx); - // console.log(postResult.raw_log); - expect(postResult.code).toEqual(4); - expect(postResult.raw_log).toContain("wrong number of signers"); - }); - - it("can send multiple messages with one signature", async () => { - pendingWithoutWasmd(); - const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0)); - const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos"); - - const memo = "My first contract on chain"; - const msg1: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address1, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - const msg2: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address1, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "7654321", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const client = new RestClient(wasmd.endpoint); - const { account_number, sequence } = (await client.authAccounts(address1)).result.value; - - const signBytes = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, account_number, sequence); - const signature1 = await account1.sign(signBytes); - const signedTx = { - msg: [msg1, msg2], - fee: fee, - memo: memo, - signatures: [signature1], - }; - const postResult = await client.postTx(signedTx); - // console.log(postResult.raw_log); - expect(postResult.code).toBeUndefined(); - }); - - it("can send multiple messages with multiple signatures", async () => { - pendingWithoutWasmd(); - const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0)); - const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1)); - const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos"); - const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos"); - - const memo = "My first contract on chain"; - const msg1: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address1, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - const msg2: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address2, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "7654321", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const client = new RestClient(wasmd.endpoint); - const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value; - const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value; - - const signBytes1 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an1, sequence1); - const signBytes2 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an2, sequence2); - const signature1 = await account1.sign(signBytes1); - const signature2 = await account2.sign(signBytes2); - const signedTx = { - msg: [msg2, msg1], - fee: fee, - memo: memo, - signatures: [signature2, signature1], - }; - const postResult = await client.postTx(signedTx); - // console.log(postResult.raw_log); - expect(postResult.code).toBeUndefined(); - - await sleep(500); - const searched = await client.txsQuery(`tx.hash=${postResult.txhash}`); - expect(searched.txs.length).toEqual(1); - expect(searched.txs[0].tx.value.signatures).toEqual([signature2, signature1]); - }); - - it("can't send transaction with wrong signature order (1)", async () => { - pendingWithoutWasmd(); - const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0)); - const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1)); - const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos"); - const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos"); - - const memo = "My first contract on chain"; - const msg1: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address1, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - const msg2: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address2, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "7654321", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const client = new RestClient(wasmd.endpoint); - const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value; - const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value; - - const signBytes1 = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, an1, sequence1); - const signBytes2 = makeSignBytes([msg1, msg2], fee, wasmd.chainId, memo, an2, sequence2); - const signature1 = await account1.sign(signBytes1); - const signature2 = await account2.sign(signBytes2); - const signedTx = { - msg: [msg1, msg2], - fee: fee, - memo: memo, - signatures: [signature2, signature1], - }; - const postResult = await client.postTx(signedTx); - // console.log(postResult.raw_log); - expect(postResult.code).toEqual(8); - }); - - it("can't send transaction with wrong signature order (2)", async () => { - pendingWithoutWasmd(); - const account1 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(0)); - const account2 = await Secp256k1Pen.fromMnemonic(faucet.mnemonic, makeCosmoshubPath(1)); - const address1 = rawSecp256k1PubkeyToAddress(account1.pubkey, "cosmos"); - const address2 = rawSecp256k1PubkeyToAddress(account2.pubkey, "cosmos"); - - const memo = "My first contract on chain"; - const msg1: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address1, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "1234567", - }, - ], - }, - }; - const msg2: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - from_address: address2, - to_address: emptyAddress, - amount: [ - { - denom: "ucosm", - amount: "7654321", - }, - ], - }, - }; - - const fee: StdFee = { - amount: [ - { - amount: "5000", - denom: "ucosm", - }, - ], - gas: "890000", - }; - - const client = new RestClient(wasmd.endpoint); - const { account_number: an1, sequence: sequence1 } = (await client.authAccounts(address1)).result.value; - const { account_number: an2, sequence: sequence2 } = (await client.authAccounts(address2)).result.value; - - const signBytes1 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an1, sequence1); - const signBytes2 = makeSignBytes([msg2, msg1], fee, wasmd.chainId, memo, an2, sequence2); - const signature1 = await account1.sign(signBytes1); - const signature2 = await account2.sign(signBytes2); - const signedTx = { - msg: [msg2, msg1], - fee: fee, - memo: memo, - signatures: [signature1, signature2], - }; - const postResult = await client.postTx(signedTx); - // console.log(postResult.raw_log); - expect(postResult.code).toEqual(8); - }); - - it("can upload, instantiate and execute wasm", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new RestClient(wasmd.endpoint); - - const transferAmount: readonly Coin[] = [ - { - amount: "1234", - denom: "ucosm", - }, - { - amount: "321", - denom: "ustake", - }, - ]; - const beneficiaryAddress = makeRandomAddress(); - - let codeId: number; - - // upload - { - // console.log("Raw log:", result.raw_log); - const result = await uploadContract(client, pen); - expect(result.code).toBeFalsy(); - const logs = parseLogs(result.logs); - const codeIdAttr = findAttribute(logs, "message", "code_id"); - codeId = Number.parseInt(codeIdAttr.value, 10); - expect(codeId).toBeGreaterThanOrEqual(1); - expect(codeId).toBeLessThanOrEqual(200); - } - - let contractAddress: string; - - // instantiate - { - const result = await instantiateContract(client, pen, codeId, beneficiaryAddress, transferAmount); - expect(result.code).toBeFalsy(); - // console.log("Raw log:", result.raw_log); - const logs = parseLogs(result.logs); - const contractAddressAttr = findAttribute(logs, "message", "contract_address"); - contractAddress = contractAddressAttr.value; - const amountAttr = findAttribute(logs, "transfer", "amount"); - expect(amountAttr.value).toEqual("1234ucosm,321ustake"); - - const balance = (await client.authAccounts(contractAddress)).result.value.coins; - expect(balance).toEqual(transferAmount); - } - - // execute - { - const result = await executeContract(client, pen, contractAddress); - expect(result.code).toBeFalsy(); - // console.log("Raw log:", result.logs); - const logs = parseLogs(result.logs); - const wasmEvent = logs.find(() => true)?.events.find((e) => e.type === "wasm"); - assert(wasmEvent, "Event of type wasm expected"); - expect(wasmEvent.attributes).toContain({ key: "action", value: "release" }); - expect(wasmEvent.attributes).toContain({ - key: "destination", - value: beneficiaryAddress, - }); - - // Verify token transfer from contract to beneficiary - const beneficiaryBalance = (await client.authAccounts(beneficiaryAddress)).result.value.coins; - expect(beneficiaryBalance).toEqual(transferAmount); - const contractBalance = (await client.authAccounts(contractAddress)).result.value.coins; - expect(contractBalance).toEqual([]); - } - }); - }); - - // The /wasm endpoints - - describe("query", () => { - it("can list upload code", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new RestClient(wasmd.endpoint); - - // check with contracts were here first to compare - const existingInfos = await client.listCodeInfo(); - existingInfos.forEach((val, idx) => expect(val.id).toEqual(idx + 1)); - const numExisting = existingInfos.length; - - // upload data - const wasmCode = getHackatom(); - const result = await uploadCustomContract(client, pen, wasmCode); - expect(result.code).toBeFalsy(); - const logs = parseLogs(result.logs); - const codeIdAttr = findAttribute(logs, "message", "code_id"); - const codeId = Number.parseInt(codeIdAttr.value, 10); - - // ensure we were added to the end of the list - const newInfos = await client.listCodeInfo(); - expect(newInfos.length).toEqual(numExisting + 1); - const lastInfo = newInfos[newInfos.length - 1]; - expect(lastInfo.id).toEqual(codeId); - expect(lastInfo.creator).toEqual(faucet.address); - - // ensure metadata is present - expect(lastInfo.source).toEqual( - "https://github.com/confio/cosmwasm/raw/0.7/lib/vm/testdata/contract_0.6.wasm", - ); - expect(lastInfo.builder).toEqual("confio/cosmwasm-opt:0.6.2"); - - // check code hash matches expectation - const wasmHash = new Sha256(wasmCode).digest(); - expect(lastInfo.data_hash.toLowerCase()).toEqual(toHex(wasmHash)); - - // download code and check against auto-gen - const { data } = await client.getCode(codeId); - expect(fromBase64(data)).toEqual(wasmCode); - }); - - it("can list contracts and get info", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new RestClient(wasmd.endpoint); - const beneficiaryAddress = makeRandomAddress(); - const transferAmount: readonly Coin[] = [ - { - amount: "707707", - denom: "ucosm", - }, - ]; - - // reuse an existing contract, or upload if needed - let codeId: number; - const existingInfos = await client.listCodeInfo(); - if (existingInfos.length > 0) { - codeId = existingInfos[existingInfos.length - 1].id; - } else { - const uploadResult = await uploadContract(client, pen); - expect(uploadResult.code).toBeFalsy(); - const uploadLogs = parseLogs(uploadResult.logs); - const codeIdAttr = findAttribute(uploadLogs, "message", "code_id"); - codeId = Number.parseInt(codeIdAttr.value, 10); - } - - // create new instance and compare before and after - const existingContractsByCode = await client.listContractsByCodeId(codeId); - for (const contract of existingContractsByCode) { - expect(contract.address).toMatch(bech32AddressMatcher); - expect(contract.code_id).toEqual(codeId); - expect(contract.creator).toMatch(bech32AddressMatcher); - expect(contract.label).toMatch(/^.+$/); - } - - const result = await instantiateContract(client, pen, codeId, beneficiaryAddress, transferAmount); - expect(result.code).toBeFalsy(); - const logs = parseLogs(result.logs); - const contractAddressAttr = findAttribute(logs, "message", "contract_address"); - const myAddress = contractAddressAttr.value; - - const newContractsByCode = await client.listContractsByCodeId(codeId); - expect(newContractsByCode.length).toEqual(existingContractsByCode.length + 1); - const newContract = newContractsByCode[newContractsByCode.length - 1]; - expect(newContract).toEqual( - jasmine.objectContaining({ - code_id: codeId, - creator: faucet.address, - label: "my escrow", - }), - ); - - // check out info - const myInfo = await client.getContractInfo(myAddress); - assert(myInfo); - expect(myInfo.code_id).toEqual(codeId); - expect(myInfo.creator).toEqual(faucet.address); - expect((myInfo.init_msg as any).beneficiary).toEqual(beneficiaryAddress); - - // make sure random addresses don't give useful info - const nonExistentAddress = makeRandomAddress(); - expect(await client.getContractInfo(nonExistentAddress)).toBeNull(); - }); - - describe("contract state", () => { - const client = new RestClient(wasmd.endpoint); - const noContract = makeRandomAddress(); - const expectedKey = toAscii("config"); - let contractAddress: string | undefined; - - beforeAll(async () => { - if (wasmdEnabled()) { - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const uploadResult = await uploadContract(client, pen); - assert(!uploadResult.code); - const uploadLogs = parseLogs(uploadResult.logs); - const codeId = Number.parseInt(findAttribute(uploadLogs, "message", "code_id").value, 10); - const instantiateResult = await instantiateContract(client, pen, codeId, makeRandomAddress()); - assert(!instantiateResult.code); - const instantiateLogs = parseLogs(instantiateResult.logs); - const contractAddressAttr = findAttribute(instantiateLogs, "message", "contract_address"); - contractAddress = contractAddressAttr.value; - } - }); - - it("can get all state", async () => { - pendingWithoutWasmd(); - - // get contract state - const state = await client.getAllContractState(contractAddress!); - expect(state.length).toEqual(1); - const data = state[0]; - expect(data.key).toEqual(expectedKey); - const value = JSON.parse(fromAscii(data.val)); - expect(value.verifier).toBeDefined(); - expect(value.beneficiary).toBeDefined(); - - // bad address is empty array - const noContractState = await client.getAllContractState(noContract); - expect(noContractState).toEqual([]); - }); - - it("can query by key", async () => { - pendingWithoutWasmd(); - - // query by one key - const raw = await client.queryContractRaw(contractAddress!, expectedKey); - assert(raw, "must get result"); - const model = JSON.parse(fromAscii(raw)); - expect(model.verifier).toBeDefined(); - expect(model.beneficiary).toBeDefined(); - - // missing key is null - const missing = await client.queryContractRaw(contractAddress!, fromHex("cafe0dad")); - expect(missing).toBeNull(); - - // bad address is null - const noContractModel = await client.queryContractRaw(noContract, expectedKey); - expect(noContractModel).toBeNull(); - }); - - it("can make smart queries", async () => { - pendingWithoutWasmd(); - - // we can query the verifier properly - const resultDocument = await client.queryContractSmart(contractAddress!, { verifier: {} }); - expect(resultDocument).toEqual({ verifier: faucet.address }); - - // invalid query syntax throws an error - await client.queryContractSmart(contractAddress!, { nosuchkey: {} }).then( - () => fail("shouldn't succeed"), - (error) => - expect(error).toMatch(/query wasm contract failed: parsing hackatom::contract::QueryMsg/), - ); - - // invalid address throws an error - await client.queryContractSmart(noContract, { verifier: {} }).then( - () => fail("shouldn't succeed"), - (error) => expect(error).toMatch("not found"), - ); - }); - }); - }); -}); diff --git a/packages/sdk/src/restclient.ts b/packages/sdk/src/restclient.ts deleted file mode 100644 index cb6316e9..00000000 --- a/packages/sdk/src/restclient.ts +++ /dev/null @@ -1,457 +0,0 @@ -import { Encoding, isNonNullObject } from "@iov/encoding"; -import axios, { AxiosError, AxiosInstance } from "axios"; - -import { Coin } from "./coins"; -import { CosmosSdkTx, JsonObject, Model, parseWasmData, StdTx, WasmData } from "./types"; - -const { fromBase64, fromUtf8, toHex, toUtf8 } = Encoding; - -export interface CosmosSdkAccount { - /** Bech32 account address */ - readonly address: string; - readonly coins: ReadonlyArray; - /** Bech32 encoded pubkey */ - readonly public_key: string; - readonly account_number: number; - readonly sequence: number; -} - -export interface NodeInfo { - readonly protocol_version: { - readonly p2p: string; - readonly block: string; - readonly app: string; - }; - readonly id: string; - readonly listen_addr: string; - readonly network: string; - readonly version: string; - readonly channels: string; - readonly moniker: string; - readonly other: { - readonly tx_index: string; - readonly rpc_address: string; - }; -} - -export interface ApplicationVersion { - readonly name: string; - readonly server_name: string; - readonly client_name: string; - readonly version: string; - readonly commit: string; - readonly build_tags: string; - readonly go: string; -} - -export interface NodeInfoResponse { - readonly node_info: NodeInfo; - readonly application_version: ApplicationVersion; -} - -export interface BlockId { - readonly hash: string; - // TODO: here we also have this - // parts: { - // total: '1', - // hash: '7AF200C78FBF9236944E1AB270F4045CD60972B7C265E3A9DA42973397572931' - // } -} - -export interface BlockHeader { - readonly version: { - readonly block: string; - readonly app: string; - }; - readonly height: string; - readonly chain_id: string; - /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ - readonly time: string; - readonly last_commit_hash: string; - readonly last_block_id: BlockId; - /** Can be empty */ - readonly data_hash: string; - readonly validators_hash: string; - readonly next_validators_hash: string; - readonly consensus_hash: string; - readonly app_hash: string; - /** Can be empty */ - readonly last_results_hash: string; - /** Can be empty */ - readonly evidence_hash: string; - readonly proposer_address: string; -} - -export interface Block { - readonly header: BlockHeader; - readonly data: { - /** Array of base64 encoded transactions */ - readonly txs: ReadonlyArray | null; - }; -} - -export interface BlockResponse { - readonly block_id: BlockId; - readonly block: Block; -} - -interface AuthAccountsResponse { - readonly height: string; - readonly result: { - readonly type: "cosmos-sdk/Account"; - readonly value: CosmosSdkAccount; - }; -} - -// Currently all wasm query responses return json-encoded strings... -// later deprecate this and use the specific types for result -// (assuming it is inlined, no second parse needed) -type WasmResponse = WasmSuccess | WasmError; - -interface WasmSuccess { - readonly height: string; - readonly result: T; -} - -interface WasmError { - readonly error: string; -} - -export interface TxsResponse { - readonly height: string; - readonly txhash: string; - /** 🤷‍♂️ */ - readonly codespace?: string; - /** Falsy when transaction execution succeeded. Contains error code on error. */ - readonly code?: number; - readonly raw_log: string; - readonly logs?: object; - readonly tx: CosmosSdkTx; - /** The gas limit as set by the user */ - readonly gas_wanted?: string; - /** The gas used by the execution */ - readonly gas_used?: string; - readonly timestamp: string; -} - -interface SearchTxsResponse { - readonly total_count: string; - readonly count: string; - readonly page_number: string; - readonly page_total: string; - readonly limit: string; - readonly txs: readonly TxsResponse[]; -} - -export interface PostTxsResponse { - readonly height: string; - readonly txhash: string; - readonly code?: number; - readonly raw_log?: string; - /** The same as `raw_log` but deserialized? */ - readonly logs?: object; - /** The gas limit as set by the user */ - readonly gas_wanted?: string; - /** The gas used by the execution */ - readonly gas_used?: string; -} - -interface EncodeTxResponse { - // base64-encoded amino-binary encoded representation - readonly tx: string; -} - -export interface CodeInfo { - readonly id: number; - /** Bech32 account address */ - readonly creator: string; - /** Hex-encoded sha256 hash of the code stored here */ - readonly data_hash: string; - // TODO: these are not supported in current wasmd - readonly source?: string; - readonly builder?: string; -} - -export interface CodeDetails extends CodeInfo { - /** Base64 encoded raw wasm data */ - readonly data: string; -} - -// This is list view, without contract info -export interface ContractInfo { - readonly address: string; - readonly code_id: number; - /** Bech32 account address */ - readonly creator: string; - readonly label: string; -} - -export interface ContractDetails extends ContractInfo { - /** Argument passed on initialization of the contract */ - readonly init_msg: object; -} - -interface SmartQueryResponse { - // base64 encoded response - readonly smart: string; -} - -type RestClientResponse = - | NodeInfoResponse - | BlockResponse - | AuthAccountsResponse - | TxsResponse - | SearchTxsResponse - | PostTxsResponse - | EncodeTxResponse - | WasmResponse - | WasmResponse - | WasmResponse - | WasmResponse - | WasmResponse; - -/** Unfortunately, Cosmos SDK encodes empty arrays as null */ -type CosmosSdkArray = ReadonlyArray | null; - -function normalizeArray(backend: CosmosSdkArray): ReadonlyArray { - return backend || []; -} - -/** - * The mode used to send transaction - * - * @see https://cosmos.network/rpc/#/Transactions/post_txs - */ -export enum BroadcastMode { - /** Return after tx commit */ - Block = "block", - /** Return afer CheckTx */ - Sync = "sync", - /** Return right away */ - Async = "async", -} - -function isWasmError(resp: WasmResponse): resp is WasmError { - return (resp as WasmError).error !== undefined; -} - -function unwrapWasmResponse(response: WasmResponse): T { - if (isWasmError(response)) { - throw new Error(response.error); - } - return response.result; -} - -// We want to get message data from 500 errors -// https://stackoverflow.com/questions/56577124/how-to-handle-500-error-message-with-axios -// this should be chained to catch one error and throw a more informative one -function parseAxiosError(err: AxiosError): never { - // use the error message sent from server, not default 500 msg - if (err.response?.data) { - let errorText: string; - const data = err.response.data; - // expect { error: string }, but otherwise dump - if (data.error && typeof data.error === "string") { - errorText = data.error; - } else if (typeof data === "string") { - errorText = data; - } else { - errorText = JSON.stringify(data); - } - throw new Error(`${errorText} (HTTP ${err.response.status})`); - } else { - throw err; - } -} - -export class RestClient { - private readonly client: AxiosInstance; - private readonly broadcastMode: BroadcastMode; - - /** - * Creates a new client to interact with a Cosmos SDK light client daemon. - * This class tries to be a direct mapping onto the API. Some basic decoding and normalizatin is done - * but things like caching are done at a higher level. - * - * When building apps, you should not need to use this class directly. If you do, this indicates a missing feature - * in higher level components. Feel free to raise an issue in this case. - * - * @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API) - * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns - */ - public constructor(apiUrl: string, broadcastMode = BroadcastMode.Block) { - const headers = { - post: { "Content-Type": "application/json" }, - }; - this.client = axios.create({ - baseURL: apiUrl, - headers: headers, - }); - this.broadcastMode = broadcastMode; - } - - public async get(path: string): Promise { - const { data } = await this.client.get(path).catch(parseAxiosError); - if (data === null) { - throw new Error("Received null response from server"); - } - return data; - } - - public async post(path: string, params: any): Promise { - if (!isNonNullObject(params)) throw new Error("Got unexpected type of params. Expected object."); - const { data } = await this.client.post(path, params).catch(parseAxiosError); - if (data === null) { - throw new Error("Received null response from server"); - } - return data; - } - - // The /auth endpoints - - public async authAccounts(address: string): Promise { - const path = `/auth/accounts/${address}`; - const responseData = await this.get(path); - if ((responseData as any).result.type !== "cosmos-sdk/Account") { - throw new Error("Unexpected response data format"); - } - return responseData as AuthAccountsResponse; - } - - // The /blocks endpoints - - public async blocksLatest(): Promise { - const responseData = await this.get("/blocks/latest"); - if (!(responseData as any).block) { - throw new Error("Unexpected response data format"); - } - return responseData as BlockResponse; - } - - public async blocks(height: number): Promise { - const responseData = await this.get(`/blocks/${height}`); - if (!(responseData as any).block) { - throw new Error("Unexpected response data format"); - } - return responseData as BlockResponse; - } - - // The /node_info endpoint - - public async nodeInfo(): Promise { - const responseData = await this.get("/node_info"); - if (!(responseData as any).node_info) { - throw new Error("Unexpected response data format"); - } - return responseData as NodeInfoResponse; - } - - // The /txs endpoints - - public async txById(id: string): Promise { - const responseData = await this.get(`/txs/${id}`); - if (!(responseData as any).tx) { - throw new Error("Unexpected response data format"); - } - return responseData as TxsResponse; - } - - public async txsQuery(query: string): Promise { - const responseData = await this.get(`/txs?${query}`); - if (!(responseData as any).txs) { - throw new Error("Unexpected response data format"); - } - return responseData as SearchTxsResponse; - } - - /** returns the amino-encoding of the transaction performed by the server */ - public async encodeTx(tx: CosmosSdkTx): Promise { - const responseData = await this.post("/txs/encode", tx); - if (!(responseData as any).tx) { - throw new Error("Unexpected response data format"); - } - return Encoding.fromBase64((responseData as EncodeTxResponse).tx); - } - - /** - * Broadcasts a signed transaction to into the transaction pool. - * Depending on the RestClient's broadcast mode, this might or might - * wait for checkTx or deliverTx to be executed before returning. - * - * @param tx a signed transaction as StdTx (i.e. not wrapped in type/value container) - */ - public async postTx(tx: StdTx): Promise { - const params = { - tx: tx, - mode: this.broadcastMode, - }; - const responseData = await this.post("/txs", params); - if (!(responseData as any).txhash) { - throw new Error("Unexpected response data format"); - } - return responseData as PostTxsResponse; - } - - // The /wasm endpoints - - // wasm rest queries are listed here: https://github.com/cosmwasm/wasmd/blob/master/x/wasm/client/rest/query.go#L19-L27 - public async listCodeInfo(): Promise { - const path = `/wasm/code`; - const responseData = (await this.get(path)) as WasmResponse>; - return normalizeArray(unwrapWasmResponse(responseData)); - } - - // this will download the original wasm bytecode by code id - // throws error if no code with this id - public async getCode(id: number): Promise { - const path = `/wasm/code/${id}`; - const responseData = (await this.get(path)) as WasmResponse; - return unwrapWasmResponse(responseData); - } - - public async listContractsByCodeId(id: number): Promise { - const path = `/wasm/code/${id}/contracts`; - const responseData = (await this.get(path)) as WasmResponse>; - return normalizeArray(unwrapWasmResponse(responseData)); - } - - /** - * Returns null when contract was not found at this address. - */ - public async getContractInfo(address: string): Promise { - const path = `/wasm/contract/${address}`; - const response = (await this.get(path)) as WasmResponse; - return unwrapWasmResponse(response); - } - - // Returns all contract state. - // This is an empty array if no such contract, or contract has no data. - public async getAllContractState(address: string): Promise { - const path = `/wasm/contract/${address}/state`; - const responseData = (await this.get(path)) as WasmResponse>; - return normalizeArray(unwrapWasmResponse(responseData)).map(parseWasmData); - } - - // Returns the data at the key if present (unknown decoded json), - // or null if no data at this (contract address, key) pair - public async queryContractRaw(address: string, key: Uint8Array): Promise { - const hexKey = toHex(key); - const path = `/wasm/contract/${address}/raw/${hexKey}?encoding=hex`; - const responseData = (await this.get(path)) as WasmResponse; - const data = unwrapWasmResponse(responseData); - return data.length === 0 ? null : fromBase64(data[0].val); - } - - /** - * Makes a smart query on the contract and parses the reponse as JSON. - * Throws error if no such contract exists, the query format is invalid or the response is invalid. - */ - public async queryContractSmart(address: string, query: object): Promise { - const encoded = toHex(toUtf8(JSON.stringify(query))); - const path = `/wasm/contract/${address}/smart/${encoded}?encoding=hex`; - const responseData = (await this.get(path)) as WasmResponse; - const result = unwrapWasmResponse(responseData); - // By convention, smart queries must return a valid JSON document (see https://github.com/CosmWasm/cosmwasm/issues/144) - return JSON.parse(fromUtf8(fromBase64(result.smart))); - } -} diff --git a/packages/sdk/src/sequence.spec.ts b/packages/sdk/src/sequence.spec.ts deleted file mode 100644 index e5d8f4cd..00000000 --- a/packages/sdk/src/sequence.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { findSequenceForSignedTx } from "./sequence"; -import response1 from "./testdata/txresponse1.json"; -import response2 from "./testdata/txresponse2.json"; -import response3 from "./testdata/txresponse3.json"; - -// Those values must match ./testdata/txresponse*.json -const chainId = "testing"; -const accountNumber = 4; - -describe("sequence", () => { - describe("findSequenceForSignedTx", () => { - it("works", async () => { - const current = 100; // what we get from GET /auth/accounts/{address} - expect(await findSequenceForSignedTx(response1.tx, chainId, accountNumber, current)).toEqual(10); - // We know response3.height > response1.height, so the sequence must be at least 10+1 - expect(await findSequenceForSignedTx(response3.tx, chainId, accountNumber, current, 11)).toEqual(19); - // We know response3.height > response2.height > response1.height, so the sequence must be at least 10+1 and smaller than 19 - expect(await findSequenceForSignedTx(response2.tx, chainId, accountNumber, 19, 11)).toEqual(13); - }); - - it("returns undefined when sequence is not in range", async () => { - expect(await findSequenceForSignedTx(response1.tx, chainId, accountNumber, 5)).toBeUndefined(); - expect(await findSequenceForSignedTx(response1.tx, chainId, accountNumber, 20, 11)).toBeUndefined(); - expect(await findSequenceForSignedTx(response1.tx, chainId, accountNumber, 20, 50)).toBeUndefined(); - - // upper bound is not included in the possible results - expect(await findSequenceForSignedTx(response1.tx, chainId, accountNumber, 10)).toBeUndefined(); - }); - }); -}); diff --git a/packages/sdk/src/sequence.ts b/packages/sdk/src/sequence.ts deleted file mode 100644 index 5cf2a738..00000000 --- a/packages/sdk/src/sequence.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Secp256k1, Secp256k1Signature, Sha256 } from "@iov/crypto"; - -import { makeSignBytes } from "./encoding"; -import { decodeSignature } from "./signature"; -import { CosmosSdkTx } from "./types"; - -/** - * Serach for sequence s with `min` <= `s` < `upperBound` to find the sequence that was used to sign the transaction - * - * @param tx The signed transaction - * @param chainId The chain ID for which this transaction was signed - * @param accountNumber The account number for which this transaction was signed - * @param upperBound The upper bound for the testing, i.e. sequence must be lower than this value - * @param min The lowest sequence that is tested - * - * @returns the sequence if a match was found and undefined otherwise - */ -export async function findSequenceForSignedTx( - tx: CosmosSdkTx, - chainId: string, - accountNumber: number, - upperBound: number, - min = 0, -): Promise { - const firstSignature = tx.value.signatures.find(() => true); - if (!firstSignature) throw new Error("Signature missing in tx"); - - const { pubkey, signature } = decodeSignature(firstSignature); - const secp256keSignature = Secp256k1Signature.fromFixedLength(signature); - - for (let s = min; s < upperBound; s++) { - // console.log(`Trying sequence ${s}`); - const signBytes = makeSignBytes( - tx.value.msg, - tx.value.fee, - chainId, - tx.value.memo || "", - accountNumber, - s, - ); - const prehashed = new Sha256(signBytes).digest(); - const valid = await Secp256k1.verifySignature(secp256keSignature, prehashed, pubkey); - if (valid) return s; - } - return undefined; -} diff --git a/packages/sdk/src/signature.spec.ts b/packages/sdk/src/signature.spec.ts deleted file mode 100644 index b0e782c1..00000000 --- a/packages/sdk/src/signature.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { decodeSignature, encodeSecp256k1Signature } from "./signature"; -import { StdSignature } from "./types"; - -const { fromBase64 } = Encoding; - -describe("signature", () => { - describe("encodeSecp256k1Signature", () => { - it("encodes a full signature", () => { - const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); - const signature = fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ); - expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: { - type: "tendermint/PubKeySecp256k1", - value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", - }, - signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - }); - }); - - it("throws when getting uncompressed public keys", () => { - const pubkey = fromBase64( - "BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=", - ); - const signature = fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ); - expect(() => encodeSecp256k1Signature(pubkey, signature)).toThrowError( - /public key must be compressed secp256k1/i, - ); - }); - - it("throws if signature contains recovery byte", () => { - const pubkey = fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"); - const signature = Uint8Array.from([ - ...fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ), - 99, - ]); - expect(() => encodeSecp256k1Signature(pubkey, signature)).toThrowError( - /signature must be 64 bytes long/i, - ); - }); - }); - - describe("decodeSignature", () => { - it("works for secp256k1", () => { - const signature: StdSignature = { - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: { - type: "tendermint/PubKeySecp256k1", - value: "AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP", - }, - signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - }; - expect(decodeSignature(signature)).toEqual({ - pubkey: fromBase64("AtQaCqFnshaZQp6rIkvAPyzThvCvXSDO+9AzbxVErqJP"), - signature: fromBase64( - "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - ), - }); - }); - }); -}); diff --git a/packages/sdk/src/signature.ts b/packages/sdk/src/signature.ts deleted file mode 100644 index d31eb119..00000000 --- a/packages/sdk/src/signature.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { encodeSecp256k1Pubkey } from "./pubkey"; -import { pubkeyType, StdSignature } from "./types"; - -/** - * Takes a binary pubkey and signature to create a signature object - * - * @param pubkey a compressed secp256k1 public key - * @param signature a 64 byte fixed length representation of secp256k1 signature components r and s - */ -export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature { - if (signature.length !== 64) { - throw new Error( - "Signature must be 64 bytes long. Cosmos SDK uses a 2x32 byte fixed length encoding for the secp256k1 signature integers r and s.", - ); - } - - return { - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: encodeSecp256k1Pubkey(pubkey), - signature: Encoding.toBase64(signature), - }; -} - -export function decodeSignature( - signature: StdSignature, -): { readonly pubkey: Uint8Array; readonly signature: Uint8Array } { - switch (signature.pub_key.type) { - // Note: please don't add cases here without writing additional unit tests - case pubkeyType.secp256k1: - return { - pubkey: Encoding.fromBase64(signature.pub_key.value), - signature: Encoding.fromBase64(signature.signature), - }; - default: - throw new Error("Unsupported pubkey type"); - } -} diff --git a/packages/sdk/src/signingcosmwasmclient.spec.ts b/packages/sdk/src/signingcosmwasmclient.spec.ts deleted file mode 100644 index 00fe65eb..00000000 --- a/packages/sdk/src/signingcosmwasmclient.spec.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { Sha256 } from "@iov/crypto"; -import { Encoding } from "@iov/encoding"; -import { assert } from "@iov/utils"; - -import { Coin } from "./coins"; -import { PrivateCosmWasmClient } from "./cosmwasmclient"; -import { Secp256k1Pen } from "./pen"; -import { RestClient } from "./restclient"; -import { SigningCosmWasmClient, UploadMeta } from "./signingcosmwasmclient"; -import { getHackatom, makeRandomAddress, pendingWithoutWasmd } from "./testutils.spec"; - -const { toHex } = Encoding; - -const httpUrl = "http://localhost:1317"; - -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", - pubkey: { - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }, - address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", -}; - -describe("SigningCosmWasmClient", () => { - describe("makeReadOnly", () => { - it("can be constructed", async () => { - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - expect(client).toBeTruthy(); - }); - }); - - describe("getHeight", () => { - it("always uses authAccount implementation", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - - const openedClient = (client as unknown) as PrivateCosmWasmClient; - const blockLatestSpy = spyOn(openedClient.restClient, "blocksLatest").and.callThrough(); - const authAccountsSpy = spyOn(openedClient.restClient, "authAccounts").and.callThrough(); - - const height = await client.getHeight(); - expect(height).toBeGreaterThan(0); - - expect(blockLatestSpy).toHaveBeenCalledTimes(0); - expect(authAccountsSpy).toHaveBeenCalledTimes(1); - }); - }); - - describe("upload", () => { - it("works", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - const wasm = getHackatom(); - const { - codeId, - originalChecksum, - originalSize, - compressedChecksum, - compressedSize, - } = await client.upload(wasm); - expect(originalChecksum).toEqual(toHex(new Sha256(wasm).digest())); - expect(originalSize).toEqual(wasm.length); - expect(compressedChecksum).toMatch(/^[0-9a-f]{64}$/); - expect(compressedSize).toBeLessThan(wasm.length * 0.5); - expect(codeId).toBeGreaterThanOrEqual(1); - }); - - it("can set builder and source", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - const wasm = getHackatom(); - - const meta: UploadMeta = { - source: "https://crates.io/api/v1/crates/cw-nameservice/0.1.0/download", - builder: "confio/cosmwasm-opt:0.6.2", - }; - const { codeId } = await client.upload(wasm, meta); - - const codeDetails = await client.getCodeDetails(codeId); - expect(codeDetails.source).toEqual(meta.source); - expect(codeDetails.builder).toEqual(meta.builder); - }); - }); - - describe("instantiate", () => { - it("works with transfer amount", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - const { codeId } = await client.upload(getHackatom()); - - const transferAmount: readonly Coin[] = [ - { - amount: "1234", - denom: "ucosm", - }, - { - amount: "321", - denom: "ustake", - }, - ]; - const beneficiaryAddress = makeRandomAddress(); - const { contractAddress } = await client.instantiate( - codeId, - { - verifier: faucet.address, - beneficiary: beneficiaryAddress, - }, - "My cool label", - "Let's see if the memo is used", - transferAmount, - ); - - const rest = new RestClient(httpUrl); - const balance = (await rest.authAccounts(contractAddress)).result.value.coins; - expect(balance).toEqual(transferAmount); - }); - - it("can instantiate one code multiple times", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - const { codeId } = await client.upload(getHackatom()); - - const contractAddress1 = await client.instantiate( - codeId, - { - verifier: faucet.address, - beneficiary: makeRandomAddress(), - }, - "contract 1", - ); - const contractAddress2 = await client.instantiate( - codeId, - { - verifier: faucet.address, - beneficiary: makeRandomAddress(), - }, - "contract 2", - ); - expect(contractAddress1).not.toEqual(contractAddress2); - }); - }); - - describe("execute", () => { - it("works", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - const { codeId } = await client.upload(getHackatom()); - - // instantiate - const transferAmount: readonly Coin[] = [ - { - amount: "233444", - denom: "ucosm", - }, - { - amount: "5454", - denom: "ustake", - }, - ]; - const beneficiaryAddress = makeRandomAddress(); - const { contractAddress } = await client.instantiate( - codeId, - { - verifier: faucet.address, - beneficiary: beneficiaryAddress, - }, - "amazing random contract", - undefined, - transferAmount, - ); - - // execute - const result = await client.execute(contractAddress, { release: {} }, undefined); - const wasmEvent = result.logs.find(() => true)?.events.find((e) => e.type === "wasm"); - assert(wasmEvent, "Event of type wasm expected"); - expect(wasmEvent.attributes).toContain({ key: "action", value: "release" }); - expect(wasmEvent.attributes).toContain({ - key: "destination", - value: beneficiaryAddress, - }); - - // Verify token transfer from contract to beneficiary - const rest = new RestClient(httpUrl); - const beneficiaryBalance = (await rest.authAccounts(beneficiaryAddress)).result.value.coins; - expect(beneficiaryBalance).toEqual(transferAmount); - const contractBalance = (await rest.authAccounts(contractAddress)).result.value.coins; - expect(contractBalance).toEqual([]); - }); - }); - - describe("sendTokens", () => { - it("works", async () => { - pendingWithoutWasmd(); - const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, faucet.address, (signBytes) => pen.sign(signBytes)); - - // instantiate - const transferAmount: readonly Coin[] = [ - { - amount: "7890", - denom: "ucosm", - }, - ]; - const beneficiaryAddress = makeRandomAddress(); - - // no tokens here - const before = await client.getAccount(beneficiaryAddress); - expect(before).toBeUndefined(); - - // send - const result = await client.sendTokens(beneficiaryAddress, transferAmount, "for dinner"); - const [firstLog] = result.logs; - expect(firstLog).toBeTruthy(); - - // got tokens - const after = await client.getAccount(beneficiaryAddress); - assert(after); - expect(after.balance).toEqual(transferAmount); - }); - }); -}); diff --git a/packages/sdk/src/signingcosmwasmclient.ts b/packages/sdk/src/signingcosmwasmclient.ts deleted file mode 100644 index e0daf56c..00000000 --- a/packages/sdk/src/signingcosmwasmclient.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { Sha256 } from "@iov/crypto"; -import { Encoding } from "@iov/encoding"; -import pako from "pako"; - -import { isValidBuilder } from "./builder"; -import { Coin, coins } from "./coins"; -import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient"; -import { makeSignBytes } from "./encoding"; -import { findAttribute, Log } from "./logs"; -import { BroadcastMode } from "./restclient"; -import { - MsgExecuteContract, - MsgInstantiateContract, - MsgSend, - MsgStoreCode, - StdFee, - StdSignature, -} from "./types"; - -export interface SigningCallback { - (signBytes: Uint8Array): Promise; -} - -export interface FeeTable { - readonly upload: StdFee; - readonly init: StdFee; - readonly exec: StdFee; - readonly send: StdFee; -} - -function prepareBuilder(buider: string | undefined): string { - if (buider === undefined) { - return ""; // normalization needed by backend - } else { - if (!isValidBuilder(buider)) throw new Error("The builder (Docker Hub image with tag) is not valid"); - return buider; - } -} - -const defaultFees: FeeTable = { - upload: { - amount: coins(25000, "ucosm"), - gas: "1000000", // one million - }, - init: { - amount: coins(12500, "ucosm"), - gas: "500000", // 500k - }, - exec: { - amount: coins(5000, "ucosm"), - gas: "200000", // 200k - }, - send: { - amount: coins(2000, "ucosm"), - gas: "80000", // 80k - }, -}; - -export interface UploadMeta { - /** The source URL */ - readonly source?: string; - /** The builder tag */ - readonly builder?: string; -} - -export interface UploadResult { - /** Size of the original wasm code in bytes */ - readonly originalSize: number; - /** A hex encoded sha256 checksum of the original wasm code (that is stored on chain) */ - readonly originalChecksum: string; - /** Size of the compressed wasm code in bytes */ - readonly compressedSize: number; - /** A hex encoded sha256 checksum of the compressed wasm code (that stored in the transaction) */ - readonly compressedChecksum: string; - /** The ID of the code asigned by the chain */ - readonly codeId: number; - readonly logs: readonly Log[]; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} - -export interface InstantiateResult { - /** The address of the newly instantiated contract */ - readonly contractAddress: string; - readonly logs: readonly Log[]; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} - -export interface ExecuteResult { - readonly logs: readonly Log[]; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} - -export class SigningCosmWasmClient extends CosmWasmClient { - public readonly senderAddress: string; - - private readonly signCallback: SigningCallback; - private readonly fees: FeeTable; - - /** - * Creates a new client with signing capability to interact with a CosmWasm blockchain. This is the bigger brother of CosmWasmClient. - * - * This instance does a lot of caching. In order to benefit from that you should try to use one instance - * for the lifetime of your application. When switching backends, a new instance must be created. - * - * @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API) - * @param senderAddress The address that will sign and send transactions using this instance - * @param signCallback An asynchonous callback to create a signature for a given transaction. This can be implemented using secure key stores that require user interaction. - * @param customFees The fees that are paid for transactions - * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns - */ - public constructor( - apiUrl: string, - senderAddress: string, - signCallback: SigningCallback, - customFees?: Partial, - broadcastMode = BroadcastMode.Block, - ) { - super(apiUrl, broadcastMode); - this.anyValidAddress = senderAddress; - - this.senderAddress = senderAddress; - this.signCallback = signCallback; - this.fees = { ...defaultFees, ...(customFees || {}) }; - } - - public async getNonce(address?: string): Promise { - return super.getNonce(address || this.senderAddress); - } - - public async getAccount(address?: string): Promise { - return super.getAccount(address || this.senderAddress); - } - - /** Uploads code and returns a receipt, including the code ID */ - public async upload(wasmCode: Uint8Array, meta: UploadMeta = {}, memo = ""): Promise { - const source = meta.source || ""; - const builder = prepareBuilder(meta.builder); - - const compressed = pako.gzip(wasmCode, { level: 9 }); - const storeCodeMsg: MsgStoreCode = { - type: "wasm/store-code", - value: { - sender: this.senderAddress, - // eslint-disable-next-line @typescript-eslint/camelcase - wasm_byte_code: Encoding.toBase64(compressed), - source: source, - builder: builder, - }, - }; - const fee = this.fees.upload; - const { accountNumber, sequence } = await this.getNonce(); - const chainId = await this.getChainId(); - const signBytes = makeSignBytes([storeCodeMsg], fee, chainId, memo, accountNumber, sequence); - const signature = await this.signCallback(signBytes); - const signedTx = { - msg: [storeCodeMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; - - const result = await this.postTx(signedTx); - const codeIdAttr = findAttribute(result.logs, "message", "code_id"); - return { - originalSize: wasmCode.length, - originalChecksum: Encoding.toHex(new Sha256(wasmCode).digest()), - compressedSize: compressed.length, - compressedChecksum: Encoding.toHex(new Sha256(compressed).digest()), - codeId: Number.parseInt(codeIdAttr.value, 10), - logs: result.logs, - transactionHash: result.transactionHash, - }; - } - - public async instantiate( - codeId: number, - initMsg: object, - label: string, - memo = "", - transferAmount?: readonly Coin[], - ): Promise { - const instantiateMsg: MsgInstantiateContract = { - type: "wasm/instantiate", - value: { - sender: this.senderAddress, - // eslint-disable-next-line @typescript-eslint/camelcase - code_id: codeId.toString(), - label: label, - // eslint-disable-next-line @typescript-eslint/camelcase - init_msg: initMsg, - // eslint-disable-next-line @typescript-eslint/camelcase - init_funds: transferAmount || [], - }, - }; - const fee = this.fees.init; - const { accountNumber, sequence } = await this.getNonce(); - const chainId = await this.getChainId(); - const signBytes = makeSignBytes([instantiateMsg], fee, chainId, memo, accountNumber, sequence); - - const signature = await this.signCallback(signBytes); - const signedTx = { - msg: [instantiateMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; - - const result = await this.postTx(signedTx); - const contractAddressAttr = findAttribute(result.logs, "message", "contract_address"); - return { - contractAddress: contractAddressAttr.value, - logs: result.logs, - transactionHash: result.transactionHash, - }; - } - - public async execute( - contractAddress: string, - handleMsg: object, - memo = "", - transferAmount?: readonly Coin[], - ): Promise { - const executeMsg: MsgExecuteContract = { - type: "wasm/execute", - value: { - sender: this.senderAddress, - contract: contractAddress, - msg: handleMsg, - // eslint-disable-next-line @typescript-eslint/camelcase - sent_funds: transferAmount || [], - }, - }; - const fee = this.fees.exec; - const { accountNumber, sequence } = await this.getNonce(); - const chainId = await this.getChainId(); - const signBytes = makeSignBytes([executeMsg], fee, chainId, memo, accountNumber, sequence); - const signature = await this.signCallback(signBytes); - const signedTx = { - msg: [executeMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; - - const result = await this.postTx(signedTx); - return { - logs: result.logs, - transactionHash: result.transactionHash, - }; - } - - public async sendTokens( - recipientAddress: string, - transferAmount: readonly Coin[], - memo = "", - ): Promise { - const sendMsg: MsgSend = { - type: "cosmos-sdk/MsgSend", - value: { - // eslint-disable-next-line @typescript-eslint/camelcase - from_address: this.senderAddress, - // eslint-disable-next-line @typescript-eslint/camelcase - to_address: recipientAddress, - amount: transferAmount, - }, - }; - const fee = this.fees.send; - const { accountNumber, sequence } = await this.getNonce(); - const chainId = await this.getChainId(); - const signBytes = makeSignBytes([sendMsg], fee, chainId, memo, accountNumber, sequence); - const signature = await this.signCallback(signBytes); - const signedTx = { - msg: [sendMsg], - fee: fee, - memo: memo, - signatures: [signature], - }; - - return this.postTx(signedTx); - } -} diff --git a/packages/sdk/src/testdata/contract.json b/packages/sdk/src/testdata/contract.json deleted file mode 100644 index 1b75f593..00000000 --- a/packages/sdk/src/testdata/contract.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "// source": "https://github.com/CosmWasm/cosmwasm/blob/v0.8.0-alpha3/packages/vm/testdata/contract_0.8.wasm", - "data": "AGFzbQEAAAABiwEVYAJ/fwF/YAJ/fwBgA39/fwF/YAN/f38AYAF/AGABfwF/YAR/f39/AGAAAGAFf39/f38AYAR/f39/AX9gAX8BfmADf35+AGAEf35+fwBgAAF/YAN/f34AYAR/fn5+AGAFf39/f38Bf2AGf39/f39/AX9gB39/f39/f38Bf2ADfn9/AX9gA35+fwF/AmIFA2VudgdkYl9yZWFkAAADZW52CGRiX3dyaXRlAAADZW52FGNhbm9uaWNhbGl6ZV9hZGRyZXNzAAADZW52EGh1bWFuaXplX2FkZHJlc3MAAANlbnYLcXVlcnlfY2hhaW4AAAOSApACCAYDAwYIAwADAwEDAQEBBgMGAAcAAQEECgcAAAAEBAQAAAIEAQgBAQEBAQEDAQEDAwMIAwMHBwEAAAUACQcAAAAAAAAEBAADAQMIAQEBAQEBAQEBAwEACAABBQQHBAgBAQMBBQEAAAcAAQEAAQMEAQEBAQEBAQEDAwAEDgYBAwEGEAYBAAUBAAENAAcAAQEACgoAAAADBAQEBAUAAQACBA0HAQEFAQQEBQQEAAEJBQQGAQEBAQAFBAEAAQQAAAAAAQABBwEBAAMDAQECBgEAAAIAAAAAAAgIAQAGBgUFAAMDAAMAAgUDBQMFAAACAAATABEJAAUFBgYBAgIAEgMAAAAAFAAAAAAAAAICDAwPCwsEBQFwAXR0BQMBABEGGQN/AUGAgMAAC38AQaiGwQALfwBBqIbBAAsHbQkGbWVtb3J5AgAKX19kYXRhX2VuZAMBC19faGVhcF9iYXNlAwIEaW5pdAA9BmhhbmRsZQA+BXF1ZXJ5AD8IYWxsb2NhdGUAXwpkZWFsbG9jYXRlAGAVY29zbXdhc21fdm1fdmVyc2lvbl8xAGEJsgEBAEEBC3MMIdQBGRdqWyCUAR8iMzIiJyUmIokCHGsdRyEgSEaIAoYCGSJYVyInJUsiSssBRUQdQyFtIm9uHSHTAeYBIosBjQGMASGRASKTAZIBHfUBlwGxASKjAaABogGZASKVAdkBnQG6AdgBnAGwAZ4BtgG3AZsBlgEiuAG5AR2YASKjAcQBxgGZASLDAcIB2gHWAegB0wHeASKVASLpAe8B8AEiiwLxAfIB8wGKAowCCpHdCJACugYBBX8jAEEQayIJJAACQAJAAkACQAJAAkAgAS0ABEUEQAJAIAEoAgAiBigCCCIFIAZBBGooAgBHBEAgBigCACEHDAELIAVBAWoiByAFSQ0GIAVBAXQiCCAHIAggB0sbIghBAEgNBgJ/IAVFBEAgCEEBEEAMAQsgBigCACAFQQEgCBBBCyIHRQ0CIAYgBzYCACAGQQRqIAg2AgAgBigCCCEFCyAFIAdqQSw6AAAgBiAGKAIIQQFqNgIICyABQQA6AAQCQCABKAIAIgYoAggiBSAGQQRqKAIARwRAIAYoAgAhBwwBCyAFQQFqIgcgBUkNBSAFQQF0IgggByAIIAdLGyIIQQBIDQUCfyAFRQRAIAhBARBADAELIAYoAgAgBUEBIAgQQQsiB0UNAiAGIAc2AgAgBkEEaiAINgIAIAYoAgghBQsgBSAHakEiOgAAIAYgBigCCEEBajYCCAJAIAEoAgAiBkEEaigCACIHIAZBCGooAgAiBWsgA08EQCAGKAIAIQcMAQsgAyAFaiIIIAVJDQUgB0EBdCIFIAggBSAISxsiBUEASA0FAn8gB0UEQCAFQQEQQAwBCyAGKAIAIAdBASAFEEELIgdFDQMgBiAHNgIAIAZBBGogBTYCACAGQQhqKAIAIQULIAZBCGogAyAFajYCACAFIAdqIAIgAxCOAhoCQCABKAIAIgJBBGooAgAiAyACQQhqKAIAIgVrQQJPBEAgAigCACEDDAELIAVBAmoiByAFSQ0FIANBAXQiBSAHIAUgB0sbIgVBAEgNBQJ/IANFBEAgBUEBEEAMAQsgAigCACADQQEgBRBBCyIDRQ0EIAIgAzYCACACQQRqIAU2AgAgAkEIaigCACEFCyACQQhqIAVBAmo2AgAgAyAFakGi9AA7AAAgCSABKAIAIAQoAgAgBCgCCBCBASAJKAIAIgFBA0cEQCAJQQxqKAIAIQIgCUEIaigCACEDIAAgCSgCBDYCBCAAIAE2AgAgAEEMaiACNgIAIABBCGogAzYCAAwGCyAAQQM2AgAMBQsgCEEBEMcBAAsgCEEBEMcBAAsgBUEBEMcBAAsgBUEBEMcBAAsQyAEACyAJQRBqJAAL5wYBBX8jAEEQayIIJAACQAJAAkACQAJAAkAgAS0ABEUEQAJAIAEoAgAiBigCCCIEIAZBBGooAgBHBEAgBigCACEFDAELIARBAWoiBSAESQ0GIARBAXQiByAFIAcgBUsbIgdBAEgNBgJ/IARFBEAgB0EBEEAMAQsgBigCACAEQQEgBxBBCyIFRQ0CIAYgBTYCACAGQQRqIAc2AgAgBigCCCEECyAEIAVqQSw6AAAgBiAGKAIIQQFqNgIICyABQQA6AAQCQCABKAIAIgYoAggiBCAGQQRqKAIARwRAIAYoAgAhBQwBCyAEQQFqIgUgBEkNBSAEQQF0IgcgBSAHIAVLGyIHQQBIDQUCfyAERQRAIAdBARBADAELIAYoAgAgBEEBIAcQQQsiBUUNAiAGIAU2AgAgBkEEaiAHNgIAIAYoAgghBAsgBCAFakEiOgAAIAYgBigCCEEBajYCCAJAIAEoAgAiBkEEaigCACIFIAZBCGooAgAiBGtBCU8EQCAGKAIAIQUMAQsgBEEJaiIHIARJDQUgBUEBdCIEIAcgBCAHSxsiBEEASA0FAn8gBUUEQCAEQQEQQAwBCyAGKAIAIAVBASAEEEELIgVFDQMgBiAFNgIAIAZBBGogBDYCACAGQQhqKAIAIQQLIAZBCGogBEEJajYCACAEIAVqIgRBCGogAkEIai0AADoAACAEIAIpAAA3AAACQCABKAIAIgVBBGooAgAiAiAFQQhqKAIAIgRrQQJPBEAgBSgCACECDAELIARBAmoiBiAESQ0FIAJBAXQiBCAGIAQgBksbIgRBAEgNBQJ/IAJFBEAgBEEBEEAMAQsgBSgCACACQQEgBBBBCyICRQ0EIAUgAjYCACAFQQRqIAQ2AgAgBUEIaigCACEECyAFQQhqIARBAmo2AgAgAiAEakGi9AA7AAAgASgCACEBAkAgAygCACICRQRAIAggARCCAQwBCyAIIAEgAiADQQhqKAIAEIEBCyAIKAIAIgFBA0cEQCAIQQxqKAIAIQIgCEEIaigCACEDIAAgCCgCBDYCBCAAIAE2AgAgAEEMaiACNgIAIABBCGogAzYCAAwGCyAAQQM2AgAMBQsgB0EBEMcBAAsgB0EBEMcBAAsgBEEBEMcBAAsgBEEBEMcBAAsQyAEACyAIQRBqJAALxgYBBX8jAEEQayIHJAACQAJAAkACQAJAAkAgAS0ABEUEQAJAIAEoAgAiBCgCCCIDIARBBGooAgBHBEAgBCgCACEFDAELIANBAWoiBSADSQ0GIANBAXQiBiAFIAYgBUsbIgZBAEgNBgJ/IANFBEAgBkEBEEAMAQsgBCgCACADQQEgBhBBCyIFRQ0CIAQgBTYCACAEQQRqIAY2AgAgBCgCCCEDCyADIAVqQSw6AAAgBCAEKAIIQQFqNgIICyABQQA6AAQCQCABKAIAIgQoAggiAyAEQQRqKAIARwRAIAQoAgAhBQwBCyADQQFqIgUgA0kNBSADQQF0IgYgBSAGIAVLGyIGQQBIDQUCfyADRQRAIAZBARBADAELIAQoAgAgA0EBIAYQQQsiBUUNAiAEIAU2AgAgBEEEaiAGNgIAIAQoAgghAwsgAyAFakEiOgAAIAQgBCgCCEEBajYCCAJAIAEoAgAiBEEEaigCACIFIARBCGooAgAiA2tBBk8EQCAEKAIAIQUMAQsgA0EGaiIGIANJDQUgBUEBdCIDIAYgAyAGSxsiA0EASA0FAn8gBUUEQCADQQEQQAwBCyAEKAIAIAVBASADEEELIgVFDQMgBCAFNgIAIARBBGogAzYCACAEQQhqKAIAIQMLIARBCGogA0EGajYCACADIAVqIgNBBGpBpYDAAC8AADsAACADQaGAwAAoAAA2AAACQCABKAIAIgRBBGooAgAiBSAEQQhqKAIAIgNrQQJPBEAgBCgCACEFDAELIANBAmoiBiADSQ0FIAVBAXQiAyAGIAMgBksbIgNBAEgNBQJ/IAVFBEAgA0EBEEAMAQsgBCgCACAFQQEgAxBBCyIFRQ0EIAQgBTYCACAEQQRqIAM2AgAgBEEIaigCACEDCyAEQQhqIANBAmo2AgAgAyAFakGi9AA7AAAgByACIAEoAgAQCCAHKAIAIgFBA0cEQCAHQQxqKAIAIQIgB0EIaigCACEDIAAgBygCBDYCBCAAIAE2AgAgAEEMaiACNgIAIABBCGogAzYCAAwGCyAAQQM2AgAMBQsgBkEBEMcBAAsgBkEBEMcBAAsgA0EBEMcBAAsgA0EBEMcBAAsQyAEACyAHQRBqJAAL3wkBBH8jAEHQAGsiAyQAIANBOGogAhCEAQJAIAMoAjhBAUYEQCAAIAMpAjw3AgAgAEEIaiADQcQAaikCADcCAAwBCyADIAMoAjw2AgggAyADQUBrIgItAAA6AAwgA0E4aiADQQhqQYCCwABBBSABQRBqEAUgAygCOEEDRwRAIAAgAykDODcCACAAQQhqIAIpAwA3AgAMAQsgAygCCCIFKAIIIQICQAJAAkACQAJAAkACQAJAIAMtAAxFBEACQCAFQQRqKAIAIAJHBEAgBSgCACEEDAELIAJBAWoiBCACSQ0GIAJBAXQiBiAEIAYgBEsbIgZBAEgNBgJ/IAJFBEAgBkEBEEAMAQsgBSgCACACQQEgBhBBCyIERQ0CIAUgBDYCACAFQQRqIAY2AgAgBSgCCCECCyACIARqQSw6AAAgBSAFKAIIQQFqIgI2AggLIANBADoADAJAIAVBBGooAgAgAkcEQCAFKAIAIQQMAQsgAkEBaiIEIAJJDQUgAkEBdCIGIAQgBiAESxsiBkEASA0FAn8gAkUEQCAGQQEQQAwBCyAFKAIAIAJBASAGEEELIgRFDQIgBSAENgIAIAVBBGogBjYCACAFQQhqKAIAIQILIAIgBGpBIjoAACAFQQhqIgIgAigCAEEBaiICNgIAAkAgBUEEaigCACIEIAJrQQZPBEAgBSgCACEEDAELIAJBBmoiBiACSQ0FIARBAXQiAiAGIAIgBksbIgJBAEgNBQJ/IARFBEAgAkEBEEAMAQsgBSgCACAEQQEgAhBBCyIERQ0DIAUgBDYCACAFQQRqIAI2AgAgBUEIaigCACECCyAFQQhqIgYgAkEGajYCACACIARqIgJBBGpBpYDAAC8AADsAACACQaGAwAAoAAA2AAACQCAFQQRqKAIAIgQgBigCACICa0ECTwRAIAUoAgAhBAwBCyACQQJqIgYgAkkNBSAEQQF0IgIgBiACIAZLGyICQQBIDQUCfyAERQRAIAJBARBADAELIAUoAgAgBEEBIAIQQQsiBEUNBCAFIAQ2AgAgBUEEaiACNgIAIAVBCGooAgAhAgsgBUEIaiACQQJqNgIAIAIgBGpBovQAOwAAIAMgATYCFCADQQA2AiAgA0IBNwMYIANBATYCLCADIANBFGo2AiggAyADQRhqNgI0IANBzABqQQE2AgAgA0IBNwI8IANBnIXAADYCOCADIANBKGo2AkggA0E0akGcisAAIANBOGoQ1QENBQJAIAMoAhwiAiADKAIgIgFGBEAgAygCGCEEDAELIAIgAUkNByABRQRAIAIEQCADKAIYEMABCyADQgE3AxhBACECQQEhBAwBCyADKAIYIAJBASABEEEiBEUNCCADIAE2AhwgAyAENgIYIAEhAgsgA0E4aiAFIAQgAygCIBCBASACBEAgBBDAAQsgAygCOCIBQQNGBEAgACAFQQAQfAwJCyADQcQAaigCACECIANBQGsoAgAhBSAAIAMoAjw2AgQgACABNgIAIABBDGogAjYCACAAQQhqIAU2AgAMCAsgBkEBEMcBAAsgBkEBEMcBAAsgAkEBEMcBAAsgAkEBEMcBAAsQyAEAC0GkhcAAQTcgA0E4akG0isAAEN8BAAtBzIvAAEEkQbyLwAAQzQEACyABQQEQxwEACyADQdAAaiQAC+gGAQV/IwBBIGsiCCQAAkACQAJAAkACQAJAIAEtAARFBEACQCABKAIAIgYoAggiBCAGQQRqKAIARwRAIAYoAgAhBQwBCyAEQQFqIgUgBEkNBiAEQQF0IgcgBSAHIAVLGyIHQQBIDQYCfyAERQRAIAdBARBADAELIAYoAgAgBEEBIAcQQQsiBUUNAiAGIAU2AgAgBkEEaiAHNgIAIAYoAgghBAsgBCAFakEsOgAAIAYgBigCCEEBajYCCAsgAUEAOgAEAkAgASgCACIGKAIIIgQgBkEEaigCAEcEQCAGKAIAIQUMAQsgBEEBaiIFIARJDQUgBEEBdCIHIAUgByAFSxsiB0EASA0FAn8gBEUEQCAHQQEQQAwBCyAGKAIAIARBASAHEEELIgVFDQIgBiAFNgIAIAZBBGogBzYCACAGKAIIIQQLIAQgBWpBIjoAACAGIAYoAghBAWo2AggCQCABKAIAIgZBBGooAgAiBSAGQQhqKAIAIgRrQQNPBEAgBigCACEFDAELIARBA2oiByAESQ0FIAVBAXQiBCAHIAQgB0sbIgRBAEgNBQJ/IAVFBEAgBEEBEEAMAQsgBigCACAFQQEgBBBBCyIFRQ0DIAYgBTYCACAGQQRqIAQ2AgAgBkEIaigCACEECyAGQQhqIARBA2o2AgAgBCAFaiIEQQJqIAJBAmotAAA6AAAgBCACLwAAOwAAAkAgASgCACIFQQRqKAIAIgIgBUEIaigCACIEa0ECTwRAIAUoAgAhAgwBCyAEQQJqIgYgBEkNBSACQQF0IgQgBiAEIAZLGyIEQQBIDQUCfyACRQRAIARBARBADAELIAUoAgAgAkEBIAQQQQsiAkUNBCAFIAI2AgAgBUEEaiAENgIAIAVBCGooAgAhBAsgBUEIaiAEQQJqNgIAIAIgBGpBovQAOwAAIAEoAgAhASAIQRBqIAMQWiAIIAEgCCgCECIBIAgoAhgQgQEgCCgCFARAIAEQwAELIAgoAgAiAUEDRwRAIAhBCGooAgAhAiAIQQxqKAIAIQMgACAIKAIENgIEIAAgATYCACAAQQxqIAM2AgAgAEEIaiACNgIADAYLIABBAzYCAAwFCyAHQQEQxwEACyAHQQEQxwEACyAEQQEQxwEACyAEQQEQxwEACxDIAQALIAhBIGokAAuxBgEFfyMAQRBrIgkkAAJAAkACQAJAAkACQCABLQAERQRAAkAgASgCACIGKAIIIgUgBkEEaigCAEcEQCAGKAIAIQcMAQsgBUEBaiIHIAVJDQYgBUEBdCIIIAcgCCAHSxsiCEEASA0GAn8gBUUEQCAIQQEQQAwBCyAGKAIAIAVBASAIEEELIgdFDQIgBiAHNgIAIAZBBGogCDYCACAGKAIIIQULIAUgB2pBLDoAACAGIAYoAghBAWo2AggLIAFBADoABAJAIAEoAgAiBigCCCIFIAZBBGooAgBHBEAgBigCACEHDAELIAVBAWoiByAFSQ0FIAVBAXQiCCAHIAggB0sbIghBAEgNBQJ/IAVFBEAgCEEBEEAMAQsgBigCACAFQQEgCBBBCyIHRQ0CIAYgBzYCACAGQQRqIAg2AgAgBigCCCEFCyAFIAdqQSI6AAAgBiAGKAIIQQFqNgIIAkAgASgCACIGQQRqKAIAIgcgBkEIaigCACIFayADTwRAIAYoAgAhBwwBCyADIAVqIgggBUkNBSAHQQF0IgUgCCAFIAhLGyIFQQBIDQUCfyAHRQRAIAVBARBADAELIAYoAgAgB0EBIAUQQQsiB0UNAyAGIAc2AgAgBkEEaiAFNgIAIAZBCGooAgAhBQsgBkEIaiADIAVqNgIAIAUgB2ogAiADEI4CGgJAIAEoAgAiAkEEaigCACIDIAJBCGooAgAiBWtBAk8EQCACKAIAIQMMAQsgBUECaiIHIAVJDQUgA0EBdCIFIAcgBSAHSxsiBUEASA0FAn8gA0UEQCAFQQEQQAwBCyACKAIAIANBASAFEEELIgNFDQQgAiADNgIAIAJBBGogBTYCACACQQhqKAIAIQULIAJBCGogBUECajYCACADIAVqQaL0ADsAACAJIAQgASgCABALIAkoAgAiAUEDRwRAIAlBDGooAgAhAiAJQQhqKAIAIQMgACAJKAIENgIEIAAgATYCACAAQQxqIAI2AgAgAEEIaiADNgIADAYLIABBAzYCAAwFCyAIQQEQxwEACyAIQQEQxwEACyAFQQEQxwEACyAFQQEQxwEACxDIAQALIAlBEGokAAuMAwEGfyMAQSBrIgMkACABKAIAIQYgA0EIaiACIAEoAggiARCDAQJAAkACQCADKAIIQQFGBEAgACADKQIMNwIAIABBCGogA0EUaikCADcCAAwBCyABQQV0IQcgA0EQai0AACECIAMoAgwiAUEEaiEIAkADQCAHRQ0BIAJB/wFxRQRAAkAgASgCCCICIAgoAgBHBEAgASgCACEEDAELIAJBAWoiBCACSQ0GIAJBAXQiBSAEIAUgBEsbIgVBAEgNBgJ/IAJFBEAgBUEBEEAMAQsgASgCACACQQEgBRBBCyIERQ0FIAEgBDYCACAIIAU2AgAgASgCCCECCyACIARqQSw6AAAgASABKAIIQQFqNgIICyADQQhqIAYgARAIIAdBYGohB0EAIQIgBkEgaiEGIAMoAggiBEEDRg0ACyADKAIUIQEgAygCECECIAAgAygCDDYCBCAAIAQ2AgAgAEEMaiABNgIAIABBCGogAjYCAAwBCyAAIAEQewsgA0EgaiQADwsgBUEBEMcBAAsQyAEACwsAIAAoAgAgARBdC4UuAht/BH4jAEGQAmsiAyQAIANByAFqIAEgAhByIANBwAFqIANByAFqEHlBASEbAkACQCADLQDAAUEBcUUEQEEEIQIMAQsgAy0AwQFB+wBHBEBBDiECDAELIANByAFqEHMgA0G4AWogA0HIAWoQcSADLQC8ASEEIANBsAFqIAMoArgBIggQeSADLQCwAUEBcUUEQEECIQIMAQsgAy0AsQEhAiAEQQFxIQcCQAJ/AkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJ/AkACQAJAA0ACQAJAAkACQCACQf8BcSIEQSxHBEAgBEH9AEYNAiAHQf8BcQ0BQQAhB0EJIQIMFwsgB0H/AXFBACEHDRUgCBBzIANBqAFqIAgQeSADLQCoAUEBcUUNFCADLQCpASECC0EAIQcgAkH/AXEiAUEiRwRAQRMhAiABQf0ARw0VDBYLIANBoAFqIAgQeSADLQCgAUEBcUUNEyADLQChAUEiRwRAQQ4hAgwWCyAIEHMgA0HgAWogCBB4IAMoAuwBIQQgAygC6AEhBSADKALkASECIAMoAuABIgFBAUYEQCADKALwASEGDBYLIARBe2oiDkEDSw0BAkACQAJAIA5BAWsOAwQBAgALQQAhCiACQYGDwABGDQQgAkGBg8AAQQUQjwJFDQQMAwtBASEKIAJBhoPAAEYNAyACQYaDwABBBxCPAg0CDAMLQQIhCiACQY2DwABGDQIgAikAAELj3rmjp67YsfQAUg0BDAILIAlFBEAgA0HgAWpBgYPAAEEFEA4gA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAkEAIQcMFQsCQCALRQRAIANB4AFqQYaDwABBBxAOIANB7AFqKAIAIQYgA0HoAWooAgAhBCADKALkASEFIAMoAuABIQJBASEBDAELIA1FBEAgA0HgAWpBjYPAAEEIEA4gA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAiAUBEAgCxDAAQsgEQRAIBFBBXQhByAPQRBqIQEDQCABQQRqKAIABEAgASgCABDAAQsgAUEgaiEBIAdBYGoiBw0ACwtBACEBIBVFDQEgDxDAAQwBCyADQeABaiADQcgBahB2IANB7AFqIQEgA0HoAWohBSADKALgASICQRZHBEAgASgCACEGIAUoAgAhBCADKALkASEFIBYEQCAJEMABCyAUBEAgCxDAAQsgEQRAIA8gEUEFdGohCSAPIQEDQCABQRRqKAIABEAgAUEQaigCABDAAQsgAUEgaiIMIQEgCSAMRw0ACwsgFQRAIA8QwAELIBJFDRkgDRDAAQwZCyADQeABaiADQcgBahB0IAMoAuABIgJBFkcEQCABKAIAIQYgBSgCACEEIAMoAuQBIQUgFgRAIAkQwAELIBQEQCALEMABCyARBEAgDyARQQV0aiEJIA8hAQNAIAFBFGooAgAEQCABQRBqKAIAEMABCyABQSBqIgwhASAJIAxHDQALCyAVBEAgDxDAAQsgEkUNGSANEMABDBkLIABByABqIBytNwMAIABBxABqIBI2AgAgAEFAayANNgIAIABBPGogETYCACAAQThqIBU2AgAgAEE0aiAPNgIAIABBMGogHTYCACAAQSxqIBQ2AgAgAEEoaiALNgIAIABBIGogHjcDACAAQRxqIBY2AgAgAEEYaiAJNgIAIABBEGogIDcDACAAQQxqIBk2AgAgAEEIaiATNgIAQQAhGwwZCyAWBEAgGhDAAQsgAUUhB0EBDBULQQMhCgsgBQRAIAIQwAELIARFIAFFIAJBFEdyckUEQCAFEMABCwJAAkACQAJAAkAgCkECTQRAIApBAWsOAgQDAQsgA0HgAWogCBB3IAMoAuABIgJBFkYNASADKALoASEEIAMoAuQBIQUgAyADKALsASIGNgKMAiADIAQ2AogCIAMgBTYChAIgAyACNgKAAgwXCyAJDQ0gA0HgAWogCBB3IAMoAuABIgJBFkcNEyADQThqIAgQeSADLQA4QQFxRQRAQQQhAgwTCyADLQA5QfsARwRAQQ4hAgwTCyAIEHMgA0EwaiAIEHEgAygCMCEGIAMgAy0ANEEBcSIOOgDcASADIAY2AtgBIANBKGogBhB5IAMtAChBAXFFBEBBAiECDBcLIAMtACkhAkEAIQlCACEeIA4hBUIAIR8DQAJAAkACQCACQf8BcSIEQSxHBEAgBEH9AEYNASAODQJBCSECDBYLIAVB/wFxDQEgBhBzIANBIGogBhB5IAMtACBBAXFFDRQgAy0AISECDAILIB5CAVIEQCADQeABakGVg8AAQQYQDgwTCyAfQgFSBEAgA0HgAWpBm4PAAEEEEA4MEwsgCUUEQCADQeABakGfg8AAQQgQDiADQewBaigCACEGIANB6AFqKAIADBILIANB4AFqIAgQdiADKALgASICQRZHBEAgAygC7AEhBiADKALoASEEIAMoAuQBIQUgDEUNGiAJEMABDBoLICFCIIinIRkgIKchBiATrSEeICGnIRMgDCEWIAkhGgwGC0EAIQ4gA0EAOgDcAQsgAkH/AXEiBEEiRwRAQRNBECAEQf0ARhshAgwTCyADQRhqIAYQeSADLQAYQQFxRQ0RIAMtABlBIkcEQEEOIQIMEwsgBhBzIANB4AFqIAYQeCADKALsASEEIAMoAugBIQUgAygC5AEhAiADKALgASIBQQFGBEAgAygC8AEhBgwTCwJAAkAgBEF8aiIZQQRLDQACQAJAAkAgGUEBaw4EAwADAgELQQAhCiACQZWDwABGDQMgAkGVg8AAQQYQjwJFDQMMAgtBASEKIAJBm4PAAEYNAiACKAAAQfTStasGRw0BDAILQQIhCiACQZ+DwABGDQEgAikAAELj0IXL5u3XtOQAUQ0BC0EDIQoLIAUEQCACEMABCyAERSABRSACQRRHcnJFBEAgBRDAAQsCQAJAAkACQAJAAkACQAJAAkAgCkECTQRAIApBAWsOAgIDAQsgA0HgAWogBhB3IAMoAuABIgJBFkYNAyADKALoASEEIAMoAuQBIQUgA0GMAmogAygC7AEiBjYCACADQYgCaiAENgIAIAMgBTYChAIgAyACNgKAAgwbCyAeQgFSBEAgA0HgAWogA0HYAWoQDyADKALgAUEBRg0GIAMpA+gBISFCASEeDAgLIANB4AFqQZWDwABBBhAQDBgLIB9CAVENAiADQeABaiADQdgBahAPIAMoAuABQQFGDQQgAykD6AEhIEIBIR8MBgsgCQ0CIANB4AFqIAYQdyADKALgASICQRZHDRogA0EQaiAGEHkgAy0AEEEBcUUEQEEEIQIMBQsgAy0AEUEiRwRAQQ4hAgwFCyAGEHMgA0HgAWogBhB4IAMoAuwBIRMgAygC6AEhDCADKALkASEJIAMoAuABIgFBAUYEQCADKALwASEGIAkhAgwFCyATRSABRSAJQRRHcnINBSAMEMABDAULIANBgAJqIAYQESADKAKAAiICQRZGDQQgA0GMAmooAgAhBiADQYgCaigCACEEIAMoAoQCIQUMFwsgA0HgAWpBm4PAAEEEEBAMFAsgA0HgAWpBn4PAAEEIEBAMEwsgA0HwAWooAgAhBiADQewBaigCACEEIAMoAugBIQUgAygC5AEhAgwUCyAMIQUgEyEEDBgLIANBCGogBhB5QQAhBSADLQAJIQIgAy0ACEEBcQ0AC0ECIQIMEQsgA0GAAmogCBARIAMoAoACIgJBFkYNAiADKAKMAiEGIAMoAogCIQQgAygChAIhBQwVCwJ/AkACQAJAAkACQCANRQRAIANB4AFqIAgQdyADKALsASEBQQAhDiADKALgASICQRZHBEAgAygC6AEhBCADKALkAQwHCyADQZgBaiAIEHkgAy0AmAFBAXFFBEBBBCECDAYLIAMtAJkBQfsARwRAQQ4hAgwGCyAIEHMgA0GQAWogCBBxIAMoApABIQcgAyADLQCUAUEBcSIBOgDcASADIAc2AtgBIANBiAFqIAcQeSADLQCIAUEBcUUEQEECIQJBACEHDB4LIAMtAIkBIQJBACENIAEhBQNAAkACQAJAIAJB/wFxIgRBLEcEQCAEQf0ARg0BIAENAkEJIQIMBwsgBUH/AXENASAHEHMgA0GAAWogBxB5IAMtAIABQQFxRQ0FIAMtAIEBIQIMAgsgDUUEQCADQeABakGagsAAQQcQDiADQewBaigCACEGIANB6AFqKAIAIQQgAygC5AEhBSADKALgASECDAgLIANB4AFqIAgQdiADKALgASICQRZGDQsgAygC7AEhBiADKALoASEEIAMoAuQBIQUgEkUEQEEAIQcMIQsgDRDAAUEAIQcMIAtBACEBIANBADoA3AELIAJB/wFxIgRBIkcEQEETQRAgBEH9AEYbIQIMBAsgA0H4AGogBxB5IAMtAHhBAXFFDQIgAy0AeUEiRwRAQQ4hAgwECyAHEHMgA0HgAWogBxB4IAMoAuwBIQQgAygC6AEhBSADKALkASECIAMoAuABIgxBAUYEQCADKALwASEGDAQLAkAgBEEHRgRAQQAhCiACQZqCwABGDQEgAkGagsAAQQcQjwJFDQELQQEhCgsgBQRAIAIQwAELIARFIAxFIAJBFEdyckUEQCAFEMABCwJAAkACQCAKBEAgA0HgAWogBxB3IAMoAuABIgJBFkYNASADKALoASEEIAMoAuQBIQUgA0GMAmogAygC7AEiBjYCACADQYgCaiAENgIAIAMgBTYChAIgAyACNgKAAgwHCyANRQRAIANB4AFqIANB2AFqEBIgAygC4AFBAUcNAiADQfABaigCACEGIAMoAuwBIQQgAygC6AEhBSADKALkASECQQAhBwwiCyADQeABakGagsAAQQcQECADQewBaigCACEGIANB6AFqKAIAIQQgAygC5AEhBSADKALgASECDAcLIANBgAJqIAcQESADKAKAAiICQRZGDQEgA0GMAmooAgAhBiADQYgCaigCACEEIAMoAoQCIQUMBQsgAygC7AEhHCADKALoASESIAMoAuQBIQ0LIANB8ABqIAcQeUEAIQUgAy0AcSECIAMtAHBBAXENAAtBAiECDAILIANB4AFqQY2DwABBCBAQIANB7AFqKAIAIQYgA0HoAWooAgAMEgtBBCECCyANRQ0BCyASRQ0AIA0QwAFBACEHDBkLQQAhBwwYCyAcIQQgEgshBSABIQYMFgsgCw0CIANB4AFqIAgQdyADKALgASICQRZHDRAgA0HoAGogCBB5IAMtAGhBAXFFBEBBBCECDAoLIAMtAGlB+wBHBEBBDiECDAoLIAgQcyADQeAAaiAIEHEgAygCYCEBIAMgAy0AZEEBcSIOOgDcASADIAE2AtgBIANB2ABqIAEQeSADLQBYQQFxRQRAQQIhAgwJCyADLQBZIQJBACELIA4hBUEAIRACQANAAkACQAJAIAJB/wFxIgRBLEcEQCAEQf0ARg0BIA4NAkEJIQIMCgsgBUH/AXENASABEHMgA0HQAGogARB5IAMtAFBBAXFFDQggAy0AUSECDAILIAtFBEAgA0HgAWpBp4PAAEEGEA4gA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAkEADAoLIBBFBEAgA0HgAWpBrYPAAEEKEA4gA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAiAXRQ0NIAsQwAEMDQsgA0HgAWogCBB2IAMoAuABIgJBFkcEQCADKALsASEGIAMoAugBIQQgAygC5AEhBSAXBEAgCxDAAQsgGARAIBhBBXQhByAQQRBqIQEDQCABQQRqKAIABEAgASgCABDAAQsgAUEgaiEBIAdBYGoiBw0ACwsgDEUNDSAQEMABDA0LIBghESAMIRUgECEPIBchFAwEC0EAIQ4gA0EAOgDcAQsgAkH/AXEiBEEiRwRAQRAhAiAEQf0ARw0HQRMhAgwHCyADQcgAaiABEHkgAy0ASEEBcUUNBSADLQBJQSJHBEBBDiECDAcLIAEQcyADQeABaiABEHggAygC7AEhBCADKALoASEFIAMoAuQBIQIgAygC4AEiB0EBRgRAIAMoAvABIQYMBwsCQAJAIARBemoiCkEESw0AAkACQCAKQQFrDgQCAgIBAAtBACEKIAJBp4PAAEYNAiACQaeDwABBBhCPAkUNAgwBC0EBIQogAkGtg8AARg0BIAJBrYPAAEEKEI8CRQ0BC0ECIQoLIAUEQCACEMABCyAERSAHRSACQRRHcnJFBEAgBRDAAQsCQAJAAkACQAJAIApBAU0EQCAKQQFrDQEMAgsgA0HgAWogARB3IAMoAuABIgJBFkYNAiADKALoASEEIAMoAuQBIQUgA0GMAmogAygC7AEiBjYCACADQYgCaiAENgIAIAMgBTYChAIgAyACNgKAAgwLCyALRQRAIANB4AFqIANB2AFqEBIgAygC4AFBAUcNAyADQfABaigCACEGIAMoAuwBIQQgAygC6AEhBSADKALkASECQQAMDAsgA0HgAWpBp4PAAEEGEBAgA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAgwKCyAQDQQgA0HgAWogA0HYAWoQEyADKALgAUEBRwRAIAMoAuwBIRggAygC6AEhDCADKALkASEQDAMLIANB8AFqKAIAIQYgAygC7AEhBCADKALoASEFIAMoAuQBIQIgCyEJDAwLIANBgAJqIAEQESADKAKAAiICQRZGDQEgA0GMAmooAgAhBiADQYgCaigCACEEIAMoAoQCIQUMCAsgAygC7AEhHSADKALoASEXIAMoAuQBIQsLIANBQGsgARB5QQAhBSADLQBBIQIgAy0AQEEBcQ0AC0ECIQIMBQsgA0HgAWpBrYPAAEEKEBAgA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAiALIQkMBgsgAyAIEHlBACEHIAMtAAEhAiADLQAAQQFxDQALQQIhAgwRCyADQeABakGGg8AAQQcQECADQewBaigCACEGIANB6AFqKAIADAgLQQQhAgsgCwshCSAQRQ0BCyAYBEAgGEEFdCEHIBBBEGohAQNAIAFBBGooAgAEQCABKAIAEMABCyABQSBqIQEgB0FgaiIHDQALCyAMRQ0AIBAQwAELIAlFIBdFcg0AIAsQwAELQQAhC0EAIQcMCgsgFyEFIB0hBCAQIQYMCQsgA0HgAWpBgYPAAEEFEBAgA0HsAWooAgAhBiADQegBaigCAAshBCADKALkASEFIAMoAuABIQIMBwsgA0HsAWooAgAhBiADQegBaigCACEEIAMoAuQBIQUgAygC4AEhAgwBC0EEIQILIAxFIAlFcg0EIAkQwAEMBAsgEyEFIBkhBAwDCyADKALsASEGIAMoAugBIQQgAygC5AEhBQwCC0EEIQIMAQtBECECC0EACyEOIBJFIA1Fcg0AIA0QwAELAkAgByALRXINACAUBEAgCxDAAQsgEQRAIBFBBXQhByAPQRBqIQEDQCABQQRqKAIABEAgASgCABDAAQsgAUEgaiEBIAdBYGoiBw0ACwsgFUUNACAPEMABCyAWRSAOIBpFcnINACAaEMABCyADQYwCaiAGNgIAIANBiAJqIAQ2AgAgAyAFNgKEAiADIAI2AoACIANB4AFqQduFwABBGCADQYACahAUIABBHGogA0H4AWooAgA2AgAgAEEUaiADQfAB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ASACKAKsASEFIAJBhAFqIAIoArQBIgo2AgAgAkGAAWogATYCACACIAU2AnwgAiAENgJ4DA4LIANFBEAgAkGoAWogBhB3IAIoAqgBIgNBFkcEQCACKAK0ASEKIAIoArABIQkgAigCrAEhCAwQCyACQRBqIAYQeSACLQAQQQFxRQRAQQQhAwwMCyACLQARQSJHBEBBDiEDDAwLIAYQcyACQagBaiAGEHggAigCtAEhESACKAKwASEOIAIoAqwBIQMgAigCqAEiAUEBRgRAIAIoArgBIQogDiEIIBEhCQwQCyARRSABRSADQRRHcnINBSAOEMABDAULIAJBqAFqQYCCwABBBRAQDAMLIBZCAVIEQCACQagBaiAGEHcgAigCqAEiBEEWRwRAIAIoArQBIQogAigCsAEhASACKAKsASEFDA4LIAJBGGogBhB5IAItABhBAXFFBEBBBCEEDAMLIAItABlBIkcEQEEOIQQMAwsgBhBzIAJBqAFqIAYQeCACKAK0ASEBIAIoArABIQUgAigCrAEhBCACKAKoASIQQQFGBEAgAigCuAEhCgwOCyACIAE2AnQgAiAENgJwIAJB+ABqIAQgARCCAgJ/IAItAHhBAUcEQEEAIQcgAigCjAEhFSACKAKIASEKIAIoAoABIQggAigChAEMAQsgAiACLQB5OgCXASACQQI2ArwBIAJCAjcCrAEgAkGojcAANgKoASACQQM2AswBIAJBAjYCxAEgAiACQcABajYCuAEgAiACQZcBajYCyAEgAiACQfAAajYCwAEgAkGYAWogAkGoAWoQyQEgAkGoAWogAkGYAWoQygEgAigCnAEEQCACKAKYARDAAQsgAigCqAEhCCACKAKwASEKQQEhByACKAKsAQshCSAFBEAgBBDAAQsgAUUgEEUgBEEUR3JyRQRAIAUQwAELQgEhFiAHRQ0EQRQhBAwCCyACQagBakGhgMAAQQYQEAwCCyACQfgAaiAGEBEgAigCeCIEQRZGDQIgAkGEAWooAgAhCiACQYABaigCACEBIAIoAnwhBQwLCyAIIQUgCSEBDAoLIAJBtAFqKAIAIQogAkGwAWooAgAhASACKAKsASEFIAIoAqgBIQQMCQsgAkEIaiAGEHlBACEFIAItAAkhASACLQAIQQFxDQALC0ECIQcMBQsgAkGoAWogEhB1IAIoAqgBIgNB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AUEIaikCADcDACACIAEpAgA3AzgMBAsgAkHQAGogAkGIAWpBz4LAAEELEIUBIAIoAlBBAUYEQCACQUBrIAJB3ABqKQIANwMAIAIgAikCVDcDOAwECyACIAIoAlQ2AnggAiACQdgAai0AADoAfCACQdAAaiACQfgAakHagsAAQQkgAUEIahAFIAJB0ABqIQMCQCACKAJQQQNGBEAgAkHQAGogAkH4AGpBp4HAACABQRRqEAYgAigCUEEDRg0BCyACQUBrIANBCGopAgA3AwAgAiADKQIANwM4DAQLIAJBOGogAigCeCACLQB8EH0MAwsgAkHQAGogAkGIAWpBxYLAAEEKEIUBIAIoAlBBAUcNASACQUBrIAJB0ABqQQRyIgFBCGopAgA3AwAgAiABKQIANwM4DAILIAJBOGogAigCVCACQdgAai0AABB9DAELIAJBOGogAigCVCACQdgAai0AABB9CyACKAI4IgNBA0cEQCACQUBrKAIAIQEgAigCPCEEIAJB3ABqIAJBxABqKAIANgIAIAJB2ABqIAE2AgAgAiAENgJUIAIgAzYCUAwECwJAIAIoApABIgMgAigCjAFHBEAgAigCiAEhAQwBCyADQQFqIgEgA0kNBSADQQF0IgQgASAEIAFLGyIEQQBIDQUCfyADRQRAIARBARBADAELIAIoAogBIANBASAEEEELIgFFDQsgAiAENgKMASACIAE2AogBIAIoApABIQMLIAEgA2pB/QA6AABBAyEDIAJBAzYCUCACIAIoApABQQFqNgKQAQwDCwJAIAIoApABIgMgAigCjAFHBEAgAigCiAEhBAwBCyADQQFqIgQgA0kNBCADQQF0IgUgBCAFIARLGyIFQQBIDQQCfyADRQRAIAVBARBADAELIAIoAogBIANBASAFEEELIgRFDQkgAiAFNgKMASACIAQ2AogBCyADIARqQfsAOgAAIAIgAigCkAFBAWo2ApABIAJB0ABqIAJBiAFqQdyAwABBBBCBASACKAJQIgNBA0cEQCACQdgAaiIBKAIAIQQgAigCVCEFIAJB3ABqIgYgBigCADYCACABIAQ2AgAgAiAFNgJUIAIgAzYCUAwDCwJAIAIoApABIgMgAigCjAFHBEAgAigCiAEhBAwBCyADQQFqIgQgA0kNBCADQQF0IgUgBCAFIARLGyIFQQBIDQQCfyADRQRAIAVBARBADAELIAIoAogBIANBASAFEEELIgRFDQkgAiAFNgKMASACIAQ2AogBIAIoApABIQMLIAMgBGpBOjoAACACIAIoApABQQFqNgKQASABQRRqIQMgAUEIaiEEAkACQCABKAIEQQFHBEAgAkHQAGogAkGIAWpBtILAAEEFEIUBIAIoAlBBAUYEQCACQUBrIAJB3ABqKQIANwMAIAIgAikCVDcDOAwDCyACIAIoAlQ2AnggAiACQdgAai0AADoAfCACQdAAaiACQfgAakHPgMAAQQ0gBBAFIAIoAlBBA0YEQCACQdAAaiACQfgAakHAgMAAIAMQCSACKAJQQQNGDQILIAJBQGsgAkHQAGoiAUEIaikCADcDACACIAEpAgA3AzgMAgsgAkHQAGogAkGIAWpBsYLAAEEDEIUBIAIoAlBBAUYEQCACQUBrIAJB3ABqKQIANwMAIAIgAikCVDcDOAwCCyACIAIoAlQ2AnggAiACQdgAai0AADoAfCACQdAAaiACQfgAakHPgMAAQQ0gBBAFIAJB0ABqIQECQCACKAJQQQNGBEAgAkHQAGogAkH4AGpB5oHAACADEAkgAigCUEEDRg0BCyACQUBrIAFBCGopAgA3AwAgAiABKQIANwM4DAILIAJBOGogAigCeCACLQB8EH0MAQsgAkE4aiACKAJ4IAItAHwQfQsgAigCOCIDQQNHBEAgAkFAaygCACEBIAIoAjwhBCACQdwAaiACQcQAaigCADYCACACQdgAaiABNgIAIAIgBDYCVCACIAM2AlAMAwsCQCACKAKQASIDIAIoAowBRwRAIAIoAogBIQEMAQsgA0EBaiIBIANJDQQgA0EBdCIEIAEgBCABSxsiBEEASA0EAn8gA0UEQCAEQQEQQAwBCyACKAKIASADQQEgBBBBCyIBRQ0KIAIgBDYCjAEgAiABNgKIASACKAKQASEDCyABIANqQf0AOgAAQQMhAyACQQM2AlAgAiACKAKQAUEBajYCkAEMAgsgAkE4aiACKAJ4IAItAHwQfQsgAigCOCIDQQNHBEAgAkFAaygCACEBIAIoAjwhBCACQdwAaiACQcQAaigCADYCACACQdgAaiABNgIAIAIgBDYCVCACIAM2AlAMAQsCQCACKAKQASIDIAIoAowBRwRAIAIoAogBIQEMAQsgA0EBaiIBIANJDQIgA0EBdCIEIAEgBCABSxsiBEEASA0CAn8gA0UEQCAEQQEQQAwBCyACKAKIASADQQEgBBBBCyIBRQ0IIAIgBDYCjAEgAiABNgKIASACKAKQASEDCyABIANqQf0AOgAAQQMhAyACQQM2AlAgAiACKAKQAUEBajYCkAELIANBA0cEQCACQdwAaigCACEBIAJB2ABqKAIAIQcgAigCVCEEIAIoAowBBEAgAigCiAEQwAELIAJB3ABqIAE2AgAgAkHYAGoiASAHNgIAIAIgBDYCVCACIAM2AlAgAkGgAWpB+IbAAEE9IAJB0ABqEBYgAkHoAGogAkG4AWooAgA2AgAgAkHgAGogAkGwAWopAgA3AwAgASACQagBaikCADcDACACIAIpAqABNwNQIAJBzABqQQE2AgAgAkIBNwI8IAJB4ITAADYCOCACQQY2AnwgAiACQfgAajYCSCACIAJB0ABqNgJ4IAJBiAFqIAJBOGoQyQEQjgEhASACQcIAaiACQZABaigCADYBACACIAIpA4gBNwE6IAAgAToABSAAQQA6AAQgACACKQE4NwEGIABBDGogAkE+aikBADcBACAAQQE2AgAgAkHQAGoQHAwFCyACKAKMASENIAJB0ABqIAIoAogBIg4gAigCkAEQZiACKAJQIg9BAUcNASACQUBrIgEgAkHcAGopAgA3AwAgAiACKQJUNwM4IAJBtAFqQQE2AgAgAkIBNwKkASACQYCFwAA2AqABIAJBBzYCfCACIAJB+ABqNgKwASACIAJBOGo2AnggAkGIAWogAkGgAWoQyQEQjgEhByACQaoBaiACQZABaigCADYBACACIAIpA4gBNwGiASAAIAc6AAUgAEEAOgAEIAAgAikBoAE3AQYgAEEMaiACQaYBaikBADcBACAAQQE2AgACQCACKAI4IgBBAk0EQAJAAkAgAEEBaw4CAQMACyACQUBrKAIARQ0CIAIoAjwQwAEMAgsgAkFAaygCAEUNASACKAI8EMABDAELIAEoAgBFDQAgAigCPBDAAQtBASEDQQAMAgsQyAEACyACKAJUQQFGBEBBASEFIABBATYCACAAQRxqIAJB8ABqKAIANgIAIABBFGogAkHoAGopAwA3AgAgAEEMaiACQeAAaikDADcCACAAIAJB2ABqKQMANwIEQQEhA0EADAILIAJBgAFqIAJB4ABqKAIA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ASACKAIAQQNGDQIgACACKQMANwIAIABBCGogAkEIaikDADcCACACQRBqJAAPCyAEQQEQxwEACxDIAQALAkAgAigCAEEBRw0AIAJBCGooAgBFDQAgAigCBBDAAQsgARAoAAv/AQEBfwJAAkAgAC0AACIBQQdNBEACQAJAAkACQAJAAkAgAUEBaw4HAQIDBwQFBwALIABBCGooAgBFDQYMBwsgAEEIaigCAEUNBQwGCyAAQQhqKAIARQ0EDAULIABBCGooAgBFDQMMBAsgAEEIaigCAARAIABBBGooAgAQwAELIABBFGooAgBFDQIgAEEQaigCABDAAQ8LIABBCGooAgAEQCAAQQRqKAIAEMABCyAAQRRqKAIARQ0BIABBEGooAgAQwAEMAQsgAEEIaigCAARAIABBBGooAgAQwAELIABBFGooAgBFDQAgAEEQaigCABDAAQsPCyAAQQRqKAIAEMABCwwAQuSuwoWXm6WIEQszAQF/IwBBEGsiACQAIABBHzYCDCAAQZCPwAA2AgggAEEIakGIhcAAQQBBgI/AABC1AQALEQAgACgCACkDAEEBIAEQ9AELDAAgACgCACABEPUBCxEAIAAoAgAgACgCBCABEP8BCwMAAQvDAQEBfwJAIAAoAgAiAUECTQRAAkACQCABQQFrDgIDAQALIAAoAgQgAEEMaigCAARAIABBCGooAgAQwAELDQIgAEEYaigCAEUNAiAAQRRqKAIAEMABDwsgACgCBEEBRw0BIABBDGooAgAEQCAAQQhqKAIAEMABCyAAQRRqKAIAIgFFDQEgAEEYaigCAEUNASABEMABDAELIABBDGooAgAEQCAAQQhqKAIAEMABCyAAQRhqKAIARQ0AIABBFGooAgAQwAELC/sFAQV/IAAoAggiAQRAIAAoAgAiBCABQcgAbGohBQNAIAQiAUHIAGohBAJAIAEoAgAiAkECTQRAAkACQCACQQFrDgIDAQALIAFBCGooAgAEQCABKAIEEMABCyABQRRqKAIABEAgAUEQaigCABDAAQsgAUEkaigCACICBEAgAkEFdCECIAFBHGooAgBBEGohAwNAIANBBGooAgAEQCADKAIAEMABCyADQSBqIQMgAkFgaiICDQALCyABQSBqKAIARQ0CIAEoAhwQwAEMAgsgAUEIaigCACICQQJNBEACQAJAAkAgAkEBaw4CAQIACyABQRBqKAIABEAgAUEMaigCABDAAQsgAUEsaigCAEUNBCABQShqKAIAEMABDAQLIAFBEGooAgAEQCABQQxqKAIAEMABCyABQSxqKAIARQ0DIAFBKGooAgAQwAEMAwsgAUEQaigCAARAIAFBDGooAgAQwAELIAFBGGooAgAiAkUNAiABQRxqKAIARQ0CIAIQwAEMAgsgAUEQaigCAARAIAFBDGooAgAQwAELIAFBHGooAgAEQCABQRhqKAIAEMABCyABQTxqKAIARQ0BIAFBOGooAgAQwAEMAQsgAUEQaigCACECIAFBCGooAgBFBEAgAgRAIAEoAgwQwAELIAFBHGooAgAEQCABQRhqKAIAEMABCyABQSxqKAIAIgIEQCACQQV0IQIgAUEkaigCAEEQaiEDA0AgA0EEaigCAARAIAMoAgAQwAELIANBIGohAyACQWBqIgINAAsLIAFBKGooAgBFDQEgASgCJBDAAQwBCyACBEAgASgCDBDAAQsgAUEgaigCACICBEAgAkEFdCECIAFBGGooAgBBEGohAwNAIANBBGooAgAEQCADKAIAEMABCyADQSBqIQMgAkFgaiICDQALCyABQRxqKAIABEAgASgCGBDAAQsgAUEkaigCACICRQ0AIAFBKGooAgBFDQAgAhDAAQsgBCAFRw0ACwsgAEEEaigCAARAIAAoAgAQwAELC74EAQR/IwBBEGsiBCQAIAAoAgAhAAJAAkACQAJAAkACQCABQYABTwRAIARBADYCDCABQYAQSQ0BIAFBgIAESQRAIAQgAUE/cUGAAXI6AA4gBCABQQZ2QT9xQYABcjoADSAEIAFBDHZBD3FB4AFyOgAMQQMhAQwECyAEIAFBP3FBgAFyOgAPIAQgAUESdkHwAXI6AAwgBCABQQZ2QT9xQYABcjoADiAEIAFBDHZBP3FBgAFyOgANQQQhAQwDCwJAIAAoAggiAiAAQQRqKAIARwRAIAAoAgAhAwwBCyACQQFqIgMgAkkNBiACQQF0IgUgAyAFIANLGyIFQQBIDQYCfyACRQRAIAVBARBADAELIAAoAgAgAkEBIAUQQQsiA0UNAiAAIAM2AgAgAEEEaiAFNgIAIAAoAgghAgsgAiADaiABOgAAIAAgACgCCEEBajYCCAwDCyAEIAFBP3FBgAFyOgANIAQgAUEGdkEfcUHAAXI6AAxBAiEBDAELIAVBARDHAQALAkAgAEEEaigCACIDIABBCGooAgAiAmsgAU8EQCAAKAIAIQMMAQsgASACaiIFIAJJDQMgA0EBdCICIAUgAiAFSxsiAkEASA0DAn8gA0UEQCACQQEQQAwBCyAAKAIAIANBASACEEELIgNFDQIgACADNgIAIABBBGogAjYCACAAQQhqKAIAIQILIABBCGogASACajYCACACIANqIARBDGogARCOAhoLIARBEGokAEEADwsgAkEBEMcBAAsQyAEAC1oBAX8jAEEgayICJAAgAiAAKAIANgIEIAJBGGogAUEQaikCADcDACACQRBqIAFBCGopAgA3AwAgAiABKQIANwMIIAJBBGpBnIrAACACQQhqENUBIAJBIGokAAu/AQEDfwJAAkACQCAAKAIAIgBBBGooAgAiBCAAQQhqKAIAIgNrIAJPBEAgACgCACEEDAELIAIgA2oiBSADSQ0CIARBAXQiAyAFIAMgBUsbIgNBAEgNAgJ/IARFBEAgA0EBEEAMAQsgACgCACAEQQEgAxBBCyIERQ0BIAAgBDYCACAAQQRqIAM2AgAgAEEIaigCACEDCyAAQQhqIAIgA2o2AgAgAyAEaiABIAIQjgIaQQAPCyADQQEQxwEACxDIAQALoAEBA38CQAJAIAAoAggiASAAQQRqKAIARgR/IAFBAWoiAiABSQ0CIAFBAXQiAyACIAMgAksbIgJBAEgNAgJ/IAFFBEAgAkEBEEAMAQsgACgCACABQQEgAhBBCyIBRQ0BIAAgATYCACAAQQRqIAI2AgAgACgCCAUgAQsgACgCAGpBOjoAACAAIAAoAghBAWo2AggPCyACQQEQxwEACxDIAQALxwICAn8BfiMAQUBqIgIkACACIAE2AgQgAkEANgIQIAJCATcDCCACQQg2AhwgAiACQQRqNgIYIAIgAkEIajYCJCACQTxqQQE2AgAgAkIBNwIsIAJBnIXAADYCKCACIAJBGGo2AjgCQAJAIAJBJGpBnIrAACACQShqENUBRQRAIAIoAgwiAyACKAIQIgFHBEAgAyABSQ0CAkAgAUUEQCADBEAgAigCCBDAAQsgAkEBNgIIQQAhAQwBCyACKAIIIANBASABEEEiA0UNBCACIAM2AggLIAIgATYCDAsgAkEwaiACQRBqKAIAIgE2AgAgAiACKQMIIgQ3AyggAEEMaiABNgIAIAAgBDcCBCAAQRQ2AgAgAkFAayQADwtBpIXAAEE3IAJBKGpBtIrAABDfAQALQcyLwABBJEG8i8AAEM0BAAsgAUEBEMcBAAu5AQEBfyMAQUBqIgUkACAFIAI2AgwgBSABNgIIAkAgBARAIAVBNGpBCTYCACAFQSRqQQI2AgAgBUICNwIUIAVB/IzAADYCECAFQQI2AiwgBSAENgI8IAUgAzYCOCAFIAVBKGo2AiAgBSAFQThqNgIwDAELIAVBJGpBATYCACAFQgI3AhQgBUHgjMAANgIQIAVBAjYCLCAFIAVBKGo2AiALIAUgBUEIajYCKCAAIAVBEGoQKSAFQUBrJAAL9wIBBH8jAEEgayICJAAgAkEIaiABKAIAEHkCQAJAAkAgAi0ACEEBcUUEQEECIQMMAQsCQAJAIAItAAkiBCIDQf0ARwRAAkAgA0EsRgRAIAEtAARFDQEMAwsgAS0ABA0CQQkhAwwECyABKAIAEHMgAiABKAIAEHkgAi0AAEEBcUUEQEEEIQMMBAsgAi0AASEEDAILIABBADsBAAwECyABQQA6AAQLIARB/wFxIgNB/QBHBEAgA0EiRwRAQRAhAwwCCyACQRBqIAEoAgAQLCACKAIQIgNBFkYNAiACQRxqKAIAIQEgAkEYaigCACEEIAIoAhQhBQwBC0ETIQMLIABBAToAACAAQRBqIAE2AgAgAEEMaiAENgIAIABBCGogBTYCACAAQQRqIAM2AgAMAQsgAkEQaiABEC0gAigCEEEWRwRAIABBAToAACAAQQRqIAIpAxA3AgAgAEEMaiACQRhqKQMANwIADAELIABBgAI7AQALIAJBIGokAAvNAQEEfyMAQSBrIgIkACACIAEQeQJAIAItAABBAXEEQCACLQABQSJHBEAgAEEONgIADAILIAEQcyACQQhqIAEQeCACQRRqKAIAIQUgAkEQaigCACEBIAIoAgwhAyACKAIIIgRBAUYEQCACQRhqKAIAIQQgACABNgIEIAAgAzYCACAAQQxqIAQ2AgAgAEEIaiAFNgIADAILIABBFjYCACABBEAgAxDAAQsgBUUgBEUgA0EUR3JyDQEgARDAAQwBCyAAQQQ2AgALIAJBIGokAAtxAQN/IwBBEGsiAiQAIAIgASgCABB3AkAgAigCACIDQRZHBEAgAkEMaigCACEBIAJBCGooAgAhBCAAIAIoAgQ2AgQgACADNgIAIABBDGogATYCACAAQQhqIAQ2AgAMAQsgACABKAIAEBELIAJBEGokAAvKAgEDfyMAQSBrIgIkACACQQhqIAEoAgAQeUEBIQMCQAJAAkAgAi0ACEEBcQRAAkACQCACLQAJIgMiBEEsRwRAIARB3QBHDQFBACEDIABBADoAAQwGCyABKAIAEHMgAiABKAIAEHlBASEDIAItAABBAXFFDQMgAi0AASEDDAELIAEtAARFBEAgAEEEakEHNgIAQQEhAwwFCyABQQA6AAQLIANB3QBGDQIgAkEQaiABKAIAEBEgAigCECIBQRZHBEAgAkEYaigCACEDIAIoAhQhBCAAQRBqIAJBHGooAgA2AgAgAEEMaiADNgIAIABBCGogBDYCACAAQQRqIAE2AgBBASEDDAQLIABBAToAAUEAIQMMAwsgAEEEakEBNgIADAILIABBBGpBBDYCAAwBCyAAQQRqQRM2AgBBASEDCyAAIAM6AAAgAkEgaiQAC4wDAQV/IwBBIGsiAiQAIAIgARB5AkACQAJAIAItAABBAXEEQCACLQABQSJHBEAgAEEBOgAAIABBBGpBDjYCAAwECyABEHMgAkEIaiABEHggAkEUaigCACEDIAJBEGooAgAhBCACKAIMIQEgAigCCCIFQQFGBEAgAkEYaigCACEFIABBAToAACAAQRBqIAU2AgAgAEEMaiADNgIAIABBCGogBDYCACAAQQRqIAE2AgAMBAsgA0F4aiIGQQVLDQECQAJAIAZBAWsOBQMDAwMBAAsgAUGvj8AARwRAIAEpAABC9srJy+as2rLyAFINAwsgAEEAOwEADAMLIAFBtJDAAEcEQCABQbSQwABBDRCPAg0CCyAAQYACOwEADAILIABBAToAACAAQQRqQQQ2AgAMAgsgAkEIaiABIANBxJDAAEECECogAEEBOgAAIABBDGogAkEQaikDADcCACAAQQRqIAIpAwg3AgALIAQEQCABEMABCyADRSAFRSABQRRHcnINACAEEMABCyACQSBqJAALrwQBBX8jAEEgayICJAAgAiABEHkCQAJAAkAgAi0AAEEBcQRAIAItAAFBIkcEQCAAQQE6AAAgAEEEakEONgIADAQLIAEQcyACQQhqIAEQeCACQRRqKAIAIQMgAkEQaigCACEEIAIoAgwhASACKAIIIgVBAUYEQCACQRhqKAIAIQUgAEEBOgAAIABBEGogBTYCACAAQQxqIAM2AgAgAEEIaiAENgIAIABBBGogATYCAAwECyADQXtqIgZBEEsNAQJAAkACQAJAAkACQCAGQQFrDhAHAAEHBwMCBwcHBwcHBwcEBQsgAUHsjcAARwRAIAFB7I3AAEEHEI8CDQcLIABBADsBAAwHCyABQciPwABHBEAgASkAAELj4NX7xe3bt/AAUg0GCyAAQYACOwEADAYLIAFB0I/AAEcEQCABQdCPwABBDBCPAg0FCyAAQYAEOwEADAULIAFB3I/AAEcEQCABQdyPwABBCxCPAg0ECyAAQYAGOwEADAQLIAFB54/AAEcEQCABQeePwABBFRCPAg0DCyAAQYAIOwEADAMLIAFB/I/AAEcEQCABQfyPwABBBRCPAg0CCyAAQYAKOwEADAILIABBAToAACAAQQRqQQQ2AgAMAgsgAkEIaiABIANBhJDAAEEGECogAEEBOgAAIABBDGogAkEQaikDADcCACAAQQRqIAIpAwg3AgALIAQEQCABEMABCyADRSAFRSABQRRHcnINACAEEMABCyACQSBqJAAL4xABBH8jAEEwayIDJAACQAJAAkACQAJAAkACQAJAAkAgASgCCCIEIAFBBGooAgBHBEAgASgCACEFDAELIARBAWoiBSAESQ0HIARBAXQiBiAFIAYgBUsbIgZBAEgNBwJ/IARFBEAgBkEBEEAMAQsgASgCACAEQQEgBhBBCyIFRQ0BIAEgBTYCACABQQRqIAY2AgAgASgCCCEECyAEIAVqQfsAOgAAIAEgASgCCEEBajYCCCADQRhqIAFBjI3AAEEDEIEBIAMoAhgiBEEDRwRAIANBJGooAgAhASADQSBqKAIAIQIgACADKAIcNgIEIAAgBDYCACAAQQxqIAE2AgAgAEEIaiACNgIADAgLAkAgASgCCCIEIAFBBGooAgBHBEAgASgCACEFDAELIARBAWoiBSAESQ0HIARBAXQiBiAFIAYgBUsbIgZBAEgNBwJ/IARFBEAgBkEBEEAMAQsgASgCACAEQQEgBhBBCyIFRQ0CIAEgBTYCACABQQRqIAY2AgAgASgCCCEECyAEIAVqQTo6AAAgASABKAIIQQFqNgIIAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAi0AAEEBaw4IAQIDBAUGBwgACyADQRhqIAFBuoTAAEELEIUBIAMoAhhBAUcNCCADQQhqIANBJGopAgA3AwAgAyADKQIcNwMADBQLIANBGGogAUGshMAAQQ4QhQEgAygCGEEBRw0IIANBCGogA0EkaikCADcDACADIAMpAhw3AwAMEwsgA0EYaiABQaCEwABBDBCFASADKAIYQQFHDQggA0EIaiADQSRqKQIANwMAIAMgAykCHDcDAAwSCyADQRhqIAFBk4TAAEEJEIUBIAMoAhhBAUcNCCADQQhqIANBJGopAgA3AwAgAyADKQIcNwMADBELIANBGGogAUGHhMAAQQwQhQEgAygCGEEBRw0IIANBCGogA0EYakEEciICQQhqKQIANwMAIAMgAikCADcDAAwQCyADQRhqIAFB+IPAAEEJEIUBIAMoAhhBAUYEQCADQQhqIANBJGopAgA3AwAgAyADKQIcNwMADBALIAMgAygCHDYCECADIANBIGotAAA6ABQgA0EYaiADQRBqQYGEwABBBiACQQRqEAUgA0EYaiEEAkAgAygCGEEDRgRAIANBGGogA0EQakHAgMAAQQMgAkEQahAFIAMoAhhBA0YNAQsgA0EIaiAEQQhqKQIANwMAIAMgBCkCADcDAAwQCyADIAMoAhAgAy0AFBB9DA8LIANBGGogAUHlg8AAQQ0QhQEgAygCGEEBRgRAIANBCGogA0EkaikCADcDACADIAMpAhw3AwAMDwsgAyADKAIcNgIQIAMgA0Egai0AADoAFCADQRhqIANBEGpB8oPAAEEGIAJBBGoQBSADQRhqIQQCQCADKAIYQQNGBEAgA0EYaiADQRBqQcCAwABBAyACQRBqEAUgAygCGEEDRg0BCyADQQhqIARBCGopAgA3AwAgAyAEKQIANwMADA8LIAMgAygCECADLQAUEH0MDgsgA0EYaiABQdmDwABBDBCFASADKAIYQQFHDQYgA0EIaiADQRhqQQRyIgJBCGopAgA3AwAgAyACKQIANwMADA0LIANBGGogAUG/g8AAQQkQhQEgAygCGEEBRgRAIANBCGogA0EkaikCADcDACADIAMpAhw3AwAMDQsgAyADKAIcNgIQIAMgA0Egai0AADoAFCADQRhqIANBEGpByIPAAEEHIAJBBGoQBSADQRhqIQQCQCADKAIYQQNGBEAgA0EYaiADQRBqQc+DwABBCiACQRBqEAUgAygCGEEDRg0BCyADQQhqIARBCGopAgA3AwAgAyAEKQIANwMADA0LIAMgAygCECADLQAUEH0MDAsgAyADKAIcNgIQIAMgA0Egai0AADoAFCADQRhqIANBEGpBwIDAAEEDIAJBBGoQBSADKAIYQQNGDQUgA0EIaiADQSBqKQMANwMAIAMgAykDGDcDAAwLCyADIAMoAhw2AhAgAyADQSBqLQAAOgAUIANBGGogA0EQakHAgMAAQQMgAkEEahAFIAMoAhhBA0YNCSADQQhqIANBIGopAwA3AwAgAyADKQMYNwMADAoLIAMgAygCHDYCECADIANBIGotAAA6ABQgA0EYaiADQRBqQcCAwABBAyACQQRqEAUgAygCGEEDRg0HIANBCGogA0EgaikDADcDACADIAMpAxg3AwAMCQsgAyADKAIcNgIQIAMgA0Egai0AADoAFCADQRhqIANBEGpBnITAAEEEIAJBBGoQBSADKAIYQQNGDQUgA0EIaiADQSBqKQMANwMAIAMgAykDGDcDAAwICyADIAMoAhwgA0Egai0AABB9DAcLIAMgAygCHCADQSBqLQAAEH0MBgsgAyADKAIQIAMtABQQfQwFCyAGQQEQxwEACyAGQQEQxwEACyADIAMoAhAgAy0AFBB9DAILIAMgAygCECADLQAUEH0MAQsgAyADKAIQIAMtABQQfQsgAygCACICQQNHBEAgA0EMaigCACEBIANBCGooAgAhBCAAIAMoAgQ2AgQgACACNgIAIABBDGogATYCACAAQQhqIAQ2AgAMAgsCQAJAIAEoAggiBCABQQRqKAIARwRAIAEoAgAhBQwBCyAEQQFqIgIgBEkNAiAEQQF0IgUgAiAFIAJLGyICQQBIDQICfyAERQRAIAJBARBADAELIAEoAgAgBEEBIAIQQQsiBUUNASABIAU2AgAgAUEEaiACNgIAIAEoAgghBAsgBCAFakH9ADoAACAAQQM2AgAgASABKAIIQQFqNgIIDAILIAJBARDHAQALEMgBAAsgA0EwaiQACx0AIAEoAgBFBEAACyAAQdCNwAA2AgQgACABNgIAC1UBAn8gASgCACECIAFBADYCAAJAIAIEQCABKAIEIQNBCEEEEEAiAUUNASABIAM2AgQgASACNgIAIABB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AnwhBiADQZgBaiACQQxqIggQZCADQZgBakEEciEEIAMoApgBQQFGBEAgAEEBNgIAIAAgBCkCADcCBCAAQRxqIARBGGooAgA2AgAgAEEUaiAEQRBqKQIANwIAIABBDGogBEEIaikCADcCACAFRQ0BIAYQwAEMAQsgA0HkAGogBEEIaigCADYCACADQfAAaiABQShqKAIANgIAIAMgBzYCWCADIAU2AlQgAyAGNgJQIAMgBCkCADcCXCADIAEpAiA3A2ggA0G4AWoQfyADQdABaiADQbgBahCEAQJAIAMoAtABQQFGBEAgA0H4AWogA0HcAWopAgA3AwAgAyADKQLUATcD8AEMAQsgAyADKALUATYCyAEgAyADQdgBai0AADoAzAEgA0HQAWogA0HIAWpBr4/AAEEIIANB0ABqEDcgA0HQAWohBAJAIAMoAtABQQNHDQAgA0HQAWogA0HIAWpBt4/AAEELIANB3ABqEDcgAygC0AFBA0cNACADQdABaiADQcgBakHCj8AAQQYgA0HoAGoQNyADKALQAUEDRw0AIANB8AFqIAMoAsgBIAMtAMwBEHwMAQsgA0H4AWogBEEIaikCADcDACADIAQpAgA3A/ABCwJ/IAMoAvABIgRBA0cEQCADQfgBaigCACEFIANB/AFqKAIAIQYgAygC9AEhByADKAK8AQRAIAMoArgBEMABCyADQfwBaiAGNgIAIANB+AFqIAU2AgAgAyAHNgL0ASADIAQ2AvABIANB0AFqQZiJwABBGSADQfABahAWIANByABqIANB5AFqKQIANwMAIAMgA0HcAWopAgA3A0AgA0HYAWooAgAhBSADKALQASEEQQEhBiADKALUAQwBCyADKALAASEFIAMoArgBIQRBACEGIAMoArwBCyEHIANBLGoiCSAFNgIAIANBKGogBzYCACADQTBqIAMpA0A3AwAgA0E4aiADQcgAaikDADcDACADIAQ2AiQgAyAGNgIgAkAgBkUEQCADQeCNwABBBiAEIAUQYyADLQAAQQlHDQEgBwRAIAQQwAELIAMoAlQEQCADKAJQEMABCyADQeAAaigCAARAIAMoAlwQwAELIANB7ABqKAIABEAgAygCaBDAAQsgAEEYakIANwIAIABBEGpCBDcCACAAQQhqQgA3AgAgAEKAgICAgAE3AgAgAkEEaigCAARAIAIoAgAQwAELIAJBEGooAgAEQCAIKAIAEMABCyABQRRqKAIABEAgASgCEBDAAQsgAUE0aigCACIABEAgAEEFdCECIAFBLGooAgBBEGohAANAIABBBGooAgAEQCAAKAIAEMABCyAAQSBqIQAgAkFgaiICDQALCyABQTBqKAIABEAgASgCLBDAAQsgAUE8aigCAEUNBCABKAI4EMABDAQLIAAgAykCJDcCBCAAQQE2AgAgAEEcaiADQTxqKAIANgIAIABBFGogA0E0aikCADcCACAAQQxqIAkpAgA3AgAgAygCVARAIAMoAlAQwAELIANB4ABqKAIABEAgAygCXBDAAQsgA0HsAGooAgAEQCADKAJoEMABCyACQQRqKAIABEAgAigCABDAAQsgAkEQaigCAARAIAgoAgAQwAELIAFBFGooAgBFDQIgASgCEBDAAQwCCyAAIAMpAwA3AgQgAEEBNgIAIABBHGogA0EYaigCADYCACAAQRRqIANBEGopAwA3AgAgAEEMaiADQQhqKQMANwIAIAcEQCAEEMABCyADKAJUBEAgAygCUBDAAQsgA0HgAGooAgAEQCADKAJcEMABCyADQewAaigCAARAIAMoAmgQwAELIAJBBGooAgAEQCACKAIAEMABCyACQRBqKAIABEAgCCgCABDAAQsgAUEUaigCAEUNASABKAIQEMABDAELIAJBBGooAgAEQCACKAIAEMABCyACQRBqKAIABEAgAigCDBDAAQsgAUEUaigCAARAIAEoAhAQwAELIAFBJGooAgBFDQAgASgCIBDAAQsgAUE0aigCACIABEAgAEEFdCECIAFBLGooAgBBEGohAANAIABBBGooAgAEQCAAKAIAEMABCyAAQSBqIQAgAkFgaiICDQALCyABQTBqKAIABEAgASgCLBDAAQsgAUE8aigCAEUNACABKAI4EMABCyADQYACaiQAC+4YAgl/A34jAEHAAmsiAyQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCACQf8BcUEBaw4FAgMEBQABCxAeAAsgA0EQaiABQcgAEI4CGiADQYABahBiIAMoAoABQQFHDQkgAEEBNgIAIAAgA0GAAWpBBHIiASkCADcCBCAAQRxqIAFBGGooAgA2AgAgAEEUaiABQRBqKQIANwIAIABBDGogAUEIaikCADcCAAwKCxA6AAsCQANAIAMgDDcD+AEgAyADQfgBajYCyAEgA0EANgKgAiADQgE3A5gCIANBCjYCXCADIANByAFqNgJYIAMgA0GYAmo2AtgBIANBATYClAEgA0IBNwKEASADQZyFwAA2AoABIAMgA0HYAGo2ApABIANB2AFqQZyKwAAgA0GAAWoQ1QENBQJAIAMoApwCIgIgAygCoAIiBEYEQCADKAKYAiEFDAELIAIgBEkNByAERQRAIAIEQCADKAKYAhDAAQsgA0IBNwOYAkEAIQJBASEFDAELIAMoApgCIAJBASAEEEEiBUUNCCADIAQ2ApwCIAMgBTYCmAIgBCECCyADQRBqQaSOwABBCCAFIAMoAqACEGMgAy0AEEEJRw0BIAIEQCAFEMABCyADKQP4ASINQgF8IgwgDVoNAAtBgIvAAEEcQayOwAAQzQEACyAAIAMpAxA3AgQgAEEBNgIAIABBHGogA0EoaigCADYCACAAQRRqIANBIGopAwA3AgAgAEEMaiADQRhqKQMANwIAIAJFDQIgBRDAAQwCCxA7AAtBwAxAAEF/RwRAIABCgICAgIABNwIAIABBGGpCADcCACAAQRBqQgQ3AgAgAEEIakIANwIADAELQSBBARBAIgJFDQQgAkEYakH4jsAAKQAANwAAIAJBEGpB8I7AACkAADcAACACQQhqQeiOwAApAAA3AAAgAkHgjsAAKQAANwAAEI4BIQQgAEEMakKggICAgAQ3AgAgAEEIaiACNgIAIAAgBDoABSAAQQA6AAQgAEEBNgIAIABBFGogAykCmAI3AgAgAEEcaiADQaACaigCADYCAAsgAUEUaigCAARAIAEoAhAQwAELIAFBJGooAgAEQCABKAIgEMABCyABQSxqKAIAIQAgAUE0aigCACICBEAgAkEFdCEEIABBEGohAgNAIAJBBGooAgAEQCACKAIAEMABCyACQSBqIQIgBEFgaiIEDQALCyABQTBqKAIABEAgABDAAQsgAUE8aigCAEUNBiABKAI4EMABDAYLQaSFwABBNyADQYABakG0isAAEN8BAAtBzIvAAEEkQbyLwAAQzQEACyAEQQEQxwEAC0EgQQEQxwEACwJ/AkAgAygChAEiAkUEQEEBIQFBBSEGQQVBARBAIgQNAUEFQQEQxwEACyACQQh2IQUgA0GIAWooAgAhBCADQYwBaigCACEGQQAhASACQYCAfHEMAQsgBEEEakGCjsAALQAAOgAAIARB/o3AACgAADYAABCOASEFIANB4ABqIANBoAJqKAIANgIAIAMgAykCmAI3A1hBAyECQQALIQcgA0GAAmoiCCADQeAAaigCADYCACADIAMpA1g3A/gBIAJB/wFxIAVBCHRBgP4DcXIgB3IhBSABBEAgACAFNgIEIABBATYCACAAQRBqQQU2AgAgAEEMaiAGNgIAIABBCGogBDYCACAAQRRqIAMpA/gBNwIAIABBHGogCCgCADYCAAwBCyADQYABaiAFIAYQFSADQYABakEEciEBIAMoAoABQQFGBEAgAEEBNgIAIAAgASkCADcCBCAAQRxqIAFBGGooAgA2AgAgAEEUaiABQRBqKQIANwIAIABBDGogAUEIaikCADcCACAERQ0BIAUQwAEMAQsgA0H4AGogAUEgaigCADYCACADQfAAaiABQRhqKQIANwMAIANB6ABqIAFBEGopAgA3AwAgA0HgAGogAUEIaikCACIMNwMAIAMgASkCACINNwNYAkACQAJAAkAgA0E4aigCACIBIAynRgRAIAMoAjAiAiANpyIGRg0BIAIgBiABEI8CRQ0BCxCOASEBIANBgAFqIgJBBzoAACACIAE6AAEgAEEBNgIAIABBHGogA0GYAWooAgA2AgAgAEEUaiADQZABaikDADcCACAAQQxqIANBiAFqKQMANwIAIAAgAykDgAE3AgQMAQsgA0GAAWogA0HkAGoQZSADQYABakEEciEBIAMoAoABQQFGBEAgAEEBNgIAIAAgASkCADcCBCAAQRxqIAFBGGooAgA2AgAgAEEUaiABQRBqKQIANwIAIABBDGogAUEIaikCADcCAAwDCyADQbABaiABQQhqIgIoAgA2AgAgAyABKQIANwOoASADQYABaiADQcgAahBlIAMoAoABQQFGBEAgAEEBNgIAIAAgASkCADcCBCAAQRxqIAFBGGooAgA2AgAgAEEUaiABQRBqKQIANwIAIABBDGogAikCADcCAAwCCyADQcABaiACKAIANgIAIAMgASkCADcDuAEgA0GAAWogA0G4AWoQygEgA0GgAmogAykCgAE3AwAgA0GoAmogA0GIAWooAgA2AgAgA0KAgICAEDcDmAIgA0GAAWogA0GYAmoQGiADQYABakEEciEBIAMoAoABQQFGBEAgA0GQAmoiAiABQRhqKAIANgIAIANBiAJqIgYgAUEQaikCADcDACADQYACaiIHIAFBCGopAgA3AwAgAyABKQIANwP4ASADQZgCahAjIANB8AFqIAIoAgAiATYCACADQegBaiAGKQMAIgw3AwAgA0HgAWogBykDACINNwMAIAMgAykD+AEiDjcD2AEgAEEcaiABNgIAIABBFGogDDcCACAAQQxqIA03AgAgACAONwIEIABBATYCACADKAK8AUUNAiADKAK4ARDAAQwCCyADQYACaiICIAFBCGooAgA2AgAgAyABKQIANwP4ASADQZgCahAjIANB4AFqIAIpAwAiDDcDACADQdABaiAMPgIAIAMgAykD+AE3A8gBAkBBMEEEEEAiAQRAIANBmAJqQeaNwABBBkHsjcAAQQcQXCADQQhqIANBqAFqEF4gA0GAAWpB843AAEELIAMoAgggAygCDBBcIAFBEGogA0GoAmoiBikDADcCACABQQhqIANBoAJqKQMANwIAIAEgAykDmAI3AgAgASADKQOAATcCGCABQSBqIANBiAFqKQMANwIAIAFBKGogA0GQAWoiBykDADcCAEHIAEEIEEAiAkUNASADQYgBaiIIIANBwAFqKAIANgIAIANBlAFqIANBsAFqKAIANgIAIANBsAJqIgkgAykDyAE3AwAgA0G4AmoiCiADQdABaigCADYCACADIAMpA6gBNwKMASADQaACaiILIAgpAwA3AwAgBiAHKQMANwMAIAMgAykDuAE3A5gCIAJBADYCACACIAMpA5gCNwIEIAJBDGogCykDADcCACACQRRqIAYpAwA3AgAgAkEcaiAJKQMANwIAIAJBJGogCigCADYCACAAQRxqQQA2AgAgAEEUakKCgICAIDcCACAAQRBqIAE2AgAgAEEIakKBgICAEDcCACAAIAI2AgQgAEEANgIADAILQTBBBBDHAQALQcgAQQgQxwEACyADKAJcBEAgAygCWBDAAQsgA0HoAGooAgAEQCADKAJkEMABCyADQfQAaigCAARAIAMoAnAQwAELIAQEQCAFEMABCyADQSRqKAIABEAgAygCIBDAAQsgA0E0aigCAARAIAMoAjAQwAELIANBxABqKAIAIgAEQCAAQQV0IQQgA0E8aigCAEEQaiECA0AgAkEEaigCAARAIAIoAgAQwAEL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An8gBEUEQCAFQQEQQAwBCyABKAIAIARBASAFEEELIgNFDQcgASADNgIAIAFBBGogBTYCACABQQhqKAIAIQQLIAMgBGpBIjoAACABQQhqIgMgAygCAEEBaiIENgIAAkAgAUEEaigCACIDIARrQQZPBEAgASgCACEDDAELIARBBmoiBSAESQ0KIANBAXQiBCAFIAQgBUsbIgRBAEgNCgJ/IANFBEAgBEEBEEAMAQsgASgCACADQQEgBBBBCyIDRQ0IIAEgAzYCACABQQRqIAQ2AgAgAUEIaigCACEECyABQQhqIgUgBEEGajYCACADIARqIgNBBGpBpYDAAC8AADsAACADQaGAwAAoAAA2AAACQCABQQRqKAIAIgMgBSgCACIEa0ECTwRAIAEoAgAhAwwBCyAEQQJqIgUgBEkNCiADQQF0IgQgBSAEIAVLGyIEQQBIDQoCfyADRQRAIARBARBADAELIAEoAgAgA0EBIAQQQQsiA0UNCSABIAM2AgAgAUEEaiAENgIAIAFBCGooAgAhBAsgAUEIaiAEQQJqNgIAIAMgBGpBovQAOwAAIAJBKGogAkHQAGogARALIAIoAigiA0EDRw0KIAIgAUEAEHwMCwsgAEEBNgIAIAAgAkEoakEEciIDKQIANwIEIABBHGogA0EYaigCADYCACAAQRRqIANBEGopAgA3AgAgAEEMaiADQQhqKQIANwIADA4LIAZBARDHAQALIAZBARDHAQALIANBARDHAQALIANBARDHAQALIAVBARDHAQALIAVBARDHAQALIARBARDHAQALIARBARDHAQALEMgBAAsgAkEwaigCACEBIAIoAiwhBCACQQxqIAJBNGooAgA2AgAgAkEIaiABNgIAIAIgBDYCBCACIAM2AgALIAACfyACKAIAIgFBA0cEQCACQQxqKAIAIQMgAkEIaigCACEEIAIoAgQhBSACKAKUAQRAIAIoApABEMABCyACQQxqIAM2AgAgAkEIaiAENgIAIAIgBTYCBCACIAE2AgAgAkEoakHyicAAQScgAhAWIAJB+ABqIAJBPGopAgAiDDcDACACIAJBNGopAgAiDTcDcCACKQMoIQ4gAEEMaiACQTBqKAIANgIAIAAgDjcCBCAAQRBqIA03AgAgAEEYaiAMNwIAQQEMAQsgAikDkAEhDCAAQQxqIAIoApgBNgIAIAAgDDcCBEEACzYCACACKAJQIQMgAigCWCIABEAgAEEFdCEBIANBEGohAANAIABBBGooAgAEQCAAKAIAEMABCyAAQSBqIQAgAUFgaiIBDQALCyACKAJURQ0EIAMQwAEMBAsgAkEwaigCACEEIAIoAiwhBSACQZwBaiACQTRqKAIANgIAIAJBmAFqIAQ2AgAgAiAFNgKUASACIAM2ApABCwJAIAIoApABIgNBA0cEQCACQZwBaigCACEEIAJBmAFqKAIAIQUgAigClAEhBiACKAJkRQ0BIAIoAmAQwAEMAQsgAkHYAGogAkH4AGopAwA3AwAgAiACKQNwNwNQIAIpA2AhDCAAQQxqIAIoAmg2AgAgACAMNwIEIABBADYCACACKAIEBEAgAigCABDAAQsgAkEQaigCAARAIAIoAgwQwAELIAJBHGooAgAEQCACKAIYEMABCyAHBEAgCBDAAQsgCkUNAiAJEMABDAILIAJBnAFqIAQ2AgAgAkGYAWogBTYCACACIAY2ApQBIAIgAzYCkAEgAkEoakHOicAAQSQgAkGQAWoQFiACQdgAaiACQTxqKQIAIgw3AwAgAiACQTRqKQIAIg03A1AgAikDKCEOIABBDGogAkEwaigCADYCACAAIA43AgQgAEEQaiANNwIAIABBGGogDDcCACAAQQE2AgAgAigCBARAIAIoAgAQwAELIAJBEGooAgAEQCACKAIMEMABCyACQRxqKAIABEAgAigCGBDAAQsgBwRAIAgQwAELIApFDQEgCRDAAQwBCyAHRQ0AIAgQwAELIAEoAgAiAEUNACABQQRqKAIARQ0AIAAQwAELIAJBsAFqJAALpR4CG38DfiMAQZACayICJAAgAkHwAGogABBpIAJB8ABqQQRyIQACQCACKAJwQQFGBEAgAkHkAGogAEEYaigCADYCACACQdwAaiAAQRBqKQIANwIAIAJB1ABqIABBCGopAgA3AgAgAkEBNgJIIAIgACkCADcCTAwBCyACQfwAaiIDKAIAIQQgAkH4AGoiBSgCACERIAIoAnQhCiACQfAAaiABEGkCQCACKAJwQQFGBEAgAkHkAGogAEEYaigCADYCACACQdwAaiAAQRBqKQIANwIAIAJB1ABqIABBCGopAgA3AgAgAkEBNgJIIAIgACkCADcCTAwBCyADKAIAIQAgBSgCACESIAIoAnQh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2AJBAUcEQAJAIAIoAogDIgAgAigChANHBEAgAigCgAMhAwwBCyAAQQFqIgEgAEkNCSAAQQF0IgMgASADIAFLGyIBQQBIDQkCfyAARQRAIAFBARBADAELIAIoAoADIABBASABEEELIgNFDQIgAiABNgKEAyACIAM2AoADCyAAIANqQfsAOgAAIAIgAigCiANBAWo2AogDIAJBsANqIAJBgANqQY+NwABBAhCBASACKAKwAyIBQQNHBEAgAkG8A2ooAgAhACACQbgDaigCACEDIAIoArQDIQQMBgsCQCACKAKIAyIBIAIoAoQDRwRAIAIoAoADIQMMAQsgAUEBaiIAIAFJDQkgAUEBdCIDIAAgAyAASxsiAEEASA0JAn8gAUUEQCAAQQEQQAwBCyACKAKAAyABQQEgABBBCyIDRQ0DIAIgADYChAMgAiADNgKAAyACKAKIAyEBCyABIANqQTo6AAAgAiACKAKIA0EBajYCiAMgAkGwA2ogAkGAA2oQhAEgAigCsANBAUYEQCACQZgDaiACQbwDaikCADcDACACIAIpArQDNwOQAwwFCyACIAIoArQDNgKABCACIAJBuANqLQAAOgCEBCACQbADaiACQYAEaiAEEDYgAkGwA2ohACACKAKwA0EDRw0DIAJBsANqIAJBgARqIAJB6AJqEDQgAigCsANBA0cNAyACQbADaiACQYAEaiACQfQCahA1IAIoArADQQNHDQMgAkGQA2ogAigCgAQgAi0AhAQQfAwECyACQZAEaiACQYADaiAEEDEgAigCkAQiAUEDRwRAIAJBnARqKAIAIQAgAkGYBGooAgAhAyACKAKUBCEEDAULIAIoAogDIQEMBQsgAUEBEMcBAAsgAEEBEMcBAAsgAkGYA2ogAEEIaikCADcDACACIAApAgA3A5ADCyACKAKQAyIBQQNHBEAgAkGYA2ooAgAhAyACQZwDaigCACEAIAIoApQDIQQMAQsCQCACKAKIAyIBIAIoAoQDRwRAIAIoAoADIQMMAQsgAUEBaiIAIAFJDQQgAUEBdCIDIAAgAyAASxsiAEEASA0EAn8gAUUEQCAAQQEQQAwBCyACKAKAAyABQQEgABBBCyIDRQ0DIAIgADYChAMgAiADNgKAAyACKAKIAyEBCyABIANqQf0AOgAAIAIgAigCiANBAWoiATYCiAMMAQsgAigChAMEQCACKAKAAxDAAQsgAkGcA2ogADYCACACQZgDaiADNgIAIAIgBDYClAMgAiABNgKQAyACQbADakGOhsAAQeoAIAJBkANqEBYgAkGYBGogAkHEA2oiACkCACIXNwMAIAIgAkG8A2oiASkCACIYNwOQBCACKQOwAyEZIAJBuANqIgMgAygCADYCACABIBg3AgAgACAXNwIAIAIgGTcDsANBxIrAAEErIAJBsANqQfCKwAAQ3wEACyACKQOAAyEXIAIgATYCuAMgAiAXNwOwAyACQbADahBoAkAgAigC2AJFBEAgBBAkIAJB8AJqKAIAIgEEQCACQegCaigCACEAIAFBGGwhAQNAIABBBGooAgAEQCAAKAIAEMABCyAAQRBqKAIABEAgAEEMaigCABDAAQsgAEEYaiEAIAFBaGoiAQ0ACwsgAkHsAmooAgAEQCACKALoAhDAAQsgAkH0AmooAgAiAEUNASACQfgCaigCAEUNASAAEMABDAELIAQQHAsgAkGgBGokAA8LIABBARDHAQALEMgBAAu1GwIPfwN+IwBB8AFrIgEkACABQaABaiAAEGlBBCEAAkAgASgCoAFBAUYEQCABQZwBaiABQaABakEEciIAQRhqKAIANgIAIAFBlAFqIABBEGopAgA3AgAgAUGMAWogAEEIaikCADcCACABQQE2AoABIAEgACkCADcChAEMAQsgAUGoAWoiDigCACELIAFB4AFqIAEoAqQBIgwgAUGsAWoiDygCABByIAFB+ABqIAFB4AFqEHkCQCABLQB4QQFxRQ0AIAEtAHkiAkH7AEcEQCACQSJHBEBBCiEADAILIAFBoAFqIAFB4AFqEC8gAUGsAWooAgAhAiABQagBaigCACEEIAEoAqQBIQNBDiEAAkAgAS0AoAEiCEEBTQRAIAhBAWsNAwwBCyACRSADQRRHcg0CIAQQwAEMAgsgAUGwAWooAgAhBSADIQAMAQsgAUHgAWoQcyABQaABaiABQeABaiIJEC8gAUGsAWooAgAhAiABQagBaigCACEEIAEoAqQBIQMgAS0AoQEhBwJAIAEtAKABIgVBAU0EQCAFQQFrDQEgAUGwAWooAgAhBSADIQAMAgsgAkUgA0EUR3INACAEEMABCyABQaABaiAJEHcgASgCoAEiA0EWRwRAIAFBrAFqKAIAIQUgAUGoAWooAgAh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AgAgASAHNgKkASABIAFB4AFqNgKgASABQYABaiABQaABakEEchA8IAtFDQMgDBDAAQwDC0ECIQAMAQtBDiEACyABQewBaiAFNgIAIAFB6AFqIAI2AgAgASAENgLkASABIAA2AuABIAFBoAFqQfyIwABBHCABQeABahAUIAFByAFqIAFBtAFqKQIAIhA3AwAgAUGMAWogDigCADYCACABQZABaiAPKQIANwMAIAFBmAFqIBA3AwAgAUEBNgKAASABIAEpA6ABNwKEASALRQ0AIAwQwAELIAFB0AFqEH8gAUGAAWpBBHIhCAJAAkACQAJAAn8gASgCgAFBAUcEQAJAIAEoAtgBIgcgASgC1AFHBEAgASgC0AEhAgwBCyAHQQFqIgMgB0kNBSAHQQF0IgAgAyAAIANLGyIAQQBIDQUCfyAHRQRAIABBARBADAELIAEoAtABIAdBASAAEEELIgJFDQYgASAANgLUASABIAI2AtABCyACIAdqQfsAOgAAIAEgASgC2AFBAWo2AtgBIAFBoAFqIAFB0AFqQY+NwABBAhCBASABKAKgASIGQQNHBEAgAUGoAWooAgAhAiABKAKkASEEIAFBrAFqKAIADAILAkAgASgC2AEiBiABKALUAUcEQCABKALQASECDAELIAZBAWoiAyAGSQ0FIAZBAXQiACADIAAgA0sbIgBBAEgNBQJ/IAZFBEAgAEEBEEAMAQsgASgC0AEgBkEBIAAQQQsiAkUNBiABIAA2AtQBIAEgAjYC0AEgASgC2AEhBgsgAiAGakE6OgAAIAEgASgC2AFBAWo2AtgBIAFBwAFqIAgQWiABQaABaiABQdABaiABKALAASIAIAEoAsgBEIEBIAEoAsQBBEAgABDAAQsgASgCoAEiBkEDRwRAIAFBqAFqKAIAIQIgASgCpAEhBCABQawBaigCAAwCCwJAIAEoAtgBIgYgASgC1AFHBEAgASgC0AEhAgwBCyAGQQFqIgMgBkkNBSAGQQF0IgAgAyAAIANLGyIAQQBIDQUCfyAGRQRAIABBARBADAELIAEoAtABIAZBASAAEEELIgJFDQYgASAANgLUASABIAI2AtABIAEoAtgBIQYLIAIgBmpB/QA6AAAgASABKALYAUEBaiIGNgLYAQwDCyABQeABaiABQdABaiAIEDEgASgC4AEiBkEDRg0BIAFB6AFq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AmooAgAhBiADQdACaigCACECIAMoAswCIQcgAygCyAJBAUYEQCACIQQgBiECIAEhBiAHIQEMCwsgA0HkBGogATYCACADQeAEaiAGNgIAIANB6ARqIgUgAykD+AQ3AwAgA0HwBGogBCgCADYCACADIAI2AtwEIAMgBzYC2AQgA0GYAmogChB5IAMtAJgCQQFxDQEgA0HYBGoQHEEEIQEMCgsgA0HUAmooAgAhCCADQdACaigCACEFIAMoAswCIQcMAQsgAy0AmQJB/QBHBEAgA0HYBGoQHEELIQEMCQsgChBzIANByARqIAVBCGooAgA2AgAgAyAFKQIANwPABEEBDAQLIAQEQCABEMABCyACRSAMRSABQRRHcnJFBEAgBBDAAQsgCwRAIAghAiAFIQQgByEBDAgLIANBqAJqIAoQeSADLQCoAkEBcQ0CIAUNAQtBBCEBDAYLIAcQwAFBBCEBDAULIAMtAKkCQf0ARwRAQQshASAFRQ0FIAcQwAEMBQsgChBzIAghBiAFIQJBAAshCiADQaAEaiIFIAE2AgAgA0GcBGogBjYCACADQZgEaiACNgIAIANBpARqIAMpA8AENwIAIANBrARqIANByARqKAIANgIAIAMgByIENgKUBCADIAo2ApAEIANBkAJqIA0QeSADLQCQAkEBcUUNASADLQCRAkH9AEcEQAJAIApFBEAgAkUNASAHEMABQQshAQwGCyADQZAEakEEchAcC0ELIQEMBAsgDRBzIANBiARqIAVBCGopAgA3AwAgAyAFKQIANwOABEEACyEIIANB2ANqIg0gBjYCACADQdQDaiACNgIAIANB0ANqIAQ2AgAgA0HcA2ogAykDgAQ3AgAgA0HkA2ogA0GIBGopAwA3AgAgAyAKNgLMAyADIAg2AsgDIANByAJqIANBuANqEHQgA0HUAmohByADQdACaiELIAMoAsgCIgFBFkcEQCAHKAIAIQYgCygCACECIAMoAswCIQQgA0HIA2oQSQwDCyADQfgCaiANQQhqKQIAIhE3AwAgA0GAA2ogDUEQaigCACIFNgIAIAsgCjYCACAHIAQ2AgAgA0HYAmogAjYCACADQdwCaiANKQIAIhI3AgAgA0HkAmogETcCACADQewCaiIBIAU2AgAgAyASNwPwAiADIAg2AswCIANBADYCyAIgEARAIA8QwAELIAAgAykCzAI3AgAgAEEgaiABKAIANgIAIABBGGogA0HkAmopAgA3AgAgAEEQaiADQdwCaikCADcCACAAQQhqIANB1AJqKQIANwIADAMLIApFBEAgAkUNASAHEMABQQQhAQwCCyADQZAEakEEchAcC0EEIQELIANB1ANqIAY2AgAgA0HQA2ogAjYCACADIAQ2AswDIAMgATYCyANBpgFBARBAIgFFDQEgAUHPkcAAQaYBEI4CIQUgAyADQcgDajYCiAUgA0EANgKYBCADQgE3A5AEIANBHjYC/AQgAyADQYgFajYC+AQgAyADQZAEajYC2AQgA0HcAmpBATYCACADQgE3AswCIANBkJHAADYCyAIgAyADQfgEajYC2AIgA0HYBGpB+JLAACADQcgCahDVAQ0CIAMoApQEIgEgAygCmAQiAkcEQCABIAJJDQQCQCACRQRAIAEEQCADKAKQBBDAAQsgA0EBNgKQBEEAIQIMAQsgAygCkAQgAUEBIAIQQSIBRQ0GIAMgATYCkAQLIAMgAjYClAQLIANB4ARqIgIgA0GYBGooAgA2AgAgAyADKQOQBDcD2AQQjgEhBAJAIAMoAsgDQRRHDQAgAygC0ANFDQAgAygCzAMQwAELIANBqANqIgEgAigCADYCACADQZgDaiADQbADaigCADYCACADQZADaiABKQMAIhE3AwAgA0HUAmoiAkKmgYCA4BQ3AgAgA0HQAmogBTYCACADQdwCaiADKQPYBCISNwIAIANB5AJqIgEgET4CACADIBI3A4gDIAMgBEEIdEEFcjYCzAIgA0EBNgLIAiAQBEAgDxDAAQsgAEKAgICAEDcCACAAQQhqIAMpAswCNwIAIABBEGogAikCADcCACAAQRhqIANB3AJqKQIANwIAIABBIGogASgCADYCAAsgDhDAASADQaAFaiQADwtBpgFBARDHAQALQZiRwABBNyADQcgCakGQk8AAEN8BAAtB3JTAAEEkQcyUwAAQzQEACyACQQEQxwEAC5FvAQ9/IwBB8AVrIgIkACACQagFaiABEFUgAkG0BWooAgAhAyACQbAFaigCACEJIAIoAqwFIQQgAi0AqQUhBgJAAkAgAAJ/AkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAi0AqAUiBUEBTQRAIAVBAWsNAgwBCyADRSAE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IAIgBBDPAQALQaCwwABBHEGAssAAEM0BAAsgBEEBagwBCyAKDQMgAwshBCABIAQ2AgggByAESw0ACwsgAEKBgICAMDcCAAwFC0GgsMAAQRxBgLLAABDNAQALQQwhBiALQQFxDQFBESEGIA1BAUYNAQsgCEEQaiAFIAQQ5AEgCCgCEEEBRw0BIAEEQCAFEMABCyAAQoGAgIDwATcCACAAQQhqIAgpAhA3AgAgAEEQaiAIQRhqKAIANgIADAILIABBATYCACAAIAY2AgQgAUUNASAFEMABDAELIAAgBTYCBCAAQQA2AgAgAEEMaiAENgIAIABBCGogATYCAAsgCEEgaiQADwsQbAALIAJBARDHAQALcwEGfwJAIAEoAgQiBCABKAIIIgJNDQAgASgCACEFA0AgAiAFai0AACIGQXdqIgdBF0sEQEEBIQMMAgtBASAHdEGTgIAEcUUEQEEBIQMMAgsgASACQQFqIgI2AgggBCACSw0ACwsgACAGOgABIAAgAzoAAAs4AQF/An9BACABKAIEIAEoAggiAk0NABogASgCACACai0AACECQQELIQEgACACOgABIAAgAToAAAuyAQEDfwJAAkACQCABKAIIIgIgAUEEaigCAEcEQCABKAIAIQQMAQsgAkEBaiIDIAJJDQIgAkEBdCIEIAMgBCADSxsiA0EASA0CAn8gAkUEQCADQQEQQAwBCyABKAIAIAJBASADEEELIgRFDQEgASAENgIAIAFBBGogAzYCACABKAIIIQILIAIgBGpB3QA6AAAgAEEDNgIAIAEgASgCCEEBajYCCA8LIANBARDHAQALEMgBAAuyAQECfwJAAkACQCABKAIIIgIgAUEEaigCAEcEQCABKAIAIQMMAQsgAkEBaiIDIAJJDQIgAkEBdCIEIAMgBCADSxsiBEEASA0CAn8gAkUEQCAEQQEQQAwBCyABKAIAIAJBASAEEEELIgNFDQEgASADNgIAIAFBBGogBDYCACABKAIIIQILIAIgA2pB/QA6AAAgAEEDNgIAIAEgASgCCEEBajYCCA8LIARBARDHAQALEMgBAAvOAgECfwJAAkACQAJAIAEoAggiAiABQQRqKAIARwRAIAEoAgAhAwwBCyACQQFqIgMgAkkNAyACQQF0IgQgAyAEIANLGyIEQQBIDQMCfyACRQRAIARBARBADAELIAEo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ACAAQQhqQQE6AAAgACABNgIEIABBADYCACABIAEoAghBAWo2AggPCyADQQEQxwEACxDIAQAL8wQBBH8jAEEQayIGJAACQAJAAkACQAJAAkAgASgCCCIEIAFBBGooAgBHBEAgASgCACEFDAELIARBAWoiBSAESQ0EIARBAXQiByAFIAcgBUsbIgdBAEgNBAJ/IARFBEAgB0EBEEAMAQsgASgCACAEQQEgBxBBCyIFRQ0BIAEgBTYCACABQQRqIAc2AgAgASgCCCEECyAEIAVqQfsAOgAAQQEhBCABIAEoAghBAWo2AgggBiABIAIgAxCBASAGKAIAIgJBA0cEQCAGQQxqKAIAIQEgBkEIaigCACEDIAYoAgQhBSAAIAI2AgQgAEEQaiABNgIAIABBDGogAzYCACAAQQhqIAU2AgAMBQsCQCABKAIIIgQgAUEEaigCAEcEQCABKAIAIQUMAQsgBEEBaiICIARJDQQgBEEBdCIDIAIgAyACSxsiAkEASA0EAn8gBEUEQCACQQEQQAwBCyABKAIAIARBASACEEELIgVFDQIgASAFNgIAIAFBBGogAjYCACABKAIIIQQLIAQgBWpBOjoAACABIAEoAghBAWoiBDYCCAJAIAFBBGooAgAgBEcEQCABKAIAIQUMAQsgBEEBaiICIARJDQQgBEEBdCIDIAIgAyACSxsiAkEASA0EAn8gBEUEQCACQQEQQAwBCyABKAIAIARBASACEEELIgVFDQMgASAFNgIAIAFBBGogAjYCACABKAIIIQQLIAQgBWpB+wA6AAAgACABNgIEIABBCGpBAToAACABIAEoAghBAWo2AghBACEEDAQLIAdBARDHAQALIAJBARDHAQALIAJBARDHAQALEMgBAAsgACAENgIAIAZBEGokAAucEAIJfwN+AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQEEAIAFBZmoiBiAGIAFLGyIHBEADQCAJQRpqIgggCUkiBg0CIAYNByAIIAFLDQggC0EgaiIIIAtJIgYNAyAGDQkgCCADSw0KIAIgC2oiBSAEIAAgCWoiDCkAACIOQjiGIg9COoinai0AADoAACAFQQFqIAQgDyAOQiiGQoCAgICAgMD/AIOEIg9CNIinQT9xai0AADoAACAFQQJqIAQgDyAOQhiGQoCAgICA4D+DIA5CCIZCgICA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AyAEQQEQxwEACyACQQEQxwEACxDIAQALQeTIwABBJEHUyMAAEM0BAAsgACAENgIEIAAgATYCAAv0AQEDfyMAQRBrIgIkACAAKAIAQRhqIgMoAgAhASADQQI2AgACQAJAAkACQCABQQJNBEAgAUEBaw0CDAELQZzLwABBHEGMy8AAEJoBAAsgACgCACIDQRxqIgEoAgAiAC0AAA0BIABBAToAAEEAIQACQEGQhsEAKAIAQQFGBEBBlIbBACgCACEADAELQZCGwQBCATcDAAtBlIbBACAANgIAIANBIGotAAANAiABKAIAQQA6AAALIAJBEGokAA8LQcTPwABBIEG0z8AAEJoBAAsgAiABNgIIIAIgAEEARzoADEH4x8AAQSsgAkEIakGkyMAAEN8BAAsJACAAQQA2AgALPAECfyAAKAIIIgFB3MLAACgCAEYEfyAAKAIAIgBB2MLAACgCACICRgRAQQEPCyAAIAIgARCPAkUFQQALC7kDAQV/IwBBEGsiAyQAIANBAnIhBEGogsEAKAIAIQEDQAJAAkACQAJAAkAgASICQQNLDQACQAJAIAJBAWsOAwMCAQALQaiCwQBBAkGogsEAKAIAIgEgASACRhs2AgAgASACRw0GIANBqILBADYCACAAIAJBAUZBuMHAACgCABEBACADQQM2AgQgAxCvAQsgA0EQaiQADwsgAkEDcUECRgRAA0BBwILBACgCAEEBRwRAQcCCwQBCATcCAEHIgsEAQQA2AgALIAIhARClASEFQaiCwQAgBEGogsEAKAIAIgIgASACRhs2AgAgA0EAOgAIIAMgBTYCACADIAFBfHE2AgQgASACRgRAIAMtAAhFDQQMBQsCQCADKAIAIgFFDQAgASABKAIAIgFBf2o2AgAgAUEBRw0AIAMQpAELIAJBA3FBAkYNAAwFCwALQcTMwABBOUG0zMAAEJoBAAtBkM3AAEEqQYDNwAAQmgEACwNAEKYBIAMtAAhFDQALCyADKAIAIgJFDQAgAiACKAIAIgJBf2o2AgAgAkEBRw0AIAMQpAFBqILBACgCACEBDAELQaiCwQAoAgAhAQwACwALowIBA38jAEFAaiIBJAAgACgCACICKAIAIQMgAiAAKAIENgIAIAEgA0EDcSIANgIMIABBAkYEQAJAIANBfHEiAARAA0AgACgCBCAAKAIAIQIgAEEA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AAtBAAwECyAFQQQQzgEACyABIAJBACAEENEBAAsgASACIAQgAhDRAQALQQELIANBMGokAAt4AQJ/IAAtAAQhASAALQAFBEAgAUH/AXEhAiAAAn9BASACDQAaIAAoAgAiAUEcaigCACgCDCECIAEoAhghACABLQAAQQRxRQRAIABB49vAAEECIAIRAgAMAQsgAEHi28AAQQEgAhECAAsiAToABAsgAUH/AXFBAEcL5QICA38FfiMAQdAAayIDJAAgAAJ/QQEgAC0ACA0AGiAAKAIEIQUgACgCACIELQAAQQRxRQRAQQEgBCgCGEHd28AAQefbwAAgBRtBAkEBIAUbIARBHGooAgAoAgwRAgANARogASAAKAIAIAIoAgwRAAAMAQsgBUUEQEEBIAQoAhhB5dvAAEECIARBHGooAgAoAgwRAgANARogACgCACEECyADQQE6ABcgAyADQRdqNgIQIAQpAgghBiAEKQIQIQcgA0E0akG828AANgIAIAMgBCkCGDcDCCAEKQIgIQggBCkCKCEJIAMgBC0AMDoASCAEKQIAIQogAyAJNwNAIAMgCDcDOCADIAc3AyggAyAGNwMgIAMgCjcDGCADIANBCGo2AjBBASABIANBGGogAigCDBEAAA0AGiADKAIwQdvbwABBAiADKAI0KAIMEQIACzoACCAAIAAoAgRBAWo2AgQgA0HQAGokAAuWAQECfyAALQAIIQEgACgCBCICBEAgAUH/AXEhASAAAn9BASABDQAaAkAgAkEBRw0AIAAtAAlFDQAgACgCACICLQAAQQRxDQBBASACKAIYQejbwABBASACQRxqKAIAKAIMEQIADQEaCyAAKAIAIgEoAhhBlNfAAEEBIAFBHGooAgAoAgwRAgALIgE6AAgLIAFB/wFxQQBHCwsAIAAgASACEOcBCzIBAX9BASEBIAAtAAQEfyABBSAAKAIAIgAoAhhB/NvAAEEBIABBHGooAgAoAgwRAgALC+gBAQF/IwBBEGsiAiQAIAJBADYCDCAAIAJBDGoCfwJAIAFBgAFPBEAgAUGAEEkNASABQYCABEkEQCACIAFBP3FBgAFyOgAOIAIgAUEGdkE/cUGAAXI6AA0gAiABQQx2QQ9xQeABcjoADEEDDAMLIAIgAUE/cUGAAXI6AA8gAiABQRJ2QfABcjoADCACIAFBBnZBP3FBgAFy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CWohAwwECyAPQv////+PYINCgICAgMAAhAshD0EDIQQLIAIoAhggAyACKAIcKAIQEQAARQ0ACwwECyAJIA1rIAZqIQkgBiENIAYgDEcNAQsLIANFIAEgA0ZyDQAgAyABTw0CIAAgA2osAABBv39MDQILQQEhCiACKAIYIAAgA2ogASADayACKAIcKAIMEQIADQAgAigCGEEiIAIoAhwoAhARAAAhCgsgCEEgaiQAIAoPCyAAIAEgAyABENEBAAsLACACIAAgARDQAQuKAQEDfyMAQYABayIDJAAgACgCACECQQAhAANAIAAgA2pB/wBqIAJBD3EiBEEwciAEQdcAaiAEQQpJGzoAACAAQX9qIQAgAkEEdiICDQALIABBgAFqIgJBgQFPBEAgAkGAARDPAQALIAFBAUH928AAQQIgACADakGAAWpBACAAaxD2ASADQYABaiQAC9cCAQd/QQEhCQJAAkAgAkUNACABIAJBAXRqIQogAEGA/gNxQQh2IQsgAEH/AXEhDQJAA0AgAUECaiEMIAcgAS0AASICaiEIIAsgAS0AACIBRwRAIAEgC0sNAyAIIQcgDCIBIApHDQEMAwsgCCAHTwRAIAggBEsNAiADIAdqIQECQANAIAJFDQEgAkF/aiECIAEtAAAgAUEBaiEBIA1HDQALQQAhCQwFCyAIIQcgDCIBIApHDQEMAwsLIAcgCBDPAQALIAggBBDOAQALIAZFDQAgBSAGaiEDIABB//8DcSEBA0ACQCAFQQFqIQACfyAAIAUtAAAiAkEYdEEYdSIEQQBODQAaIAAgA0YNASAFLQABIARB/wBxQQh0ciECIAVBAmoLIQUgASACayIBQQBIDQIgCUEBcyEJIAMgBUcNAQwCCwtBzNTAAEErQYzVwAAQzQEACyAJQQFxC8oCAgN/BH4jAEEwayIDJAACQCACRQRAIABBADoAAUEBIQQMAQsCQCABLQAAQStGBEBBASEEIAJBf2oiAkUNASABQQFqIQELIANBKGohBAJAA0AgAkUNASABLQAAQVBqIgVBCk8EQEEBIQQgAEEBOgABDAQLIANBEGogB0IAQgoQkgIgA0EgaiAGQgBCChCSAiADQgBCACAGEJICIAMpAxggAykDCIRCAFIgBCkDACIGIAMpAxAgAykDAHx8IgggBlRyQQFGBEAgAEECOgABQQEhBAwE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ZXNyY192YWxpZGF0b3Jkc3RfdmFsaWRhdG9yd2l0aGRyYXd2YWxpZGF0b3JyZWNpcGllbnR1bmRlbGVnYXRlZGVsZWdhdGVJbml0UmVzcG9uc2Vsb2dMb2dBdHRyaWJ1dGVrZXl2YWx1ZUhhbmRsZVJlc3BvbnNlQ29pbmRlbm9tQmFua1F1ZXJ5YWxsX2JhbGFuY2VzYWRkcmVzc2JhbGFuY2VXYXNtUXVlcnlyYXdzbWFydFN0YWtpbmdRdWVyeXZhbGlkYXRvcnNkZWxlZ2F0aW9uc2RlbGVnYXRvcmJvbmRlZF9kZW5vbUFsbEJhbGFuY2VSZXNwb25zZWJsb2NrbWVzc2FnZWNvbnRyYWN0aGVpZ2h0dGltZWNoYWluX2lkc2VuZGVyc2VudF9mdW5kc1N0ZEVycm9ydW5kZXJmbG93bWludWVuZHN1YnRyYWhlbmR1bmF1dGhvcml6ZWRzZXJpYWxpemVfZXJyc291cmNlcGFyc2VfZXJydGFyZ2V0bnVsbF9wb2ludGVybm90X2ZvdW5ka2luZGludmFsaWRfdXRmOGludmFsaWRfYmFzZTY0Z2VuZXJpY19lcnJTZXJpYWxpemluZyBRdWVyeVJlcXVlc3Q6IABFAhAAGgAAAFF1ZXJpZXIgc3lzdGVtIGVycm9yOiAAAGgCEAAWAAAACwAAAAgAAAAEAAAADAAAAA0AAACcAhAAAAAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHljb3Ntd2FzbV9zdGQ6OnR5cGVzOjpFbnZoYWNrYXRvbTo6Y29udHJhY3Q6OkluaXRNc2djb3JlOjpyZXN1bHQ6OlJlc3VsdDxjb3Ntd2FzbV9zdGQ6OmluaXRfaGFuZGxlOjpIYW5kbGVSZXNwb25zZSwgY29zbXdhc21fc3RkOjplcnJvcnM6OnN0ZF9lcnJvcjo6U3RkRXJyb3I+Y29zbXdhc21fc3RkOjpxdWVyeTo6UXVlcnlSZXF1ZXN0PGNvc213YXNtX3N0ZDo6dHlwZXM6Ok5ldmVyPmNvcmU6OnJlc3VsdDo6UmVzdWx0PGNvc213YXNtX3N0ZDo6ZW5jb2Rpbmc6OkJpbmFyeSwgY29zbXdhc21fc3RkOjplcnJvcnM6OnN0ZF9lcnJvcjo6U3RkRXJyb3I+Y29yZTo6cmVzdWx0OjpSZXN1bHQ8Y29zbXdhc21fc3RkOjppbml0X2hhbmRsZTo6SW5pdFJlc3BvbnNlLCBjb3Ntd2FzbV9zdGQ6OmVycm9yczo6c3RkX2Vycm9yOjpTdGRFcnJvcj5oYWNrYXRvbTo6Y29udHJhY3Q6OlF1ZXJ5TXNnaGFja2F0b206OmNvbnRyYWN0OjpTdGF0ZWhhY2thdG9tOjpjb250cmFjdDo6SGFuZGxlTXNnaGFja2F0b206OmNvbnRyYWN0OjpWZXJpZmllclJlc3BvbnNlY29zbXdhc21fc3RkOjpxdWVyeTo6QWxsQmFsYW5jZVJlc3BvbnNlAAAADgAAAAQAAAAEAAAADwAAABAAAAARAAAAEgAAAAAAAAABAAAAEwAAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAFAAAABwAAAAEAAAAFQAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3c8Ojpjb3JlOjptYWNyb3M6OnBhbmljIG1hY3Jvcz4AAJwFEAAeAAAAAwAAAAoAAABUcmllZCB0byBzaHJpbmsgdG8gYSBsYXJnZXIgY2FwYWNpdHltaXNzaW5nIGZpZWxkIGBg8AUQAA8AAAD/BRAAAQAAAGR1cGxpY2F0ZSBmaWVsZCBgAAAAEAYQABEAAAD/BRAAAQAAAHVua25vd24gdmFyaWFudCBgYCwgdGhlcmUgYXJlIG5vIHZhcmlhbnRzAAAANAYQABEAAABFBhAAGAAAAGAsIGV4cGVjdGVkIDQGEAARAAAAcAYQAAwAAABFcnJPa2ludmFsaWQgVWludDEyOCAnJyAtIAAAkQYQABEAAACiBhAABAAAAGludmFsaWQgYmFzZTY0OiC4BhAAEAAAAAsAAAAIAAAABAAAABYAAABjb25maWdhY3Rpb25yZWxlYXNlZGVzdGluYXRpb25TdGF0ZXNyYy9jb250cmFjdC5ycwAAAwcQAA8AAAB/AAAACQAAAHRlc3Qua2V5AwcQAA8AAACNAAAACQAAAG11c3Qgbm90IGJlIGVtcHR5AAAAAwcQAA8AAACVAAAAEwAAAEVycm9yIGluIG1lbW9yeS5ncm93IGluc3RydWN0aW9uAwcQAA8AAACuAAAABQAAAFRoaXMgcGFnZSBpbnRlbnRpb25hbGx5IGZhdWx0ZWR2ZXJpZmllcmJlbmVmaWNpYXJ5ZnVuZGVyY3B1X2xvb3BzdG9yYWdlX2xvb3BtZW1vcnlfbG9vcGFsbG9jYXRlX2xhcmdlX21lbW9yeXBhbmljAAAA7AYQAAcAAADIBxAACAAAANAHEAAMAAAA3AcQAAsAAADnBxAAFQAAAPwHEAAFAAAAb3RoZXJfYmFsYW5jZQAAAK8HEAAIAAAANAgQAA0AAABWZXJpZmllclJlc3BvbnNlT2tFcnIAAABkCBAAAgAAAGYIEAADAAAAHwAAAAgAAAAEAAAAIAAAACEAAACQCBAAAAAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHljb3JlOjpyZXN1bHQ6OlJlc3VsdDxjb3JlOjpyZXN1bHQ6OlJlc3VsdDxjb3Ntd2FzbV9zdGQ6OmVuY29kaW5nOjpCaW5hcnksIGNvc213YXNtX3N0ZDo6ZXJyb3JzOjpzdGRfZXJyb3I6OlN0ZEVycm9yPiwgY29zbXdhc21fc3RkOjplcnJvcnM6OnN5c3RlbV9lcnJvcjo6U3lzdGVtRXJyb3I+AAAAIgAAAAQAAAAEAAAAIwAAACQAAAAlAAAAJgAAAAAAAAABAAAAEwAAACcAAAAUAAAABAAAACgAAAAvcnVzdGMvZjNlMWE5NTRkMmVhZDRlMmZjMTk3YzdkYTdkNzFlNmM2MWJhZDE5Ni9zcmMvbGliY29yZS9vcHMvYXJpdGgucnOwCRAASAAAALsCAAAzAEGQlMAAC+EFYXR0ZW1wdCB0byBhZGQgd2l0aCBvdmVyZmxvdzw6OmNvcmU6Om1hY3Jvczo6cGFuaWMgbWFjcm9zPgAALAoQAB4AAAADAAAACgAAAFRyaWVkIHRvIHNocmluayB0byBhIGxhcmdlciBjYXBhY2l0eW1pc3NpbmcgZmllbGQgYGCAChAADwAAAI8KEAABAAAAZHVwbGljYXRlIGZpZWxkIGAAAACgChAAEQAAAI8KEAABAAAAdW5rbm93biB2YXJpYW50IGBgLCB0aGVyZSBhcmUgbm8gdmFyaWFudHMAAADEChAAEQAAANUKEAAYAAAAYCwgZXhwZWN0ZWQgxAoQABEAAAAACxAADAAAAFNvbWUiAAAABAAAAAQAAAApAAAATm9uZSIAAAAEAAAABAAAACoAAAAvdXNyL2xvY2FsL2NhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTEuMC9zcmMvZGVjb2RlLnJzAAAARAsQAFUAAADHAQAAHwAAAEQLEABVAAAAzQEAAB8AAABECxAAVQAAANABAAANAAAARAsQAFUAAADWAQAAHwAAAEQLEABVAAAA2QEAAA0AAABECxAAVQAAAN8BAAAfAAAARAsQAFUAAADiAQAADQAAAEQLEABVAAAA6AEAAB8AAABECxAAVQAAAOsBAAANAAAARAsQAFUAAADxAQAAHwAAAEQLEABVAAAA9AEAAA0AAABECxAAVQAAAPoBAAAfAAAARAsQAFUAAAD9AQAADQAAAEQLEABVAAAAAwIAAB8AAABECxAAVQAAAAYCAAANAAAARAsQAFUAAABtAAAALwAAAAAAAABhdHRlbXB0IHRvIG11bHRpcGx5IHdpdGggb3ZlcmZsb3cAAABECxAAVQAAAPgAAAA3AAAARAsQAFUAAAD5AAAAPgAAAEQLEABVAAAAFgEAABEAQYCawAALlRZhdHRlbXB0IHRvIHN1YnRyYWN0IHdpdGggb3ZlcmZsb3cAAABECxAAVQAAAB8BAAApAAAARAsQAFUAAAAjAQAAKQAAAEQLEABVAAAAIwEAACgAAABECxAAVQAAACgBAAARAAAARAsQAFUAAAA5AQAAJwAAAEQLEABVAAAAPAEAAAkAAABECxAAVQAAAFsBAAApAAAARAsQAFUAAABtAQAADQAAAEQLEABVAAAAdwEAABEAAABECxAAVQAAAH8BAAAVAAAARAsQAFUAAACDAQAAMQAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGU6IAAA1A0QACoAAABJbXBvc3NpYmxlOiBtdXN0IG9ubHkgaGF2ZSAwIHRvIDggaW5wdXQgYnl0ZXMgaW4gbGFzdCBjaHVuaywgd2l0aCBubyBpbnZhbGlkIGxlbmd0aHMIDhAAVAAAAEQLEABVAAAAkgEAAA4AAABECxAAVQAAAJ0BAAANAAAARAsQAFUAAACmAQAACQAAAE92ZXJmbG93IHdoZW4gY2FsY3VsYXRpbmcgb3V0cHV0IGJ1ZmZlciBsZW5ndGhJbnZhbGlkIFVURjgvdXNyL2xvY2FsL2NhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvYmFzZTY0LTAuMTEuMC9zcmMvZW5jb2RlLnJzAM4OEABVAAAALwAAABEAAABpbnRlZ2VyIG92ZXJmbG93IHdoZW4gY2FsY3VsYXRpbmcgYnVmZmVyIHNpemV1c2l6ZSBvdmVyZmxvdyB3aGVuIGNhbGN1bGF0aW5nIGJ1ZmZlciBzaXplHwAAAAgAAAAEAAAAKwAAAGludmFsaWQgYmFzZTY0OiCcDxAAEAAAAFVuc3VwcG9ydCBxdWVyeSB0eXBlOiAAALQPEAAWAAAAVW5rbm93biBzeXN0ZW0gZXJyb3LUDxAAFAAAAE5vIHN1Y2ggY29udHJhY3Q6IAAA8A8QABIAAABDYW5ub3QgcGFyc2UgcmVxdWVzdDogAAAMEBAAFgAAAEFsbG9jYXRlZCBtZW1vcnkgdG9vIHNtYWxsIHRvIGhvbGQgdGhlIGRhdGFiYXNlIHZhbHVlIGZvciB0aGUgZ2l2ZW4ga2V5LiBZb3UgY2FuIHNwZWNpZnkgY3VzdG9tIHJlc3VsdCBidWZmZXIgbGVuZ3RocyBieSB1c2luZyBFeHRlcm5hbFN0b3JhZ2UuZ2V0X3dpdGhfcmVzdWx0X2xlbmd0aCBleHBsaWNpdGVseS5FcnJvciByZWFkaW5nIGZyb20gZGF0YWJhc2UuIEVycm9yIGNvZGU6IADeEBAAKQAAAEVycm9yIHdyaXRpbmcgdG8gZGF0YWJhc2UuIEVycm9yIGNvZGU6IAAQERAAJwAAAGNhbm9uaWNhbGl6ZV9hZGRyZXNzIHJldHVybmVkIGVycm9yaHVtYW5pemVfYWRkcmVzcyByZXR1cm5lZCBlcnJvcmdlbmVyaWNfZXJybXNnaW52YWxpZF9iYXNlNjRpbnZhbGlkX3V0Zjhub3RfZm91bmRraW5kbnVsbF9wb2ludGVycGFyc2VfZXJydGFyZ2V0c2VyaWFsaXplX2VycnNvdXJjZXVuYXV0aG9yaXplZHVuZGVyZmxvd21pbnVlbmRzdWJ0cmFoZW5kQ2Fubm90IHN1YnRyYWN0ICBmcm9tIAAAAAsSEAAQAAAAGxIQAAYAAABVbmF1dGhvcml6ZWQ0EhAADAAAAEVycm9yIHNlcmlhbGl6aW5nIHR5cGUgOiAAAABIEhAAFwAAAF8SEAACAAAARXJyb3IgcGFyc2luZyBpbnRvIHR5cGUgdBIQABgAAABfEhAAAgAAAFJlY2VpdmVkIG51bGwgcG9pbnRlciwgcmVmdXNlIHRvIHVzZZwSEAAkAAAAIG5vdCBmb3VuZAAAkAgQAAAAAADIEhAACgAAAENhbm5vdCBkZWNvZGUgVVRGOCBieXRlcyBpbnRvIHN0cmluZzogAADkEhAAJgAAAEludmFsaWQgQmFzZTY0IHN0cmluZzogABQTEAAXAAAAR2VuZXJpYyBlcnJvcjogADQTEAAPAAAATnVsbFBvaW50ZXIAghEQAAsAAACQERAADgAAAJ4REAAMAAAAqhEQAAkAAAC3ERAADAAAAMMREAAJAAAA0hEQAA0AAADlERAADAAAAPEREAAJAAAAVW5kZXJmbG93YmFja3RyYWNlAAAiAAAABAAAAAQAAAAsAAAAU2VyaWFsaXplRXJyUGFyc2VFcnJOb3RGb3VuZEludmFsaWRVdGY4SW52YWxpZEJhc2U2NEdlbmVyaWNFcnJpbnZhbGlkX3JlcXVlc3RlcnJvcm5vX3N1Y2hfY29udHJhY3RhZGRydW5rbm93bnVuc3VwcG9ydGVkX3JlcXVlc3QCFBAADwAAABYUEAAQAAAAKhQQAAcAAAAxFBAAEwAAAC8AAAAIAAAABAAAADAAAAAxAAAALwAAAAgAAAAEAAAAMgAAAIgUEAAAAAAASW52YWxpZCBKU09OSlNPTiBoYXMgYSBjb21tYSBhZnRlciB0aGUgbGFzdCB2YWx1ZSBpbiBhbiBhcnJheSBvciBtYXAuSlNPTiBoYXMgbm9uLXdoaXRlc3BhY2UgdHJhaWxpbmcgY2hhcmFjdGVycyBhZnRlciB0aGUgdmFsdWUuRm91bmQgYSBsb25lIHN1cnJvZ2F0ZSwgd2hpY2ggY2FuIGV4aXN0IGluIEpTT04gYnV0IGNhbm5vdCBiZSBlbmNvZGVkIHRvIFVURi04Lk9iamVjdCBrZXkgaXMgbm90IGEgc3RyaW5nLkludmFsaWQgdW5pY29kZSBjb2RlIHBvaW50LkludmFsaWQgdHlwZUludmFsaWQgbnVtYmVyLkludmFsaWQgZXNjYXBlIHNlcXVlbmNlLkV4cGVjdGVkIHRoaXMgY2hhcmFjdGVyIHRvIHN0YXJ0IGEgSlNPTiB2YWx1ZS5FeHBlY3RlZCB0byBwYXJzZSBlaXRoZXIgYSBgdHJ1ZWAsIGBmYWxzZWAsIG9yIGEgYG51bGxgLkV4cGVjdGVkIHRoaXMgY2hhcmFjdGVyIHRvIGJlIGVpdGhlciBhIGAnLCdgIG9yIGEgYCd9J2AuRXhwZWN0ZWQgYSBsb3cgc3Vycm9nYXRlIChEQzAw4oCTREZGRikuRXhwZWN0ZWQgdGhpcyBjaGFyYWN0ZXIgdG8gYmUgZWl0aGVyIGEgYCcsJ2Agb3JhIGAnXSdgLkV4cGVjdGVkIGEgaGlnaCBzdXJyb2dhdGUgKEQ4MDDigJNEQkZGKS5FeHBlY3RlZCB0aGlzIGNoYXJhY3RlciB0byBiZSBhIGAnOidgLkVPRiB3aGlsZSBwYXJzaW5nIGEgSlNPTiB2YWx1ZS5FT0Ygd2hpbGUgcGFyc2luZyBhIHN0cmluZy5FT0Ygd2hpbGUgcGFyc2luZyBhbiBvYmplY3QuRU9GIHdoaWxlIHBhcnNpbmcgYSBsaXN0LkNvbnRyb2wgY2hhcmFjdGVyIGZvdW5kIGluIHN0cmluZy4vdXNyL2xvY2FsL2NhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvc2VyZGUtanNvbi13YXNtLTAuMi4xL3NyYy9kZS91bmVzY2FwZS5ycwAApBcQAGIAAAAlAAAAFQBBoLDAAAvxA2F0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3ekFxAAYgAAADMAAAApAAAAAAAAAGF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvdwAAAKQXEABiAAAAmQAAAA4AAABOb24taGV4IEFTQ0lJIGNoYXJhY3RlciBmb3VuZC91c3IvbG9jYWwvY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zZXJkZS1qc29uLXdhc20tMC4yLjEvc3JjL2RlL21vZC5ycwAAoRgQAF0AAAAeAAAACQAAAKEYEABdAAAAewAAACsAAAChGBAAXQAAAHsAAAAgAAAAoRgQAF0AAAB8AAAAIQAAAFVua25vd24gc2VyaWFsaXphdGlvbiBlcnJvcgBAGRAAGwAAAEJ1ZmZlciBpcyBmdWxsAABkGRAADgAAAC91c3IvbG9jYWwvY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9zZXJkZS1qc29uLXdhc20tMC4yLjEvc3JjL3Nlci9tb2QucnMAAHwZEABeAAAA0QAAAAkAAAAAAAAAYXR0ZW1wdCB0byBzdWJ0cmFjdCB3aXRoIG92ZXJmbG93AEGgtMAAC4skYXR0ZW1wdCB0byBhZGQgd2l0aCBvdmVyZmxvd3VzaXplIG92ZXJmbG93IHdoZW4gY2FsY3VsYXRpbmcgYjY0IGxlbmd0aC91c3IvbG9jYWwvY2FyZ28vcmVnaXN0cnkvc3JjL2dpdGh1Yi5jb20tMWVjYzYyOTlkYjllYzgyMy9iYXNlNjQtMC4xMS4wL3NyYy9lbmNvZGUucnMAZhoQAFUAAAC7AAAAMwAAAGYaEABVAAAAvAAAADoAAABmGhAAVQAAAPwAAAAYAAAAZhoQAFUAAAABAQAALwAAAGYaEABVAAAAAgEAADYAAABmGhAAVQAAABABAAAuAAAAZhoQAFUAAAAQAQAACQAAAGYaEABVAAAAEgEAAA8AAABmGhAAVQAAABEBAAAJAAAAZhoQAFUAAAAUAQAACQAAAGYaEABVAAAAFgEAAAkAAABmGhAAVQAAABgBAAAuAAAAZhoQAFUAAAAYAQAACQAAAGYaEABVAAAAGQEAAAkAAABpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlOiAAAJwbEAAqAAAASW1wb3NzaWJsZSByZW1haW5kZXLQGxAAFAAAAGYaEABVAAAALwEAABYAAABmGhAAVQAAAEABAAAJAAAASW52YWxpZCBsYXN0IHN5bWJvbCAsIG9mZnNldCAuAAAMHBAAFAAAACAcEAAJAAAAKRwQAAEAAABFbmNvZGVkIHRleHQgY2Fubm90IGhhdmUgYSA2LWJpdCByZW1haW5kZXIuAEQcEAArAAAASW52YWxpZCBieXRlIAAAAHgcEAANAAAAIBwQAAkAAAApHBAAAQAAAE92ZXJmbG93IHdoZW4gY2FsY3VsYXRpbmcgbnVtYmVyIG9mIGNodW5rcyBpbiBpbnB1dC4vMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OS1fQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL/////////////////////////////////////////////////////////////8AAQIDBAUGBwgJCgv/////////DA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCX///////8mJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8+//80NTY3ODk6Ozw9/////////wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ/////z//GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z7///8/NDU2Nzg5Ojs8Pf////////8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGf///////xobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIz/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBTHRAAEx0QANMcEACTHxAAkx4QAJMdEAA2AAAABAAAAAQAAAA3AAAAOAAAACgpL3J1c3RjL2YzZTFhOTU0ZDJlYWQ0ZTJmYzE5N2M3ZGE3ZDcxZTZjNjFiYWQxOTYvc3JjL2xpYmNvcmUvbWFjcm9zL21vZC5ycwDCIBAASQAAAA8AAAAoAAAAY2FsbGVkIGBPcHRpb246OnVud3JhcCgpYCBvbiBhIGBOb25lYCB2YWx1ZVJVU1RfQkFDS1RSQUNFMQAAVSEQAAEAAABSVVNUX0xJQl9CQUNLVFJBQ0VCYWNrdHJhY2UANgAAAAQAAAAEAAAAOQAAADwAAAAIAAAABAAAAD0AAAA+AAAAPAAAAAgAAAAEAAAAPwAAAGBvbmUgb2YgsSEQAAcAAAAsIAAAwCEQAAIAAACwIRAAAQAAALAhEAABAAAAYCBvciBgAACwIRAAAQAAANwhEAAGAAAAsCEQAAEAAAAvdXNyL2xvY2FsL2NhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvc2VyZGUtMS4wLjEwNC9zcmMvZGUvbW9kLnJzAAAA/CEQAFUAAADVCAAAEgAAAGV4cGxpY2l0IHBhbmljAABDAAAABAAAAAQAAABEAAAARQAAAEYAAABDAAAABAAAAAQAAABHAAAAYWxyZWFkeSBib3Jyb3dlZGFscmVhZHkgbXV0YWJseSBib3Jyb3dlZC9ydXN0Yy9mM2UxYTk1NGQyZWFkNGUyZmMxOTdjN2RhN2Q3MWU2YzYxYmFkMTk2L3NyYy9saWJjb3JlL21hY3Jvcy9tb2QucnNhc3NlcnRpb24gZmFpbGVkOiBgKGxlZnQgPT0gcmlnaHQpYAogIGxlZnQ6IGBgLAogcmlnaHQ6IGBgAA0jEAAtAAAAOiMQAAwAAABGIxAAAQAAAMQiEABJAAAADwAAACgAAABIAAAAAAAAAAEAAABJAAAAYDogAA0jEAAtAAAAOiMQAAwAAACAIxAAAwAAAGNhbGxlZCBgT3B0aW9uOjp1bndyYXAoKWAgb24gYSBgTm9uZWAgdmFsdWUASAAAAAAAAAABAAAASgAAAEsAAAAQAAAABAAAAEwAAABIAAAAAAAAAAEAAABNAAAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQBOAAAACAAAAAQAAABPAAAAPDo6Y29yZTo6bWFjcm9zOjpwYW5pYyBtYWNyb3M+AAA0JBAAHgAAAAMAAAAKAAAAVHJpZWQgdG8gc2hyaW5rIHRvIGEgbGFyZ2VyIGNhcGFjaXR5QwAAAAQAAAAEAAAAQQAAAHNyYy9saWJzdGQvdGhyZWFkL21vZC5yc5gkEAAYAAAAiQMAABMAAABpbmNvbnNpc3RlbnQgcGFyayBzdGF0ZQACAAAAcGFyayBzdGF0ZSBjaGFuZ2VkIHVuZXhwZWN0ZWRseQDcJBAAHwAAAJgkEAAYAAAAhgMAAA0AAACYJBAAGAAAAB8EAAARAAAAZmFpbGVkIHRvIGdlbmVyYXRlIHVuaXF1ZSB0aHJlYWQgSUQ6IGJpdHNwYWNlIGV4aGF1c3RlZHRocmVhZCBuYW1lIG1heSBub3QgY29udGFpbiBpbnRlcmlvciBudWxsIGJ5dGVzAACYJBAAGAAAAJQEAAASAAAAaW5jb25zaXN0ZW50IHN0YXRlIGluIHVucGFya3NyYy9saWJzdGQvc3luYy9jb25kdmFyLnJzAAC4JRAAGgAAAEgCAAASAAAAYXR0ZW1wdGVkIHRvIHVzZSBhIGNvbmRpdGlvbiB2YXJpYWJsZSB3aXRoIHR3byBtdXRleGVzc3JjL2xpYnN0ZC9zeW5jL29uY2UucnMAAAAaJhAAFwAAAKgBAAAVAAAAYXNzZXJ0aW9uIGZhaWxlZDogc3RhdGVfYW5kX3F1ZXVlICYgU1RBVEVfTUFTSyA9PSBSVU5OSU5HAAAAGiYQABcAAACMAQAAFQAAAE9uY2UgaW5zdGFuY2UgaGFzIHByZXZpb3VzbHkgYmVlbiBwb2lzb25lZAAAGiYQABcAAADpAQAACQAAAFBvaXNvbkVycm9yIHsgaW5uZXI6IC4uIH0AAABQAAAAEAAAAAQAAABRAAAAUgAAAFMAAAAMAAAABAAAAFQAAABVAAAACAAAAAQAAABWAAAAVwAAAFUAAAAIAAAABAAAAFgAAABOdWxFcnJvckMAAAAEAAAABAAAAFkAAABzcmMvbGlic3RkL3N5cy93YXNtL2NvbmR2YXIucnMAAEgnEAAeAAAAFwAAAAkAAABjYW4ndCBibG9jayB3aXRoIHdlYiBhc3NlbWJseXNyYy9saWJzdGQvc3lzL3dhc20vbXV0ZXgucnMAAACVJxAAHAAAABYAAAAJAAAAY2Fubm90IHJlY3Vyc2l2ZWx5IGFjcXVpcmUgbXV0ZXhaAAAABAAAAAQAAABbAAAAXAAAAF0AAABaAAAABAAAAAQAAABeAAAAL3J1c3RjL2YzZTFhOTU0ZDJlYWQ0ZTJmYzE5N2M3ZGE3ZDcxZTZjNjFiYWQxOTYvc3JjL2xpYmNvcmUvZm10L21vZC5ycwAADCgQAEYAAABaAQAAEwAAAF8AAAAAAAAAAQAAABMAAABzcmMvbGliYWxsb2MvcmF3X3ZlYy5yc2NhcGFjaXR5IG92ZXJmbG93dCgQABcAAAAJAwAABQAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvckZyb21VdGY4RXJyb3JieXRlcwAAAFoAAAAEAAAABAAAAGAAAABlcnJvcgAAAFoAAAAEAAAABAAAAGEAAABgbnVtYmVyIHdvdWxkIGJlIHplcm8gZm9yIG5vbi16ZXJvIHR5cGVudW1iZXIgdG9vIHNtYWxsIHRvIGZpdCBpbiB0YXJnZXQgdHlwZW51bWJlciB0b28gbGFyZ2UgdG8gZml0IGluIHRhcmdldCB0eXBlaW52YWxpZCBkaWdpdCBmb3VuZCBpbiBzdHJpbmdjYW5ub3QgcGFyc2UgaW50ZWdlciBmcm9tIGVtcHR5IHN0cmluZy4u0ikQAAIAAABCb3Jyb3dFcnJvckJvcnJvd011dEVycm9yAAAAZwAAAAAAAAABAAAAaAAAAGluZGV4IG91dCBvZiBib3VuZHM6IHRoZSBsZW4gaXMgIGJ1dCB0aGUgaW5kZXggaXMgAAAIKhAAIAAAACgqEAASAAAAY2FsbGVkIGBPcHRpb246OnVud3JhcCgpYCBvbiBhIGBOb25lYCB2YWx1ZXNyYy9saWJjb3JlL29wdGlvbi5yc3cqEAAVAAAAfQEAABUAAAAcKRAAAAAAAHcqEAAVAAAApAQAAAUAAAA6IAAAHCkQAAAAAAC0KhAAAgAAAHNyYy9saWJjb3JlL3Jlc3VsdC5ycwAAAMgqEAAVAAAApAQAAAUAAABzcmMvbGliY29yZS9zbGljZS9tb2QucnNpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggCCsQAAYAAAAOKxAAIgAAAPAqEAAYAAAAcgoAAAUAAABzbGljZSBpbmRleCBzdGFydHMgYXQgIGJ1dCBlbmRzIGF0IABQKxAAFgAAAGYrEAANAAAA8CoQABgAAAB4CgAABQAAAClzcmMvbGliY29yZS9zdHIvbW9kLnJzAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQe3YwAALMwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMDAwMDAwMDAwMDAwMDAwMEBAQEBABBq9nAAAuhEFsuLi5dYnl0ZSBpbmRleCAgaXMgb3V0IG9mIGJvdW5kcyBvZiBgAAAAsCwQAAsAAAC7LBAAFgAAABwpEAABAAAAlSsQABYAAAAECAAACQAAAGJlZ2luIDw9IGVuZCAoIDw9ICkgd2hlbiBzbGljaW5nIGAAAPwsEAAOAAAACi0QAAQAAAAOLRAAEAAAABwpEAABAAAAlSsQABYAAAAICAAABQAAACBpcyBub3QgYSBjaGFyIGJvdW5kYXJ5OyBpdCBpcyBpbnNpZGUgIChieXRlcyApIG9mIGCwLBAACwAAAFAtEAAmAAAAdi0QAAgAAAB+LRAABgAAABwpEAABAAAAlSsQABYAAAAVCAAABQAAAGkAAAAMAAAABAAAAGoAAABrAAAAbAAAACAgICAgewosCiwgIHsgfSB9KAooLApbAG0AAAAEAAAABAAAAG4AAABdMHgwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OQBtAAAABAAAAAQAAABvAAAAcAAAAHEAAABzcmMvbGliY29yZS9mbXQvbW9kLnJzAADgLhAAFgAAAFMEAAAoAAAA4C4QABYAAABeBAAAKAAAAHNyYy9saWJjb3JlL3VuaWNvZGUvYm9vbF90cmllLnJzGC8QACAAAAAnAAAAGQAAABgvEAAgAAAAKAAAACAAAAAYLxAAIAAAACoAAAAZAAAAGC8QACAAAAArAAAAGAAAABgvEAAgAAAALAAAACAAAAAAAQMFBQYGAwcGCAgJEQocCxkMFA0SDg0PBBADEhITCRYBFwUYAhkDGgccAh0BHxYgAysELAItCy4BMAMxAjIBpwKpAqoEqwj6AvsF/QT+A/8JrXh5i42iMFdYi4yQHB3dDg9LTPv8Li8/XF1fteKEjY6RkqmxurvFxsnK3uTl/wAEERIpMTQ3Ojs9SUpdhI6SqbG0urvGys7P5OUABA0OERIpMTQ6O0VGSUpeZGWEkZudyc7PDREpRUlXZGWNkam0urvFyd/k5fAEDRFFSWRlgIGEsry+v9XX8PGDhYukpr6/xcfOz9rbSJi9zcbOz0lOT1dZXl+Jjo+xtre/wcbH1xEWF1tc9vf+/4ANbXHe3w4PH25vHB1ffX6ur7u8+hYXHh9GR05PWFpcXn5/tcXU1dzw8fVyc490dZaXL18mLi+nr7e/x8/X35pAl5gwjx/Awc7/Tk9aWwcIDxAnL+7vbm83PT9CRZCR/v9TZ3XIydDR2Nnn/v8AIF8igt8EgkQIGwQGEYGsDoCrNR4VgOADGQgBBC8ENAQHAwEHBgcRClAPEgdVCAIEHAoJAwgDBwMCAwMDDAQFAwsGAQ4VBToDEQcGBRAHVwcCBxUNUARDAy0DAQQRBg8MOgQdJV8gbQRqJYDIBYKwAxoGgv0DWQcVCxcJFAwUDGoGCgYaBlkHKwVGCiwEDAQBAzELLAQaBgsDgKwGCgYfQUwELQN0CDwDDwM8BzgIKwWC/xEYCC8RLQMgECEPgIwEgpcZCxWIlAUvBTsHAg4YCYCwMHQMgNYaDAWA/wWAtgUkDJvGCtIwEISNAzcJgVwUgLgIgMcwNQQKBjgIRggMBnQLHgNaBFkJgIMYHAoWCUgIgIoGq6QMFwQxoQSB2iYHDAUFgKURgW0QeCgqBkwEgI0EgL4DGwMPDQAGAQEDAQQCCAgJAgoFCwIQAREEEgUTERQCFQIXAhkEHAUdCCQBagNrArwC0QLUDNUJ1gLXAtoB4AXhAugC7iDwBPkG+gIMJzs+Tk+Pnp6fBgcJNj0+VvPQ0QQUGDY3Vle9Nc7P4BKHiY6eBA0OERIpMTQ6RUZJSk5PZGVaXLa3GxyoqdjZCTeQkagHCjs+ZmmPkm9f7u9aYpqbJyhVnaCho6SnqK26vMQGCwwVHTo/RVGmp8zNoAcZGiIlPj/FxgQgIyUmKDM4OkhKTFBTVVZYWlxeYGNlZmtzeH1/iqSqr7DA0Axyo6TLzG5vXiJ7BQMELQNlBAEvLoCCHQMxDxwEJAkeBSsFRAQOKoCqBiQEJAQoCDQLAYCQgTcJFgoIgJg5A2MICTAWBSEDGwUBQDgESwUvBAoHCQdAICcEDAk2AzoFGgcEDAdQSTczDTMHLggKgSYfgIEoCCqAhhcJTgQeD0MOGQcKBkcJJwl1Cz9BKgY7BQoGUQYBBRADBYCLYCBICAqApl4iRQsKBg0TOQcKNiwEEIDAPGRTDAGAoEUbSAhTHTmBB0YKHQNHSTcDDggKBjkHCoE2GYDHMg2Dm2Z1C4DEiryEL4/RgkehuYI5ByoEAmAmCkYKKAUTgrBbZUsEOQcRQAQcl/gIgvOlDYEfMQMRBAiBjIkEawUNAwkHEJNggPYKcwhuF0aAmhQMVwkZgIeBRwOFQg8VhVArgNUtAxoEAoFwOgUBhQCA1ylMBAoEAoMRREw9gMI8BgEEVQUbNAKBDiwEZAxWCg0DXQM9OR0NLAQJBwIOBoCag9YKDQMLBXQMWQcMFAwEOAgKBigIHlJ3AzEDgKYMFAQDBQMNBoVqAAAAAADA++8+AAAAAAAOAEHa6cAAC5IB+P/7////BwAAAAAAABT+If4ADAAAAAIAAAAAAABQHiCAAAwAAEAGAAAAAAAAEIY5AgAAACMAviEAAAwAAPwCAAAAAAAA0B4gwAAMAAAABAAAAAAAAEABIIAAAAAAABEAAAAAAADAwT1gAAwAAAACAAAAAAAAkEQwYAAMAAAAAwAAAAAAAFgeIIAADAAAAACEXIAAQfbqwAALBPIHgH8AQYbrwAALBPIfAD8AQZPrwAALFgMAAKACAAAAAAAA/n/f4P/+////H0AAQbXrwAAL1wHg/WYAAADDAQAeAGQgACAAAAAAAAAA4AAAAAAAABwAAAAcAAAADAAAAAwAAAAAAAAAsD9A/g8gAAAAAAA4AAAAAAAAYAAAAAACAAAAAAAAhwEEDgAAgAkAAAAAAABAf+Uf+J8AAAAAAAD/fw8AAAAAAPAXBAAAAAD4DwADAAAAPDsAAAAAAABAowMAAAAAAADwzwAAAPf//SEQA//////////7ABAAAAAAAAAAAP////8BAAAAAAAAgAMAAAAAAAAAAIAAAAAA/////wAAAAAA/AAAAAAABgBBle3AAAsHgPc/AAAAwABBpu3AAAtoAwBECAAAYAAAADAAAAD//wOAAAAAAMA/AACA/wMAAAAAAAcAAAAAAMgzAAAAACAAAAAAAAAAAH5mAAgQAAAAAAAQAAAAAAAAncECAAAAADBAAAAAAAAgIQAAAAAAQAAAAAD//wAA//8AQZfuwAALBwEAAAACAAMAQbjuwAALVAQAAAUAAAAAAAAAAAYAAAAAAAAAAAcAAAgJCgALDA0ODwAAEBESAAATFBUWAAAXGBkaGwAcAAAAHQAAAAAAAB4fICEAAAAAACIAIwAkJSYAAAAAJwBB++/AAAsCKCkAQY3wwAALAiorAEHC8MAACwEsAEHV8MAACwUtLgAALwBB+PDAAAsDMDEyAEGQ8cAACwwzAAAAKQAAAAAAADQAQbPxwAALAzUANgBB0PHAAAsINzgAADg4ODkAQZ/ywAALBiAAAAAAAQBBrvLAAAtUwAdu8AAAAAAAhwAAAABgAAAAAAAAAPAAAADA/wEAAAAAAAIAAAAAAAD/fwAAAAAAAIADAAAAAAB4BgcAAACA7x8AAAAAAAAACAADAAAAAADAfwAeAEGN88AACyeA00AAAACA+AcAAAMAAAAAAABYAQCAAMAfHwAAAAAAAAAA/1wAAEAAQb7zwAALA/mlDQBBzfPAAAsHgDywAQAAMABB3vPAAAsD+KcBAEHt88AACy8ovwAAAADgvA8AAAAAAAAAgP8GAADwDAEAAAD+BwAAAAD4eYAAfg4AAAAAAPx/AwBBpvTAAAsTf78AAPz///xtAAAAAAAAAH60vwBBwvTAAAsBowBBzvTAAAt0GAAAAAAAAAAfAAAAAAAAAH8AAIAAAAAAAAAAgAcAAAAAAAAAAGAAAAAAAAAAAKDDB/jnDwAAADwAABwAAAAAAAAA////////f/j//////x8gABAAAPj+/wAAf///+dsHAAAAAAAAAPAAAAAAfwAAAAAA8AcAQcz1wAALEv///////////////////////wBBwPbAAAsO//////////////////8AQfD2wAALAvgDAEGS98AACwf+/////7+2AEGi98AACw3/BwAAAAAA+P//AAABAEG698AACxDAn589AAAAAAIAAAD///8HAEHU98AAC9EKwP8BAAAAAAAA+A8gwDQQAEoAAAAQNxAAAAIAABA5EAA6AAAAAAECAwQFBgcICQgKCwwNDg8QERITFAIVFhcYGRobHB0eHyACAgICAgICAgICIQICAgICAgICAgICAgICIiMkJSYCJwIoAgICKSorAiwtLi8wAgIxAgICMgICAgICAgICMwICNAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNQI2AjcCAgICAgICAjgCOQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICOjs8AgICAj0CAj4/QEFCQ0RFRgICAkcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICSAICAgICAgICAgICSQICAgICOwIAAQICAgIDAgICAgQCBQYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICbQAAAAQAAAAEAAAAcgAAAFNvbWVOb25lVXRmOEVycm9ydmFsaWRfdXBfdG9lcnJvcl9sZW4AAABtAAAABAAAAAQAAABzAAAARXJyb3IAQaCGwQALAQE=" -} diff --git a/packages/sdk/src/testdata/cosmoshub.json b/packages/sdk/src/testdata/cosmoshub.json deleted file mode 100644 index cb33539c..00000000 --- a/packages/sdk/src/testdata/cosmoshub.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "//source": "https://hubble.figment.network/cosmos/chains/cosmoshub-3/blocks/415777/transactions/2BD600EA6090FC75FD844CA73542CC90A828770F4C01C5B483C3C1C43CCB65F4?format=json", - "tx": { - "type": "cosmos-sdk/StdTx", - "value": { - "msg": [ - { - "type": "cosmos-sdk/MsgSend", - "value": { - "from_address": "cosmos1txqfn5jmcts0x0q7krdxj8tgf98tj0965vqlmq", - "to_address": "cosmos1nynns8ex9fq6sjjfj8k79ymkdz4sqth06xexae", - "amount": [ - { - "denom": "uatom", - "amount": "35997500" - } - ] - } - } - ], - "fee": { - "amount": [ - { - "denom": "uatom", - "amount": "2500" - } - ], - "gas": "100000" - }, - "signatures": [ - { - "pub_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A5qFcJBJvEK/fOmEAY0DHNWwSRZ9TEfNZyH8VoVvDtAq" - }, - "signature": "NK1Oy4EUGAsoC03c1wi9GG03JC/39LEdautC5Jk643oIbEPqeXHMwaqbdvO/Jws0X/NAXaN8SAy2KNY5Qml+5Q==" - } - ], - "memo": "" - } - }, - "tx_data": "ygEoKBapCkOoo2GaChRZgJnSW8Lg8zwesNppHWhJTrk8uhIUmSc4HyYqQahKSZHt4pN2aKsALu8aEQoFdWF0b20SCDM1OTk3NTAwEhMKDQoFdWF0b20SBDI1MDAQoI0GGmoKJuta6YchA5qFcJBJvEK/fOmEAY0DHNWwSRZ9TEfNZyH8VoVvDtAqEkA0rU7LgRQYCygLTdzXCL0YbTckL/f0sR1q60LkmTrjeghsQ+p5cczBqpt2878nCzRf80Bdo3xIDLYo1jlCaX7l", - "id": "2BD600EA6090FC75FD844CA73542CC90A828770F4C01C5B483C3C1C43CCB65F4" -} diff --git a/packages/sdk/src/testdata/txresponse1.json b/packages/sdk/src/testdata/txresponse1.json deleted file mode 100644 index 703ea696..00000000 --- a/packages/sdk/src/testdata/txresponse1.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "height": "15888", - "txhash": "672DEDE8EF4DE8B5818959F417CCA357079D4D7A19C4B65443C7FBF8176AABF9", - "raw_log": "[{\"msg_index\":0,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2\"},{\"key\":\"amount\",\"value\":\"75000ucosm\"}]}]}]", - "logs": [ - { - "msg_index": 0, - "log": "", - "events": [ - { - "type": "message", - "attributes": [ - { "key": "action", "value": "send" }, - { "key": "sender", "value": "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" }, - { "key": "module", "value": "bank" } - ] - }, - { - "type": "transfer", - "attributes": [ - { "key": "recipient", "value": "cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2" }, - { "key": "amount", "value": "75000ucosm" } - ] - } - ] - } - ], - "gas_wanted": "200000", - "gas_used": "65407", - "tx": { - "type": "cosmos-sdk/StdTx", - "value": { - "msg": [ - { - "type": "cosmos-sdk/MsgSend", - "value": { - "from_address": "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - "to_address": "cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2", - "amount": [{ "denom": "ucosm", "amount": "75000" }] - } - } - ], - "fee": { "amount": [{ "denom": "ucosm", "amount": "5000" }], "gas": "200000" }, - "signatures": [ - { - "pub_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" - }, - "signature": "US7oH8S/8TxVrtBQkOhHxAM+oDB2spNAEawgh6H8CCFLRMOJK+uvQZZ6ceUgUsvDbxwCz7re1RU272fymMYRZQ==" - } - ], - "memo": "My first payment" - } - }, - "timestamp": "2020-02-14T11:25:55Z" -} diff --git a/packages/sdk/src/testdata/txresponse2.json b/packages/sdk/src/testdata/txresponse2.json deleted file mode 100644 index 0d1a37f9..00000000 --- a/packages/sdk/src/testdata/txresponse2.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "height": "16456", - "txhash": "7BFE4B93AF190F60132C62D08FDF50BE462FBCE374EB13D3FD0C32461E771EC0", - "raw_log": "[{\"msg_index\":0,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2\"},{\"key\":\"amount\",\"value\":\"75000ucosm\"}]}]}]", - "logs": [ - { - "msg_index": 0, - "log": "", - "events": [ - { - "type": "message", - "attributes": [ - { "key": "action", "value": "send" }, - { "key": "sender", "value": "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" }, - { "key": "module", "value": "bank" } - ] - }, - { - "type": "transfer", - "attributes": [ - { "key": "recipient", "value": "cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2" }, - { "key": "amount", "value": "75000ucosm" } - ] - } - ] - } - ], - "gas_wanted": "200000", - "gas_used": "65407", - "tx": { - "type": "cosmos-sdk/StdTx", - "value": { - "msg": [ - { - "type": "cosmos-sdk/MsgSend", - "value": { - "from_address": "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - "to_address": "cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2", - "amount": [{ "denom": "ucosm", "amount": "75000" }] - } - } - ], - "fee": { "amount": [{ "denom": "ucosm", "amount": "5000" }], "gas": "200000" }, - "signatures": [ - { - "pub_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" - }, - "signature": "ltvd9Rb3RF4zjbUVrpDpkok34g+py7XR8ZcM0tZUYRxxVdcMEin010x+ZFd/mOuutPj9fDmSENnienc/yi4msw==" - } - ], - "memo": "My first payment" - } - }, - "timestamp": "2020-02-14T11:35:41Z" -} diff --git a/packages/sdk/src/testdata/txresponse3.json b/packages/sdk/src/testdata/txresponse3.json deleted file mode 100644 index 8ffd0727..00000000 --- a/packages/sdk/src/testdata/txresponse3.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "height": "20730", - "txhash": "625BC75E697F73DA037387C34002BB2F682E7ACDCC4E015D3E90420516C6D0C8", - "raw_log": "[{\"msg_index\":0,\"log\":\"\",\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"send\"},{\"key\":\"sender\",\"value\":\"cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6\"},{\"key\":\"module\",\"value\":\"bank\"}]},{\"type\":\"transfer\",\"attributes\":[{\"key\":\"recipient\",\"value\":\"cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2\"},{\"key\":\"amount\",\"value\":\"75000ucosm\"}]}]}]", - "logs": [ - { - "msg_index": 0, - "log": "", - "events": [ - { - "type": "message", - "attributes": [ - { "key": "action", "value": "send" }, - { "key": "sender", "value": "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6" }, - { "key": "module", "value": "bank" } - ] - }, - { - "type": "transfer", - "attributes": [ - { "key": "recipient", "value": "cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2" }, - { "key": "amount", "value": "75000ucosm" } - ] - } - ] - } - ], - "gas_wanted": "200000", - "gas_used": "65407", - "tx": { - "type": "cosmos-sdk/StdTx", - "value": { - "msg": [ - { - "type": "cosmos-sdk/MsgSend", - "value": { - "from_address": "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - "to_address": "cosmos1t70qnpr0az8tf7py83m4ue5y89w58lkjmx0yq2", - "amount": [{ "denom": "ucosm", "amount": "75000" }] - } - } - ], - "fee": { "amount": [{ "denom": "ucosm", "amount": "5000" }], "gas": "200000" }, - "signatures": [ - { - "pub_key": { - "type": "tendermint/PubKeySecp256k1", - "value": "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ" - }, - "signature": "eOFGl1tIHDMv3JdCK9fRSikVbYUD8+B0ksb3dJFya8MPYgpEpdSA7zZc+5n/cW6LR/BJdib4nqmJQv1yD9lm3g==" - } - ], - "memo": "My first payment" - } - }, - "timestamp": "2020-02-14T12:48:56Z" -} diff --git a/packages/sdk/src/testutils.spec.ts b/packages/sdk/src/testutils.spec.ts deleted file mode 100644 index 888f5954..00000000 --- a/packages/sdk/src/testutils.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Random } from "@iov/crypto"; -import { Bech32, Encoding } from "@iov/encoding"; - -import hackatom from "./testdata/contract.json"; - -export function getHackatom(): Uint8Array { - return Encoding.fromBase64(hackatom.data); -} - -export function makeRandomAddress(): string { - return Bech32.encode("cosmos", Random.getBytes(20)); -} - -export const nonNegativeIntegerMatcher = /^[0-9]+$/; -export const tendermintIdMatcher = /^[0-9A-F]{64}$/; -export const tendermintOptionalIdMatcher = /^([0-9A-F]{64}|)$/; -export const tendermintAddressMatcher = /^[0-9A-F]{40}$/; -export const tendermintShortHashMatcher = /^[0-9a-f]{40}$/; -export const semverMatcher = /^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/; - -// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 -export const bech32AddressMatcher = /^[\x21-\x7e]{1,83}1[02-9ac-hj-np-z]{38}$/; - -/** Deployed as part of scripts/wasmd/init.sh */ -export const deployedErc20 = { - codeId: 1, - source: "https://crates.io/api/v1/crates/cw-erc20/0.4.0/download", - builder: "cosmwasm/rust-optimizer:0.8.0", - checksum: "41b3bafd7f9a3870bbfb0a0620508df564c52499cdcdc67bf9df72262f3958a6", - instances: [ - "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", // HASH - "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd", // ISA - "cosmos18r5szma8hm93pvx6lwpjwyxruw27e0k5uw835c", // JADE - ], -}; - -export const wasmd = { - endpoint: "http://localhost:1317", - chainId: "testing", -}; - -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", - pubkey: { - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }, - address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", -}; - -/** Unused account */ -export const unused = { - pubkey: { - type: "tendermint/PubKeySecp256k1", - value: "ArkCaFUJ/IH+vKBmNRCdUVl3mCAhbopk9jjW4Ko4OfRQ", - }, - address: "cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u", - accountNumber: 9, - sequence: 0, -}; - -export function wasmdEnabled(): boolean { - return !!process.env.WASMD_ENABLED; -} - -export function pendingWithoutWasmd(): void { - if (!wasmdEnabled()) { - return pending("Set WASMD_ENABLED to enable Wasmd based tests"); - } -} - -/** 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]; -} diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts deleted file mode 100644 index 0ab70b02..00000000 --- a/packages/sdk/src/types.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { Encoding } from "@iov/encoding"; - -import { Coin } from "./coins"; - -const { fromBase64, fromHex } = Encoding; - -/** An Amino/Cosmos SDK StdTx */ -export interface StdTx { - readonly msg: ReadonlyArray; - readonly fee: StdFee; - readonly signatures: ReadonlyArray; - readonly memo: string | undefined; -} - -export function isStdTx(txValue: unknown): txValue is StdTx { - const { memo, msg, fee, signatures } = txValue as StdTx; - return ( - typeof memo === "string" && Array.isArray(msg) && typeof fee === "object" && Array.isArray(signatures) - ); -} - -export interface CosmosSdkTx { - readonly type: string; - readonly value: StdTx; -} - -interface MsgTemplate { - readonly type: string; - readonly value: any; -} - -/** A Cosmos SDK token transfer message */ -export interface MsgSend extends MsgTemplate { - readonly type: "cosmos-sdk/MsgSend"; - readonly value: { - /** Bech32 account address */ - readonly from_address: string; - /** Bech32 account address */ - readonly to_address: string; - readonly amount: ReadonlyArray; - }; -} - -/** - * Uploads Wam code to the chain - * - * @see https://github.com/cosmwasm/wasmd/blob/9842678d89/x/wasm/internal/types/msg.go#L17 - */ -export interface MsgStoreCode extends MsgTemplate { - readonly type: "wasm/store-code"; - readonly value: { - /** Bech32 account address */ - readonly sender: string; - /** Base64 encoded Wasm */ - readonly wasm_byte_code: string; - /** A valid URI reference to the contract's source code. Can be empty. */ - readonly source: string; - /** A docker tag. Can be empty. */ - readonly builder: string; - }; -} - -/** - * Creates an instance of contract that was uploaded before. - * - * @see https://github.com/cosmwasm/wasmd/blob/9842678d89/x/wasm/internal/types/msg.go#L73 - */ -export interface MsgInstantiateContract extends MsgTemplate { - readonly type: "wasm/instantiate"; - readonly value: { - /** Bech32 account address */ - readonly sender: string; - /** ID of the Wasm code that was uploaded before */ - readonly code_id: string; - /** Human-readable label for this contract */ - readonly label: string; - /** Init message as JavaScript object */ - readonly init_msg: any; - readonly init_funds: ReadonlyArray; - }; -} - -/** - * Creates an instance of contract that was uploaded before. - * - * @see https://github.com/cosmwasm/wasmd/blob/9842678d89/x/wasm/internal/types/msg.go#L103 - */ -export interface MsgExecuteContract extends MsgTemplate { - readonly type: "wasm/execute"; - readonly value: { - /** Bech32 account address */ - readonly sender: string; - /** Bech32 account address */ - readonly contract: string; - /** Handle message as JavaScript object */ - readonly msg: any; - readonly sent_funds: ReadonlyArray; - }; -} - -export type Msg = MsgSend | MsgStoreCode | MsgInstantiateContract | MsgExecuteContract | MsgTemplate; - -export function isMsgSend(msg: Msg): msg is MsgSend { - return (msg as MsgSend).type === "cosmos-sdk/MsgSend"; -} - -export function isMsgStoreCode(msg: Msg): msg is MsgStoreCode { - return (msg as MsgStoreCode).type === "wasm/store-code"; -} - -export function isMsgInstantiateContract(msg: Msg): msg is MsgInstantiateContract { - return (msg as MsgInstantiateContract).type === "wasm/instantiate"; -} - -export function isMsgExecuteContract(msg: Msg): msg is MsgExecuteContract { - return (msg as MsgExecuteContract).type === "wasm/execute"; -} - -export interface StdFee { - readonly amount: ReadonlyArray; - readonly gas: string; -} - -export interface StdSignature { - readonly pub_key: PubKey; - readonly signature: string; -} - -export interface PubKey { - // type is one of the strings defined in pubkeyTypes - // I don't use a string literal union here as that makes trouble with json test data: - // https://github.com/confio/cosmwasm-js/pull/44#pullrequestreview-353280504 - readonly type: string; - // Value field is base64-encoded in all cases - // Note: if type is Secp256k1, this must contain a COMPRESSED pubkey - to encode from bcp/keycontrol land, you must compress it first - readonly value: string; -} - -export const pubkeyType = { - /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */ - secp256k1: "tendermint/PubKeySecp256k1" as const, - /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */ - ed25519: "tendermint/PubKeyEd25519" as const, - /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */ - sr25519: "tendermint/PubKeySr25519" as const, -}; - -export const pubkeyTypes: readonly string[] = [pubkeyType.secp256k1, pubkeyType.ed25519, pubkeyType.sr25519]; - -export interface WasmData { - // key is hex-encoded - readonly key: string; - // value is base64 encoded - readonly val: string; -} - -// Model is a parsed WasmData object -export interface Model { - readonly key: Uint8Array; - readonly val: Uint8Array; -} - -export function parseWasmData({ key, val }: WasmData): Model { - return { - key: fromHex(key), - val: fromBase64(val), - }; -} - -/** - * An object containing a parsed JSON document. The result of JSON.parse(). - * This doen't privide any type safety over `any` but expresses intent in the code. - */ -export type JsonObject = any; diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json deleted file mode 100644 index 167e8c02..00000000 --- a/packages/sdk/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "baseUrl": ".", - "outDir": "build", - "declarationDir": "build/types", - "rootDir": "src" - }, - "include": [ - "src/**/*" - ] -} diff --git a/packages/sdk/typedoc.js b/packages/sdk/typedoc.js deleted file mode 100644 index e2387c7d..00000000 --- a/packages/sdk/typedoc.js +++ /dev/null @@ -1,14 +0,0 @@ -const packageJson = require("./package.json"); - -module.exports = { - src: ["./src"], - out: "docs", - exclude: "**/*.spec.ts", - target: "es6", - name: `${packageJson.name} Documentation`, - readme: "README.md", - mode: "file", - excludeExternals: true, - excludeNotExported: true, - excludePrivate: true, -}; diff --git a/packages/sdk/types/address.d.ts b/packages/sdk/types/address.d.ts deleted file mode 100644 index 9eb5af82..00000000 --- a/packages/sdk/types/address.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { PubKey } from "./types"; -export declare function rawSecp256k1PubkeyToAddress(pubkeyRaw: Uint8Array, prefix: string): string; -export declare function pubkeyToAddress(pubkey: PubKey, prefix: string): string; diff --git a/packages/sdk/types/builder.d.ts b/packages/sdk/types/builder.d.ts deleted file mode 100644 index 68e18c0a..00000000 --- a/packages/sdk/types/builder.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function isValidBuilder(builder: string): boolean; diff --git a/packages/sdk/types/coins.d.ts b/packages/sdk/types/coins.d.ts deleted file mode 100644 index 9208f3e2..00000000 --- a/packages/sdk/types/coins.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface Coin { - readonly denom: string; - readonly amount: string; -} -/** Creates a coin */ -export declare function coin(amount: number, denom: string): Coin; -/** Creates a list of coins with one element */ -export declare function coins(amount: number, denom: string): Coin[]; diff --git a/packages/sdk/types/cosmwasmclient.d.ts b/packages/sdk/types/cosmwasmclient.d.ts deleted file mode 100644 index 12ac73ec..00000000 --- a/packages/sdk/types/cosmwasmclient.d.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { Coin } from "./coins"; -import { Log } from "./logs"; -import { BroadcastMode, RestClient } from "./restclient"; -import { CosmosSdkTx, JsonObject, PubKey, StdTx } from "./types"; -export interface GetNonceResult { - readonly accountNumber: number; - readonly sequence: number; -} -export interface Account { - /** Bech32 account address */ - readonly address: string; - readonly balance: ReadonlyArray; - readonly pubkey: PubKey | undefined; - readonly accountNumber: number; - readonly sequence: number; -} -export interface PostTxResult { - readonly logs: readonly Log[]; - readonly rawLog: string; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} -export interface SearchByIdQuery { - readonly id: string; -} -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: readonly { - readonly key: string; - readonly value: string; - }[]; -} -export declare type SearchTxQuery = - | SearchByIdQuery - | SearchByHeightQuery - | SearchBySentFromOrToQuery - | SearchByTagsQuery; -export interface SearchTxFilter { - readonly minHeight?: number; - readonly maxHeight?: number; -} -export interface Code { - readonly id: number; - /** Bech32 account address */ - readonly creator: string; - /** Hex-encoded sha256 hash of the code stored here */ - readonly checksum: string; - readonly source?: string; - readonly builder?: string; -} -export interface CodeDetails extends Code { - /** The original wasm bytes */ - readonly data: Uint8Array; -} -export interface Contract { - readonly address: string; - readonly codeId: number; - /** Bech32 account address */ - readonly creator: string; - readonly label: string; -} -export interface ContractDetails extends Contract { - /** Argument passed on initialization of the contract */ - readonly initMsg: object; -} -/** 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; - readonly logs: readonly Log[]; - readonly tx: CosmosSdkTx; - /** The gas limit as set by the user */ - readonly gasWanted?: number; - /** The gas used by the execution */ - readonly gasUsed?: number; - /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ - readonly timestamp: string; -} -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; -} -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: ReadonlyArray; -} -/** Use for testing only */ -export interface PrivateCosmWasmClient { - readonly restClient: RestClient; -} -export declare class CosmWasmClient { - protected readonly restClient: RestClient; - /** Any address the chain considers valid (valid bech32 with proper prefix) */ - protected anyValidAddress: string | undefined; - private readonly codesCache; - private chainId; - /** - * Creates a new client to interact with a CosmWasm blockchain. - * - * This instance does a lot of caching. In order to benefit from that you should try to use one instance - * for the lifetime of your application. When switching backends, a new instance must be created. - * - * @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API) - * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns - */ - constructor(apiUrl: string, broadcastMode?: BroadcastMode); - getChainId(): Promise; - getHeight(): Promise; - /** - * Returns a 32 byte upper-case hex transaction hash (typically used as the transaction ID) - */ - getIdentifier(tx: CosmosSdkTx): Promise; - /** - * Returns account number and sequence. - * - * Throws if the account does not exist on chain. - * - * @param address returns data for this address. When unset, the client's sender adddress is used. - */ - getNonce(address: string): Promise; - getAccount(address: string): Promise; - /** - * Gets block header and meta - * - * @param height The height of the block. If undefined, the latest height is used. - */ - getBlock(height?: number): Promise; - searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise; - postTx(tx: StdTx): Promise; - getCodes(): Promise; - getCodeDetails(codeId: number): Promise; - getContracts(codeId: number): Promise; - /** - * Throws an error if no contract was found at the address - */ - getContract(address: string): Promise; - /** - * Returns the data at the key if present (raw contract dependent storage data) - * or null if no data at this key. - * - * Promise is rejected when contract does not exist. - */ - queryContractRaw(address: string, key: Uint8Array): Promise; - /** - * Makes a smart query on the contract, returns the parsed JSON document. - * - * Promise is rejected when contract does not exist. - * Promise is rejected for invalid query format. - * Promise is rejected for invalid response format. - */ - queryContractSmart(address: string, queryMsg: object): Promise; - private txsQuery; -} diff --git a/packages/sdk/types/decoding.d.ts b/packages/sdk/types/decoding.d.ts deleted file mode 100644 index fd0c5746..00000000 --- a/packages/sdk/types/decoding.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { StdTx } from "./types"; -export declare function unmarshalTx(data: Uint8Array): StdTx; diff --git a/packages/sdk/types/encoding.d.ts b/packages/sdk/types/encoding.d.ts deleted file mode 100644 index 4d32b80b..00000000 --- a/packages/sdk/types/encoding.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Msg, StdFee, StdTx } from "./types"; -export declare function marshalTx(tx: StdTx): Uint8Array; -export declare function makeSignBytes( - msgs: readonly Msg[], - fee: StdFee, - chainId: string, - memo: string, - accountNumber: number, - sequence: number, -): Uint8Array; diff --git a/packages/sdk/types/index.d.ts b/packages/sdk/types/index.d.ts deleted file mode 100644 index 474b2dd3..00000000 --- a/packages/sdk/types/index.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as logs from "./logs"; -import * as types from "./types"; -export { logs, types }; -export { pubkeyToAddress } from "./address"; -export { Coin, coin, coins } from "./coins"; -export { unmarshalTx } from "./decoding"; -export { makeSignBytes, marshalTx } from "./encoding"; -export { BroadcastMode, RestClient, TxsResponse } from "./restclient"; -export { - Account, - Block, - BlockHeader, - Code, - CodeDetails, - Contract, - ContractDetails, - CosmWasmClient, - GetNonceResult, - IndexedTx, - PostTxResult, - SearchByHeightQuery, - SearchByIdQuery, - SearchBySentFromOrToQuery, - SearchByTagsQuery, - SearchTxQuery, - SearchTxFilter, -} from "./cosmwasmclient"; -export { makeCosmoshubPath, Pen, PrehashType, Secp256k1Pen } from "./pen"; -export { decodeBech32Pubkey, encodeBech32Pubkey, encodeSecp256k1Pubkey } from "./pubkey"; -export { findSequenceForSignedTx } from "./sequence"; -export { encodeSecp256k1Signature, decodeSignature } from "./signature"; -export { - ExecuteResult, - FeeTable, - InstantiateResult, - SigningCallback, - SigningCosmWasmClient, - UploadMeta, - UploadResult, -} from "./signingcosmwasmclient"; diff --git a/packages/sdk/types/logs.d.ts b/packages/sdk/types/logs.d.ts deleted file mode 100644 index 2e1decb3..00000000 --- a/packages/sdk/types/logs.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -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 declare function parseAttribute(input: unknown): Attribute; -export declare function parseEvent(input: unknown): Event; -export declare function parseLog(input: unknown): Log; -export declare function parseLogs(input: unknown): readonly Log[]; -/** - * 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 declare function findAttribute( - logs: readonly Log[], - eventType: "message" | "transfer", - attrKey: string, -): Attribute; diff --git a/packages/sdk/types/pen.d.ts b/packages/sdk/types/pen.d.ts deleted file mode 100644 index 068db3cb..00000000 --- a/packages/sdk/types/pen.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Slip10RawIndex } from "@iov/crypto"; -import { StdSignature } from "./types"; -export declare type PrehashType = "sha256" | "sha512" | null; -/** - * A pen is the most basic tool you can think of for signing. It works - * everywhere and can be used intuitively by everyone. However, it does not - * come with a great amount of features. End of semi suitable metaphor. - * - * This wraps a single keypair and allows for signing. - * - * Non-goals of this types are: multi account support, persistency, data migrations, - * obfuscation of sensitive data. - */ -export interface Pen { - readonly pubkey: Uint8Array; - readonly sign: (signBytes: Uint8Array, prehashType?: PrehashType) => Promise; -} -/** - * The Cosmoshub derivation path in the form `m/44'/118'/0'/0/a` - * with 0-based account index `a`. - */ -export declare function makeCosmoshubPath(a: number): readonly Slip10RawIndex[]; -export declare class Secp256k1Pen implements Pen { - static fromMnemonic(mnemonic: string, hdPath?: readonly Slip10RawIndex[]): Promise; - readonly pubkey: Uint8Array; - private readonly privkey; - private constructor(); - /** - * Creates and returns a signature - */ - sign(signBytes: Uint8Array, prehashType?: PrehashType): Promise; - address(prefix: string): string; -} diff --git a/packages/sdk/types/pubkey.d.ts b/packages/sdk/types/pubkey.d.ts deleted file mode 100644 index b6ebdebc..00000000 --- a/packages/sdk/types/pubkey.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PubKey } from "./types"; -export declare function encodeSecp256k1Pubkey(pubkey: Uint8Array): PubKey; -export declare function decodeBech32Pubkey(bechEncoded: string): PubKey; -export declare function encodeBech32Pubkey(pubkey: PubKey, prefix: string): string; diff --git a/packages/sdk/types/restclient.d.ts b/packages/sdk/types/restclient.d.ts deleted file mode 100644 index 5d5deea4..00000000 --- a/packages/sdk/types/restclient.d.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { Coin } from "./coins"; -import { CosmosSdkTx, JsonObject, Model, StdTx } from "./types"; -export interface CosmosSdkAccount { - /** Bech32 account address */ - readonly address: string; - readonly coins: ReadonlyArray; - /** Bech32 encoded pubkey */ - readonly public_key: string; - readonly account_number: number; - readonly sequence: number; -} -export interface NodeInfo { - readonly protocol_version: { - readonly p2p: string; - readonly block: string; - readonly app: string; - }; - readonly id: string; - readonly listen_addr: string; - readonly network: string; - readonly version: string; - readonly channels: string; - readonly moniker: string; - readonly other: { - readonly tx_index: string; - readonly rpc_address: string; - }; -} -export interface ApplicationVersion { - readonly name: string; - readonly server_name: string; - readonly client_name: string; - readonly version: string; - readonly commit: string; - readonly build_tags: string; - readonly go: string; -} -export interface NodeInfoResponse { - readonly node_info: NodeInfo; - readonly application_version: ApplicationVersion; -} -export interface BlockId { - readonly hash: string; -} -export interface BlockHeader { - readonly version: { - readonly block: string; - readonly app: string; - }; - readonly height: string; - readonly chain_id: string; - /** An RFC 3339 time string like e.g. '2020-02-15T10:39:10.4696305Z' */ - readonly time: string; - readonly last_commit_hash: string; - readonly last_block_id: BlockId; - /** Can be empty */ - readonly data_hash: string; - readonly validators_hash: string; - readonly next_validators_hash: string; - readonly consensus_hash: string; - readonly app_hash: string; - /** Can be empty */ - readonly last_results_hash: string; - /** Can be empty */ - readonly evidence_hash: string; - readonly proposer_address: string; -} -export interface Block { - readonly header: BlockHeader; - readonly data: { - /** Array of base64 encoded transactions */ - readonly txs: ReadonlyArray | null; - }; -} -export interface BlockResponse { - readonly block_id: BlockId; - readonly block: Block; -} -interface AuthAccountsResponse { - readonly height: string; - readonly result: { - readonly type: "cosmos-sdk/Account"; - readonly value: CosmosSdkAccount; - }; -} -declare type WasmResponse = WasmSuccess | WasmError; -interface WasmSuccess { - readonly height: string; - readonly result: T; -} -interface WasmError { - readonly error: string; -} -export interface TxsResponse { - readonly height: string; - readonly txhash: string; - /** 🤷‍♂️ */ - readonly codespace?: string; - /** Falsy when transaction execution succeeded. Contains error code on error. */ - readonly code?: number; - readonly raw_log: string; - readonly logs?: object; - readonly tx: CosmosSdkTx; - /** The gas limit as set by the user */ - readonly gas_wanted?: string; - /** The gas used by the execution */ - readonly gas_used?: string; - readonly timestamp: string; -} -interface SearchTxsResponse { - readonly total_count: string; - readonly count: string; - readonly page_number: string; - readonly page_total: string; - readonly limit: string; - readonly txs: readonly TxsResponse[]; -} -export interface PostTxsResponse { - readonly height: string; - readonly txhash: string; - readonly code?: number; - readonly raw_log?: string; - /** The same as `raw_log` but deserialized? */ - readonly logs?: object; - /** The gas limit as set by the user */ - readonly gas_wanted?: string; - /** The gas used by the execution */ - readonly gas_used?: string; -} -interface EncodeTxResponse { - readonly tx: string; -} -export interface CodeInfo { - readonly id: number; - /** Bech32 account address */ - readonly creator: string; - /** Hex-encoded sha256 hash of the code stored here */ - readonly data_hash: string; - readonly source?: string; - readonly builder?: string; -} -export interface CodeDetails extends CodeInfo { - /** Base64 encoded raw wasm data */ - readonly data: string; -} -export interface ContractInfo { - readonly address: string; - readonly code_id: number; - /** Bech32 account address */ - readonly creator: string; - readonly label: string; -} -export interface ContractDetails extends ContractInfo { - /** Argument passed on initialization of the contract */ - readonly init_msg: object; -} -declare type RestClientResponse = - | NodeInfoResponse - | BlockResponse - | AuthAccountsResponse - | TxsResponse - | SearchTxsResponse - | PostTxsResponse - | EncodeTxResponse - | WasmResponse - | WasmResponse - | WasmResponse - | WasmResponse - | WasmResponse; -/** - * The mode used to send transaction - * - * @see https://cosmos.network/rpc/#/Transactions/post_txs - */ -export declare enum BroadcastMode { - /** Return after tx commit */ - Block = "block", - /** Return afer CheckTx */ - Sync = "sync", - /** Return right away */ - Async = "async", -} -export declare class RestClient { - private readonly client; - private readonly broadcastMode; - /** - * Creates a new client to interact with a Cosmos SDK light client daemon. - * This class tries to be a direct mapping onto the API. Some basic decoding and normalizatin is done - * but things like caching are done at a higher level. - * - * When building apps, you should not need to use this class directly. If you do, this indicates a missing feature - * in higher level components. Feel free to raise an issue in this case. - * - * @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API) - * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns - */ - constructor(apiUrl: string, broadcastMode?: BroadcastMode); - get(path: string): Promise; - post(path: string, params: any): Promise; - authAccounts(address: string): Promise; - blocksLatest(): Promise; - blocks(height: number): Promise; - nodeInfo(): Promise; - txById(id: string): Promise; - txsQuery(query: string): Promise; - /** returns the amino-encoding of the transaction performed by the server */ - encodeTx(tx: CosmosSdkTx): Promise; - /** - * Broadcasts a signed transaction to into the transaction pool. - * Depending on the RestClient's broadcast mode, this might or might - * wait for checkTx or deliverTx to be executed before returning. - * - * @param tx a signed transaction as StdTx (i.e. not wrapped in type/value container) - */ - postTx(tx: StdTx): Promise; - listCodeInfo(): Promise; - getCode(id: number): Promise; - listContractsByCodeId(id: number): Promise; - /** - * Returns null when contract was not found at this address. - */ - getContractInfo(address: string): Promise; - getAllContractState(address: string): Promise; - queryContractRaw(address: string, key: Uint8Array): Promise; - /** - * Makes a smart query on the contract and parses the reponse as JSON. - * Throws error if no such contract exists, the query format is invalid or the response is invalid. - */ - queryContractSmart(address: string, query: object): Promise; -} -export {}; diff --git a/packages/sdk/types/sequence.d.ts b/packages/sdk/types/sequence.d.ts deleted file mode 100644 index 70d38469..00000000 --- a/packages/sdk/types/sequence.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CosmosSdkTx } from "./types"; -/** - * Serach for sequence s with `min` <= `s` < `upperBound` to find the sequence that was used to sign the transaction - * - * @param tx The signed transaction - * @param chainId The chain ID for which this transaction was signed - * @param accountNumber The account number for which this transaction was signed - * @param upperBound The upper bound for the testing, i.e. sequence must be lower than this value - * @param min The lowest sequence that is tested - * - * @returns the sequence if a match was found and undefined otherwise - */ -export declare function findSequenceForSignedTx( - tx: CosmosSdkTx, - chainId: string, - accountNumber: number, - upperBound: number, - min?: number, -): Promise; diff --git a/packages/sdk/types/signature.d.ts b/packages/sdk/types/signature.d.ts deleted file mode 100644 index c23e7167..00000000 --- a/packages/sdk/types/signature.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { StdSignature } from "./types"; -/** - * Takes a binary pubkey and signature to create a signature object - * - * @param pubkey a compressed secp256k1 public key - * @param signature a 64 byte fixed length representation of secp256k1 signature components r and s - */ -export declare function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature; -export declare function decodeSignature( - signature: StdSignature, -): { - readonly pubkey: Uint8Array; - readonly signature: Uint8Array; -}; diff --git a/packages/sdk/types/signingcosmwasmclient.d.ts b/packages/sdk/types/signingcosmwasmclient.d.ts deleted file mode 100644 index f6c34312..00000000 --- a/packages/sdk/types/signingcosmwasmclient.d.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Coin } from "./coins"; -import { Account, CosmWasmClient, GetNonceResult, PostTxResult } from "./cosmwasmclient"; -import { Log } from "./logs"; -import { BroadcastMode } from "./restclient"; -import { StdFee, StdSignature } from "./types"; -export interface SigningCallback { - (signBytes: Uint8Array): Promise; -} -export interface FeeTable { - readonly upload: StdFee; - readonly init: StdFee; - readonly exec: StdFee; - readonly send: StdFee; -} -export interface UploadMeta { - /** The source URL */ - readonly source?: string; - /** The builder tag */ - readonly builder?: string; -} -export interface UploadResult { - /** Size of the original wasm code in bytes */ - readonly originalSize: number; - /** A hex encoded sha256 checksum of the original wasm code (that is stored on chain) */ - readonly originalChecksum: string; - /** Size of the compressed wasm code in bytes */ - readonly compressedSize: number; - /** A hex encoded sha256 checksum of the compressed wasm code (that stored in the transaction) */ - readonly compressedChecksum: string; - /** The ID of the code asigned by the chain */ - readonly codeId: number; - readonly logs: readonly Log[]; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} -export interface InstantiateResult { - /** The address of the newly instantiated contract */ - readonly contractAddress: string; - readonly logs: readonly Log[]; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} -export interface ExecuteResult { - readonly logs: readonly Log[]; - /** Transaction hash (might be used as transaction ID). Guaranteed to be non-empty upper-case hex */ - readonly transactionHash: string; -} -export declare class SigningCosmWasmClient extends CosmWasmClient { - readonly senderAddress: string; - private readonly signCallback; - private readonly fees; - /** - * Creates a new client with signing capability to interact with a CosmWasm blockchain. This is the bigger brother of CosmWasmClient. - * - * This instance does a lot of caching. In order to benefit from that you should try to use one instance - * for the lifetime of your application. When switching backends, a new instance must be created. - * - * @param apiUrl The URL of a Cosmos SDK light client daemon API (sometimes called REST server or REST API) - * @param senderAddress The address that will sign and send transactions using this instance - * @param signCallback An asynchonous callback to create a signature for a given transaction. This can be implemented using secure key stores that require user interaction. - * @param customFees The fees that are paid for transactions - * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns - */ - constructor( - apiUrl: string, - senderAddress: string, - signCallback: SigningCallback, - customFees?: Partial, - broadcastMode?: BroadcastMode, - ); - getNonce(address?: string): Promise; - getAccount(address?: string): Promise; - /** Uploads code and returns a receipt, including the code ID */ - upload(wasmCode: Uint8Array, meta?: UploadMeta, memo?: string): Promise; - instantiate( - codeId: number, - initMsg: object, - label: string, - memo?: string, - transferAmount?: readonly Coin[], - ): Promise; - execute( - contractAddress: string, - handleMsg: object, - memo?: string, - transferAmount?: readonly Coin[], - ): Promise; - sendTokens(recipientAddress: string, transferAmount: readonly Coin[], memo?: string): Promise; -} diff --git a/packages/sdk/types/types.d.ts b/packages/sdk/types/types.d.ts deleted file mode 100644 index aeaa640f..00000000 --- a/packages/sdk/types/types.d.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Coin } from "./coins"; -/** An Amino/Cosmos SDK StdTx */ -export interface StdTx { - readonly msg: ReadonlyArray; - readonly fee: StdFee; - readonly signatures: ReadonlyArray; - readonly memo: string | undefined; -} -export declare function isStdTx(txValue: unknown): txValue is StdTx; -export interface CosmosSdkTx { - readonly type: string; - readonly value: StdTx; -} -interface MsgTemplate { - readonly type: string; - readonly value: any; -} -/** A Cosmos SDK token transfer message */ -export interface MsgSend extends MsgTemplate { - readonly type: "cosmos-sdk/MsgSend"; - readonly value: { - /** Bech32 account address */ - readonly from_address: string; - /** Bech32 account address */ - readonly to_address: string; - readonly amount: ReadonlyArray; - }; -} -/** - * Uploads Wam code to the chain - * - * @see https://github.com/cosmwasm/wasmd/blob/9842678d89/x/wasm/internal/types/msg.go#L17 - */ -export interface MsgStoreCode extends MsgTemplate { - readonly type: "wasm/store-code"; - readonly value: { - /** Bech32 account address */ - readonly sender: string; - /** Base64 encoded Wasm */ - readonly wasm_byte_code: string; - /** A valid URI reference to the contract's source code. Can be empty. */ - readonly source: string; - /** A docker tag. Can be empty. */ - readonly builder: string; - }; -} -/** - * Creates an instance of contract that was uploaded before. - * - * @see https://github.com/cosmwasm/wasmd/blob/9842678d89/x/wasm/internal/types/msg.go#L73 - */ -export interface MsgInstantiateContract extends MsgTemplate { - readonly type: "wasm/instantiate"; - readonly value: { - /** Bech32 account address */ - readonly sender: string; - /** ID of the Wasm code that was uploaded before */ - readonly code_id: string; - /** Human-readable label for this contract */ - readonly label: string; - /** Init message as JavaScript object */ - readonly init_msg: any; - readonly init_funds: ReadonlyArray; - }; -} -/** - * Creates an instance of contract that was uploaded before. - * - * @see https://github.com/cosmwasm/wasmd/blob/9842678d89/x/wasm/internal/types/msg.go#L103 - */ -export interface MsgExecuteContract extends MsgTemplate { - readonly type: "wasm/execute"; - readonly value: { - /** Bech32 account address */ - readonly sender: string; - /** Bech32 account address */ - readonly contract: string; - /** Handle message as JavaScript object */ - readonly msg: any; - readonly sent_funds: ReadonlyArray; - }; -} -export declare type Msg = MsgSend | MsgStoreCode | MsgInstantiateContract | MsgExecuteContract | MsgTemplate; -export declare function isMsgSend(msg: Msg): msg is MsgSend; -export declare function isMsgStoreCode(msg: Msg): msg is MsgStoreCode; -export declare function isMsgInstantiateContract(msg: Msg): msg is MsgInstantiateContract; -export declare function isMsgExecuteContract(msg: Msg): msg is MsgExecuteContract; -export interface StdFee { - readonly amount: ReadonlyArray; - readonly gas: string; -} -export interface StdSignature { - readonly pub_key: PubKey; - readonly signature: string; -} -export interface PubKey { - readonly type: string; - readonly value: string; -} -export declare const pubkeyType: { - /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */ - secp256k1: "tendermint/PubKeySecp256k1"; - /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */ - ed25519: "tendermint/PubKeyEd25519"; - /** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */ - sr25519: "tendermint/PubKeySr25519"; -}; -export declare const pubkeyTypes: readonly string[]; -export interface WasmData { - readonly key: string; - readonly val: string; -} -export interface Model { - readonly key: Uint8Array; - readonly val: Uint8Array; -} -export declare function parseWasmData({ key, val }: WasmData): Model; -/** - * An object containing a parsed JSON document. The result of JSON.parse(). - * This doen't privide any type safety over `any` but expresses intent in the code. - */ -export declare type JsonObject = any; -export {}; diff --git a/packages/sdk/webpack.web.config.js b/packages/sdk/webpack.web.config.js deleted file mode 100644 index 7373cace..00000000 --- a/packages/sdk/webpack.web.config.js +++ /dev/null @@ -1,19 +0,0 @@ -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(["WASMD_ENABLED"])], - }, -];