From db0fc219aa994281e784a2a99c470a9e6be2dd7c Mon Sep 17 00:00:00 2001 From: Evan Gray Date: Tue, 7 Jun 2022 11:36:21 -0400 Subject: [PATCH] cosmwasm: terra2 support Co-authored-by: Csongor Kiss --- Tiltfile | 6 +- clients/js/main.ts | 4 +- clients/js/networks.ts | 12 + clients/js/package-lock.json | 18 +- clients/js/package.json | 2 +- cosmwasm/Cargo.lock | 627 ++--- cosmwasm/Cargo.toml | 4 - cosmwasm/Dockerfile | 3 +- cosmwasm/Makefile | 16 +- cosmwasm/contracts/cw20-wrapped/Cargo.toml | 20 +- .../contracts/cw20-wrapped/src/contract.rs | 4 +- .../cw20-wrapped/tests/integration.rs | 4 +- cosmwasm/contracts/cw721-base/.cargo/config | 5 - cosmwasm/contracts/cw721-base/Cargo.toml | 38 - cosmwasm/contracts/cw721-base/NOTICE | 14 - cosmwasm/contracts/cw721-base/README.md | 71 - .../contracts/cw721-base/examples/schema.rs | 39 - cosmwasm/contracts/cw721-base/helpers.ts | 393 --- .../schema/all_nft_info_response.json | 155 - .../cw721-base/schema/approval_response.json | 94 - .../cw721-base/schema/approvals_response.json | 97 - .../schema/contract_info_response.json | 17 - .../cw721-base/schema/execute_msg.json | 310 -- .../cw721-base/schema/instantiate_msg.json | 24 - .../cw721-base/schema/minter_response.json | 14 - .../cw721-base/schema/nft_info_response.json | 31 - .../schema/num_tokens_response.json | 15 - .../cw721-base/schema/operators_response.json | 97 - .../cw721-base/schema/owner_of_response.json | 103 - .../cw721-base/schema/query_msg.json | 285 -- .../cw721-base/schema/tokens_response.json | 17 - .../cw721-base/src/contract_tests.rs | 756 ----- cosmwasm/contracts/cw721-base/src/error.rs | 20 - cosmwasm/contracts/cw721-base/src/execute.rs | 397 --- cosmwasm/contracts/cw721-base/src/helpers.rs | 179 -- cosmwasm/contracts/cw721-base/src/lib.rs | 51 - cosmwasm/contracts/cw721-base/src/msg.rs | 154 - cosmwasm/contracts/cw721-base/src/query.rs | 299 -- cosmwasm/contracts/cw721-base/src/state.rs | 141 - .../contracts/cw721-wrapped/.cargo/config | 5 - cosmwasm/contracts/cw721-wrapped/Cargo.toml | 31 - .../cw721-wrapped/examples/schema.rs | 59 - .../schema/all_nft_info_response.json | 234 -- .../schema/approval_response.json | 94 - .../schema/approvals_response.json | 97 - .../schema/contract_info_response.json | 17 - .../cw721-wrapped/schema/execute_msg.json | 389 --- .../cw721-wrapped/schema/instantiate_msg.json | 24 - .../cw721-wrapped/schema/minter_response.json | 14 - .../schema/nft_info_response.json | 110 - .../schema/num_tokens_response.json | 15 - .../schema/operators_response.json | 97 - .../schema/owner_of_response.json | 103 - .../cw721-wrapped/schema/query_msg.json | 285 -- .../cw721-wrapped/schema/tokens_response.json | 17 - cosmwasm/contracts/cw721-wrapped/src/lib.rs | 203 -- cosmwasm/contracts/cw721-wrapped/src/msg.rs | 135 - cosmwasm/contracts/cw721-wrapped/src/state.rs | 35 - .../mock-bridge-integration/Cargo.toml | 26 +- .../mock-bridge-integration/src/contract.rs | 6 +- cosmwasm/contracts/nft-bridge/.cargo/config | 5 - cosmwasm/contracts/nft-bridge/Cargo.toml | 30 - cosmwasm/contracts/nft-bridge/src/contract.rs | 589 ---- cosmwasm/contracts/nft-bridge/src/lib.rs | 7 - cosmwasm/contracts/nft-bridge/src/msg.rs | 61 - cosmwasm/contracts/nft-bridge/src/state.rs | 272 -- cosmwasm/contracts/nft-bridge/src/token_id.rs | 97 - cosmwasm/contracts/token-bridge/Cargo.toml | 22 +- .../contracts/token-bridge/src/contract.rs | 556 ++-- cosmwasm/contracts/token-bridge/src/lib.rs | 4 + cosmwasm/contracts/token-bridge/src/msg.rs | 19 +- cosmwasm/contracts/token-bridge/src/state.rs | 73 +- .../token-bridge/src/testing/tests.rs | 59 +- .../token-bridge/src/token_address.rs | 228 ++ cosmwasm/contracts/wormhole/Cargo.toml | 18 +- cosmwasm/contracts/wormhole/src/byte_utils.rs | 12 +- cosmwasm/contracts/wormhole/src/contract.rs | 4 +- .../contracts/wormhole/tests/integration.rs | 2 +- cosmwasm/devnet/Dockerfile | 2 +- cosmwasm/devnet/config/app.toml | 29 +- cosmwasm/devnet/config/config.toml | 47 +- cosmwasm/devnet/config/genesis.json | 294 +- cosmwasm/packages/cw721/.cargo/config | 4 - cosmwasm/packages/cw721/Cargo.toml | 19 - cosmwasm/packages/cw721/NOTICE | 14 - cosmwasm/packages/cw721/README.md | 122 - cosmwasm/packages/cw721/examples/schema.rs | 41 - .../cw721/schema/all_nft_info_response.json | 155 - .../cw721/schema/approval_response.json | 94 - .../cw721/schema/approvals_response.json | 97 - .../cw721/schema/contract_info_response.json | 17 - .../cw721/schema/cw721_execute_msg.json | 236 -- .../cw721/schema/cw721_query_msg.json | 240 -- .../cw721/schema/cw721_receive_msg.json | 28 - .../cw721/schema/nft_info_response.json | 31 - .../cw721/schema/num_tokens_response.json | 15 - .../cw721/schema/operators_response.json | 97 - .../cw721/schema/owner_of_response.json | 103 - .../cw721/schema/tokens_response.json | 17 - cosmwasm/packages/cw721/src/lib.rs | 15 - cosmwasm/packages/cw721/src/msg.rs | 36 - cosmwasm/packages/cw721/src/query.rs | 132 - cosmwasm/packages/cw721/src/receiver.rs | 43 - cosmwasm/packages/cw721/src/traits.rs | 166 -- cosmwasm/test/package-lock.json | 2507 +++++++++++++++-- cosmwasm/test/package.json | 4 +- cosmwasm/test/src/__tests__/bridge.ts | 396 ++- cosmwasm/test/src/helpers/client.ts | 6 +- cosmwasm/test/src/helpers/receipt.ts | 2 +- cosmwasm/test/src/helpers/vaa.ts | 20 +- cosmwasm/test/src/instantiate.ts | 9 +- cosmwasm/tools/deploy.js | 159 +- cosmwasm/tools/package-lock.json | 327 ++- cosmwasm/tools/package.json | 2 +- devnet/eth-devnet.yaml | 4 +- devnet/terra2-devnet.yaml | 4 +- docs/devnet.md | 52 +- ethereum/scripts/register_terra2_chain.js | 29 + scripts/devnet-consts.json | 26 + scripts/guardian-set-init.sh | 9 +- solana/devnet_setup.sh | 1 + terra/Dockerfile | 2 +- terra/tools/deploy.js | 2 + 123 files changed, 4125 insertions(+), 10120 deletions(-) delete mode 100644 cosmwasm/contracts/cw721-base/.cargo/config delete mode 100644 cosmwasm/contracts/cw721-base/Cargo.toml delete mode 100644 cosmwasm/contracts/cw721-base/NOTICE delete mode 100644 cosmwasm/contracts/cw721-base/README.md delete mode 100644 cosmwasm/contracts/cw721-base/examples/schema.rs delete mode 100644 cosmwasm/contracts/cw721-base/helpers.ts delete mode 100644 cosmwasm/contracts/cw721-base/schema/all_nft_info_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/approval_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/approvals_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/contract_info_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/execute_msg.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/instantiate_msg.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/minter_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/nft_info_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/num_tokens_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/operators_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/owner_of_response.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/query_msg.json delete mode 100644 cosmwasm/contracts/cw721-base/schema/tokens_response.json delete mode 100644 cosmwasm/contracts/cw721-base/src/contract_tests.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/error.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/execute.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/helpers.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/lib.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/msg.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/query.rs delete mode 100644 cosmwasm/contracts/cw721-base/src/state.rs delete mode 100644 cosmwasm/contracts/cw721-wrapped/.cargo/config delete mode 100644 cosmwasm/contracts/cw721-wrapped/Cargo.toml delete mode 100644 cosmwasm/contracts/cw721-wrapped/examples/schema.rs delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/all_nft_info_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/approval_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/approvals_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/contract_info_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/execute_msg.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/instantiate_msg.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/minter_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/nft_info_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/num_tokens_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/operators_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/owner_of_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/query_msg.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/schema/tokens_response.json delete mode 100644 cosmwasm/contracts/cw721-wrapped/src/lib.rs delete mode 100644 cosmwasm/contracts/cw721-wrapped/src/msg.rs delete mode 100644 cosmwasm/contracts/cw721-wrapped/src/state.rs delete mode 100644 cosmwasm/contracts/nft-bridge/.cargo/config delete mode 100644 cosmwasm/contracts/nft-bridge/Cargo.toml delete mode 100644 cosmwasm/contracts/nft-bridge/src/contract.rs delete mode 100644 cosmwasm/contracts/nft-bridge/src/lib.rs delete mode 100644 cosmwasm/contracts/nft-bridge/src/msg.rs delete mode 100644 cosmwasm/contracts/nft-bridge/src/state.rs delete mode 100644 cosmwasm/contracts/nft-bridge/src/token_id.rs create mode 100644 cosmwasm/contracts/token-bridge/src/token_address.rs delete mode 100644 cosmwasm/packages/cw721/.cargo/config delete mode 100644 cosmwasm/packages/cw721/Cargo.toml delete mode 100644 cosmwasm/packages/cw721/NOTICE delete mode 100644 cosmwasm/packages/cw721/README.md delete mode 100644 cosmwasm/packages/cw721/examples/schema.rs delete mode 100644 cosmwasm/packages/cw721/schema/all_nft_info_response.json delete mode 100644 cosmwasm/packages/cw721/schema/approval_response.json delete mode 100644 cosmwasm/packages/cw721/schema/approvals_response.json delete mode 100644 cosmwasm/packages/cw721/schema/contract_info_response.json delete mode 100644 cosmwasm/packages/cw721/schema/cw721_execute_msg.json delete mode 100644 cosmwasm/packages/cw721/schema/cw721_query_msg.json delete mode 100644 cosmwasm/packages/cw721/schema/cw721_receive_msg.json delete mode 100644 cosmwasm/packages/cw721/schema/nft_info_response.json delete mode 100644 cosmwasm/packages/cw721/schema/num_tokens_response.json delete mode 100644 cosmwasm/packages/cw721/schema/operators_response.json delete mode 100644 cosmwasm/packages/cw721/schema/owner_of_response.json delete mode 100644 cosmwasm/packages/cw721/schema/tokens_response.json delete mode 100644 cosmwasm/packages/cw721/src/lib.rs delete mode 100644 cosmwasm/packages/cw721/src/msg.rs delete mode 100644 cosmwasm/packages/cw721/src/query.rs delete mode 100644 cosmwasm/packages/cw721/src/receiver.rs delete mode 100644 cosmwasm/packages/cw721/src/traits.rs create mode 100644 ethereum/scripts/register_terra2_chain.js diff --git a/Tiltfile b/Tiltfile index f019a09eb..6cdf2ae8f 100644 --- a/Tiltfile +++ b/Tiltfile @@ -580,8 +580,8 @@ k8s_yaml_with_ns("devnet/terra2-devnet.yaml") k8s_resource( "terra2-terrad", port_forwards = [ - port_forward(26657, name = "Terra 2 RPC [:26657]", host = webHost), - port_forward(1317, name = "Terra 2 LCD [:1317]", host = webHost), + port_forward(26658, container_port = 26657, name = "Terra 2 RPC [:26658]", host = webHost), + port_forward(1318, container_port = 1317, name = "Terra 2 LCD [:1318]", host = webHost), ], resource_deps = ["const-gen"], labels = ["terra2"], @@ -597,7 +597,7 @@ k8s_resource( k8s_resource( "terra2-fcd", resource_deps = ["terra2-terrad", "terra2-postgres"], - port_forwards = [port_forward(3060, name = "Terra 2 FCD [:3060]", host = webHost)], + port_forwards = [port_forward(3061, container_port = 3060, name = "Terra 2 FCD [:3061]", host = webHost)], labels = ["terra2"], trigger_mode = trigger_mode, ) diff --git a/clients/js/main.ts b/clients/js/main.ts index 0bcf2a43d..423b661ce 100644 --- a/clients/js/main.ts +++ b/clients/js/main.ts @@ -3,7 +3,7 @@ import yargs from "yargs"; import { hideBin } from "yargs/helpers"; -import { setDefaultWasm } from "@certusone/wormhole-sdk"; +import { isTerraChain, setDefaultWasm } from "@certusone/wormhole-sdk"; import { execute_governance_solana } from "./solana"; import { execute_governance_evm } from "./evm"; import { execute_governance_terra } from "./terra"; @@ -271,7 +271,7 @@ yargs(hideBin(process.argv)) ); } else if (isEVMChain(chain)) { await execute_governance_evm(parsed_vaa.payload, buf, network, chain); - } else if (chain === "terra") { + } else if (isTerraChain(chain)) { await execute_governance_terra(parsed_vaa.payload, buf, network); } else if (chain === "solana") { await execute_governance_solana(parsed_vaa, buf, network); diff --git a/clients/js/networks.ts b/clients/js/networks.ts index b5aa47fab..b1f7e7931 100644 --- a/clients/js/networks.ts +++ b/clients/js/networks.ts @@ -90,6 +90,10 @@ const MAINNET = { rpc: undefined, key: undefined, }, + terra2: { + rpc: undefined, + key: undefined, + }, ropsten: { rpc: `https://ropsten.infura.io/v3/${get_env_var("INFURA_KEY")}`, key: get_env_var("ETH_KEY"), @@ -170,6 +174,10 @@ const TESTNET = { rpc: "https://proxy.devnet.neonlabs.org/solana", key: get_env_var("ETH_KEY"), }, + terra2: { + rpc: undefined, + key: undefined, + }, ropsten: { rpc: `https://ropsten.infura.io/v3/${get_env_var("INFURA_KEY")}`, key: get_env_var("ETH_KEY"), @@ -250,6 +258,10 @@ const DEVNET = { rpc: undefined, key: undefined, }, + terra2: { + rpc: undefined, + key: undefined, + }, ropsten: { rpc: undefined, key: undefined, diff --git a/clients/js/package-lock.json b/clients/js/package-lock.json index df3941ea7..e5415b5a1 100644 --- a/clients/js/package-lock.json +++ b/clients/js/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "dependencies": { "@celo-tools/celo-ethers-wrapper": "^0.1.0", - "@certusone/wormhole-sdk": "^0.3.8", + "@certusone/wormhole-sdk": "^0.4.1", "@solana/web3.js": "^1.22.0", "@terra-money/terra.js": "^1.8.9", "axios": "^0.24.0", @@ -542,14 +542,14 @@ } }, "node_modules/@certusone/wormhole-sdk": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.3.8.tgz", - "integrity": "sha512-XHWKRqYo+Euj8DNWPLM3j5cXAqVkp4QtmpYqheLqO3hQLIc5MvyHZfXHxfAq0gmrdQT89xP5Dq8Q3uLGtq07QQ==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.4.1.tgz", + "integrity": "sha512-kScSlYtdOY+xlJNMBSkze16umYIw+/yI2TRQ1qY27Gnzqwes4Fl1z+WJEioO3pCH62SYLCYlme16xjL50Y7b+A==", "dependencies": { "@improbable-eng/grpc-web": "^0.14.0", "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.24.0", - "@terra-money/terra.js": "^3.0.7", + "@terra-money/terra.js": "^3.1.3", "algosdk": "^1.15.0", "axios": "^0.24.0", "bech32": "^2.0.0", @@ -10963,14 +10963,14 @@ "requires": {} }, "@certusone/wormhole-sdk": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.3.8.tgz", - "integrity": "sha512-XHWKRqYo+Euj8DNWPLM3j5cXAqVkp4QtmpYqheLqO3hQLIc5MvyHZfXHxfAq0gmrdQT89xP5Dq8Q3uLGtq07QQ==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.4.1.tgz", + "integrity": "sha512-kScSlYtdOY+xlJNMBSkze16umYIw+/yI2TRQ1qY27Gnzqwes4Fl1z+WJEioO3pCH62SYLCYlme16xjL50Y7b+A==", "requires": { "@improbable-eng/grpc-web": "^0.14.0", "@solana/spl-token": "^0.1.8", "@solana/web3.js": "^1.24.0", - "@terra-money/terra.js": "^3.0.7", + "@terra-money/terra.js": "^3.1.3", "algosdk": "^1.15.0", "axios": "^0.24.0", "bech32": "^2.0.0", diff --git a/clients/js/package.json b/clients/js/package.json index 24673473e..6c54d2024 100644 --- a/clients/js/package.json +++ b/clients/js/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "dependencies": { "@celo-tools/celo-ethers-wrapper": "^0.1.0", - "@certusone/wormhole-sdk": "^0.3.8", + "@certusone/wormhole-sdk": "^0.4.1", "@solana/web3.js": "^1.22.0", "@terra-money/terra.js": "^1.8.9", "axios": "^0.24.0", diff --git a/cosmwasm/Cargo.lock b/cosmwasm/Cargo.lock index 849af0d0f..08015d420 100644 --- a/cosmwasm/Cargo.lock +++ b/cosmwasm/Cargo.lock @@ -17,6 +17,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -88,12 +99,45 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + +[[package]] +name = "bytecheck" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a31f923c2db9513e4298b72df143e6e655a759b3d6a0966df18f81223fff54f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb17c862a905d912174daa27ae002326fff56dc8b8ada50a0a5f0976cb174f0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "cc" version = "1.0.72" @@ -112,31 +156,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" -[[package]] -name = "const-oid" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" - [[package]] name = "const-oid" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" -[[package]] -name = "cosmwasm-crypto" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec9bdd1f4da5fc0d085251b0322661c5aaf773ab299e3e205fb18130b7f6ba3" -dependencies = [ - "digest", - "ed25519-zebra 2.2.0", - "k256 0.9.6", - "rand_core 0.5.1", - "thiserror", -] - [[package]] name = "cosmwasm-crypto" version = "1.0.0" @@ -144,21 +169,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" dependencies = [ "digest", - "ed25519-zebra 3.0.0", + "ed25519-zebra", "k256 0.10.4", "rand_core 0.6.3", "thiserror", ] -[[package]] -name = "cosmwasm-derive" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac17a14b4ab09a5d89b5301218067acca33d9311376e5c34c9877f09e562395" -dependencies = [ - "syn", -] - [[package]] name = "cosmwasm-derive" version = "1.0.0" @@ -168,32 +184,6 @@ dependencies = [ "syn", ] -[[package]] -name = "cosmwasm-schema" -version = "1.0.0-beta4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5de9749a4a933c34c59db83a77935a79cd705f93ae2b1cfbe40821f32751f75" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47306c113f4d964c35a74a87ceb8ccfb5811e9810a9dc427101148b5b9134ca" -dependencies = [ - "base64", - "cosmwasm-crypto 0.16.2", - "cosmwasm-derive 0.16.2", - "schemars", - "serde", - "serde-json-wasm 0.3.1", - "thiserror", - "uint", -] - [[package]] name = "cosmwasm-std" version = "1.0.0" @@ -201,45 +191,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" dependencies = [ "base64", - "cosmwasm-crypto 1.0.0", - "cosmwasm-derive 1.0.0", + "cosmwasm-crypto", + "cosmwasm-derive", "forward_ref", "schemars", "serde", - "serde-json-wasm 0.4.1", + "serde-json-wasm", "thiserror", "uint", ] -[[package]] -name = "cosmwasm-storage" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e3472d8e0e7155c5f4d89674ad47adede4b1491ad14f4141610e1522028a6a7" -dependencies = [ - "cosmwasm-std 0.16.2", - "serde", -] - [[package]] name = "cosmwasm-storage" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" dependencies = [ - "cosmwasm-std 1.0.0", + "cosmwasm-std", "serde", ] [[package]] name = "cosmwasm-vm" -version = "0.16.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d90f1d30e2d01d815c520dad2738f93188f2e64b3dda3e11609c13eb73109b8" +checksum = "472bd6f037bf4de43a29f65ca5d66b8c06510fdb2cd9c911ed08b5a2cec3606f" dependencies = [ "clru", - "cosmwasm-crypto 0.16.2", - "cosmwasm-std 0.16.2", + "cosmwasm-crypto", + "cosmwasm-std", "hex", "loupe", "parity-wasm", @@ -263,24 +243,24 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.74.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ca3560686e7c9c7ed7e0fe77469f2410ba5d7781b1acaa9adc8d8deea28e3e" +checksum = "7e6bea67967505247f54fa2c85cf4f6e0e31c4e5692c9b70e4ae58e339067333" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.74.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf9bf1ffffb6ce3d2e5ebc83549bd2436426c99b31cc550d521364cbe35d276" +checksum = "48194035d2752bdd5bdae429e3ab88676e95f52a2b1355a5d4e809f9e39b1d74" dependencies = [ "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", - "gimli 0.24.0", + "gimli 0.25.0", "log", "regalloc", "smallvec", @@ -289,9 +269,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.74.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc21936a5a6d07e23849ffe83e5c1f6f50305c074f4b2970ca50c13bf55b821" +checksum = "976efb22fcab4f2cd6bd4e9913764616a54d895c1a23530128d04e03633c555f" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -299,21 +279,21 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.74.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5b6ffaa87560bebe69a5446449da18090b126037920b0c1c6d5945f72faf6b" +checksum = "9dabb5fe66e04d4652e434195b45ae65b5c8172d520247b8f66d8df42b2b45dc" [[package]] name = "cranelift-entity" -version = "0.74.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6b4a8bef04f82e4296782646f733c641d09497df2fabf791323fefaa44c64c" +checksum = "3329733e4d4b8e91c809efcaa4faee80bf66f20164e3dd16d707346bd3494799" [[package]] name = "cranelift-frontend" -version = "0.74.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b783b351f966fce33e3c03498cb116d16d97a8f9978164a60920bd0d3a99c" +checksum = "279afcc0d3e651b773f94837c3d581177b348c8d69e928104b2e9fccb226f921" dependencies = [ "cranelift-codegen", "log", @@ -435,22 +415,22 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.8.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e867b9972b83b32e00e878dfbff48299ba26618dabeb19b9c56fae176dc225" +checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" dependencies = [ - "cosmwasm-std 0.16.2", + "cosmwasm-std", "schemars", "serde", ] [[package]] -name = "cw0" -version = "0.8.1" +name = "cw-utils" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c497f885a40918a02df7d938c81809965fa05cfc21b3dc591e9950237b5de0a9" +checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" dependencies = [ - "cosmwasm-std 0.16.2", + "cosmwasm-std", "schemars", "serde", "thiserror", @@ -458,11 +438,11 @@ dependencies = [ [[package]] name = "cw2" -version = "0.8.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d48454f96494aa1018556cd457977375cc8c57ef3e5c767cfa2ea5ec24b0258" +checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" dependencies = [ - "cosmwasm-std 0.16.2", + "cosmwasm-std", "cw-storage-plus", "schemars", "serde", @@ -470,25 +450,25 @@ dependencies = [ [[package]] name = "cw20" -version = "0.8.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a11a2adbd52258f5b4ed5323f62bc6e559f2cefbe52ef0e58290016fde5bb083" +checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" dependencies = [ - "cosmwasm-std 0.16.2", - "cw0", + "cosmwasm-std", + "cw-utils", "schemars", "serde", ] [[package]] name = "cw20-base" -version = "0.8.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3791e0f6b4a0a82b86541d48dcc67c2d607da8e5691a91b40b2c06ddf09c52" +checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" dependencies = [ - "cosmwasm-std 0.16.2", + "cosmwasm-std", "cw-storage-plus", - "cw0", + "cw-utils", "cw2", "cw20", "schemars", @@ -497,15 +477,12 @@ dependencies = [ ] [[package]] -name = "cw20-legacy" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d27b11827323369993519abb494f3ae9b6aac4d716d058bea5e181b9b0074b7" +name = "cw20-wrapped-2" +version = "0.1.0" dependencies = [ - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", + "cosmwasm-std", + "cosmwasm-storage", "cw-storage-plus", - "cw0", "cw2", "cw20", "cw20-base", @@ -514,61 +491,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cw20-wrapped" -version = "0.1.0" -dependencies = [ - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", - "cw-storage-plus", - "cw2", - "cw20", - "cw20-legacy", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721" -version = "0.10.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std 0.16.2", - "cw0", - "schemars", - "serde", -] - -[[package]] -name = "cw721-base" -version = "0.10.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std 0.16.2", - "cw-storage-plus", - "cw0", - "cw2", - "cw721", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw721-wrapped" -version = "0.10.1" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", - "cw2", - "cw721", - "cw721-base", - "schemars", - "serde", -] - [[package]] name = "darling" version = "0.13.0" @@ -609,9 +531,6 @@ name = "der" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" -dependencies = [ - "const-oid 0.6.2", -] [[package]] name = "der" @@ -619,7 +538,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ - "const-oid 0.7.1", + "const-oid", ] [[package]] @@ -639,9 +558,9 @@ checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" [[package]] name = "dynasm" -version = "1.2.0" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab1096ebdaa974cd6a41a743e94dfa00cce9bfbf4690bcc73fdec6a903938ccc" +checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" dependencies = [ "bitflags", "byteorder", @@ -654,13 +573,13 @@ dependencies = [ [[package]] name = "dynasmrt" -version = "1.2.0" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c69d1e16ae47889b47c301c790f48615cd9bfbdf586e3f6d4fde64af3d259" +checksum = "64fba5a42bd76a17cad4bfa00de168ee1cbfa06a5e8ce992ae880218c05641a9" dependencies = [ "byteorder", "dynasm", - "memmap2 0.5.0", + "memmap2", ] [[package]] @@ -687,20 +606,6 @@ dependencies = [ "signature", ] -[[package]] -name = "ed25519-zebra" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.5.1", - "serde", - "sha2", - "thiserror", -] - [[package]] name = "ed25519-zebra" version = "3.0.0" @@ -732,7 +637,6 @@ dependencies = [ "ff 0.10.1", "generic-array", "group 0.10.0", - "pkcs8 0.7.6", "rand_core 0.6.3", "subtle", "zeroize", @@ -756,6 +660,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "enumset" version = "1.0.8" @@ -849,9 +773,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" dependencies = [ "fallible-iterator", "indexmap", @@ -891,6 +815,18 @@ name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +dependencies = [ + "ahash", +] [[package]] name = "hermit-abi" @@ -930,7 +866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.11.2", "serde", ] @@ -940,6 +876,15 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "js-sys" +version = "0.3.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "k256" version = "0.9.6" @@ -949,7 +894,6 @@ dependencies = [ "cfg-if", "ecdsa 0.12.4", "elliptic-curve 0.10.6", - "sha2", ] [[package]] @@ -1044,15 +988,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" -[[package]] -name = "memmap2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.5.0" @@ -1082,16 +1017,16 @@ dependencies = [ ] [[package]] -name = "mock-bridge-integration" +name = "mock-bridge-integration-2" version = "0.1.0" dependencies = [ "bigint", - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", + "cosmwasm-std", + "cosmwasm-storage", "cosmwasm-vm", "cw20", "cw20-base", - "cw20-wrapped", + "cw20-wrapped-2", "generic-array", "hex", "k256 0.9.6", @@ -1102,8 +1037,8 @@ dependencies = [ "sha3", "terraswap", "thiserror", - "token-bridge-terra", - "wormhole-bridge-terra", + "token-bridge-terra-2", + "wormhole-bridge-terra-2", ] [[package]] @@ -1112,25 +1047,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "nft-bridge" -version = "0.1.0" -dependencies = [ - "bigint", - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", - "cw721", - "cw721-base", - "cw721-wrapped", - "hex", - "lazy_static", - "schemars", - "serde", - "serde_json", - "sha3", - "wormhole-bridge-terra", -] - [[package]] name = "num_cpus" version = "1.13.0" @@ -1141,17 +1057,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7" -dependencies = [ - "crc32fast", - "indexmap", - "memchr", -] - [[package]] name = "object" version = "0.27.1" @@ -1161,6 +1066,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "object" +version = "0.28.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +dependencies = [ + "crc32fast", + "hashbrown 0.11.2", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -1179,16 +1102,6 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" -[[package]] -name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" -dependencies = [ - "der 0.4.4", - "spki 0.4.1", -] - [[package]] name = "pkcs8" version = "0.8.0" @@ -1196,7 +1109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ "der 0.5.1", - "spki 0.5.4", + "spki", "zeroize", ] @@ -1239,6 +1152,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "protobuf" +version = "2.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96" +dependencies = [ + "bytes", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -1364,9 +1286,9 @@ dependencies = [ [[package]] name = "region" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" dependencies = [ "bitflags", "libc", @@ -1383,6 +1305,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "rend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +dependencies = [ + "bytecheck", +] + [[package]] name = "rfc6979" version = "0.1.0" @@ -1396,21 +1327,23 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.6.7" +version = "0.7.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb135b3e5e3311f0a254bfb00333f4bac9ef1d89888b84242a89eb8722b09a07" +checksum = "517a3034eb2b1499714e9d1e49b2367ad567e07639b69776d35e259d9c27cca6" dependencies = [ - "memoffset", + "bytecheck", + "hashbrown 0.12.1", "ptr_meta", + "rend", "rkyv_derive", "seahash", ] [[package]] name = "rkyv_derive" -version = "0.6.7" +version = "0.7.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba8f489f6b6d8551bb15904293c1ad58a6abafa7d8390d15f7ed05a2afcd87d5" +checksum = "505c209ee04111a006431abf39696e640838364d67a107c559ababaf6fd8c9dd" dependencies = [ "proc-macro2", "quote", @@ -1485,7 +1418,7 @@ checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der 0.5.1", "generic-array", - "pkcs8 0.8.0", + "pkcs8", "subtle", "zeroize", ] @@ -1499,15 +1432,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-json-wasm" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50eef3672ec8fa45f3457fd423ba131117786784a895548021976117c1ded449" -dependencies = [ - "serde", -] - [[package]] name = "serde-json-wasm" version = "0.4.1" @@ -1600,15 +1524,6 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" -[[package]] -name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" -dependencies = [ - "der 0.4.4", -] - [[package]] name = "spki" version = "0.5.4" @@ -1674,29 +1589,18 @@ dependencies = [ "winapi", ] -[[package]] -name = "terra-cosmwasm" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552f18cba2b535d1f8c0e3b3f37696820b954bc7535d2e33909f2a6342302718" -dependencies = [ - "cosmwasm-std 0.16.2", - "schemars", - "serde", -] - [[package]] name = "terraswap" -version = "2.4.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96f2c2a6371e9ddf2c942368e64645cc3e8fc2855da70c8c6bed238dcdd5522f" +checksum = "02458cd8271acd0fc98d097ca6d296f5f7abe6359ca841554db90de67c376500" dependencies = [ - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", + "cosmwasm-std", + "cosmwasm-storage", "cw20", + "protobuf", "schemars", "serde", - "terra-cosmwasm", ] [[package]] @@ -1720,15 +1624,15 @@ dependencies = [ ] [[package]] -name = "token-bridge-terra" +name = "token-bridge-terra-2" version = "0.1.0" dependencies = [ "bigint", - "cosmwasm-std 0.16.2", - "cosmwasm-storage 0.16.2", + "cosmwasm-std", + "cosmwasm-storage", "cw20", "cw20-base", - "cw20-wrapped", + "cw20-wrapped-2", "generic-array", "hex", "k256 0.9.6", @@ -1739,7 +1643,7 @@ dependencies = [ "sha3", "terraswap", "thiserror", - "wormhole-bridge-terra", + "wormhole-bridge-terra-2", ] [[package]] @@ -1749,6 +1653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1817,17 +1722,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] -name = "wasmer" -version = "2.0.0" +name = "wasm-bindgen" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f52e455a01d0fac439cd7a96ba9b519bdc84e923a5b96034054697ebb17cd75" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" + +[[package]] +name = "wasmer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f727a39e7161f7438ddb8eafe571b67c576a8c2fb459f666d9053b5bba4afdea" dependencies = [ "cfg-if", "indexmap", + "js-sys", "loupe", "more-asserts", "target-lexicon", "thiserror", + "wasm-bindgen", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", @@ -1842,9 +1803,9 @@ dependencies = [ [[package]] name = "wasmer-compiler" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc86dda6f715f03104800be575a38382b35c3962953af9e9d8722dcf0bd2458f" +checksum = "4e9951599222eb12bd13d4d91bcded0a880e4c22c2dfdabdf5dc7e5e803b7bf3" dependencies = [ "enumset", "loupe", @@ -1861,18 +1822,19 @@ dependencies = [ [[package]] name = "wasmer-compiler-cranelift" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a570746cbec434179e2d53357973a34dfdb208043104e8fac3b7b0023015cf6" +checksum = "44c83273bce44e668f3a2b9ccb7f1193db918b1d6806f64acc5ff71f6ece5f20" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", - "gimli 0.24.0", + "gimli 0.25.0", "loupe", "more-asserts", "rayon", "smallvec", + "target-lexicon", "tracing", "wasmer-compiler", "wasmer-types", @@ -1881,9 +1843,9 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9429b9f7708c582d855b1787f09c7029ff23fb692550d4a1cc351c8ea84c3014" +checksum = "5432e993840cdb8e6875ddc8c9eea64e7a129579b4706bd91b8eb474d9c4a860" dependencies = [ "byteorder", "dynasm", @@ -1900,9 +1862,9 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee7b351bcc1e782997c72dc0b5b328f3ddcad4813b8ce3cac3f25ae5a4ab56b" +checksum = "458dbd9718a837e6dbc52003aef84487d79eedef5fa28c7d28b6784be98ac08e" dependencies = [ "proc-macro-error", "proc-macro2", @@ -1912,14 +1874,15 @@ dependencies = [ [[package]] name = "wasmer-engine" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8454ead320a4017ba36ddd9ab4fbf7776fceea6ab0b79b5e53664a1682569fc3" +checksum = "6ed603a6d037ebbb14014d7f739ae996a78455a4b86c41cfa4e81c590a1253b9" dependencies = [ "backtrace", + "enumset", "lazy_static", "loupe", - "memmap2 0.2.3", + "memmap2", "more-asserts", "rustc-demangle", "serde", @@ -1933,14 +1896,17 @@ dependencies = [ [[package]] name = "wasmer-engine-dylib" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aa390d123ebe23d5315c39f6063fcc18319661d03c8000f23d0fe1c011e8135" +checksum = "ccd7fdc60e252a795c849b3f78a81a134783051407e7e279c10b7019139ef8dc" dependencies = [ "cfg-if", + "enum-iterator", + "enumset", "leb128", "libloading", "loupe", + "object 0.28.4", "rkyv", "serde", "tempfile", @@ -1955,11 +1921,13 @@ dependencies = [ [[package]] name = "wasmer-engine-universal" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dffe8015f08915eb4939ebc8e521cde8246f272f5197ea60d46214ac5aef285" +checksum = "dcff0cd2c01a8de6009fd863b14ea883132a468a24f2d2ee59dc34453d3a31b5" dependencies = [ "cfg-if", + "enum-iterator", + "enumset", "leb128", "loupe", "region", @@ -1973,9 +1941,9 @@ dependencies = [ [[package]] name = "wasmer-middlewares" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95d2b4722d64c850893f7a7eab3ab76181efbafcd366827801d8bcd64bff525f" +checksum = "659775db15684f4674c3a8967409682c2eb44f63cc21121fa3dcd975c03ab887" dependencies = [ "loupe", "wasmer", @@ -1985,11 +1953,11 @@ dependencies = [ [[package]] name = "wasmer-object" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c541c985799fc1444702501c15d41becfb066c92d9673defc1c7417fd8739e15" +checksum = "24ce18ac2877050e59580d27ee1a88f3192d7a31e77fbba0852abc7888d6e0b5" dependencies = [ - "object 0.25.3", + "object 0.28.4", "thiserror", "wasmer-compiler", "wasmer-types", @@ -1997,9 +1965,9 @@ dependencies = [ [[package]] name = "wasmer-types" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91f75d3c31f8b1f8d818ff49624fc974220243cbc07a2252f408192e97c6b51" +checksum = "659fa3dd6c76f62630deff4ac8c7657b07f0b1e4d7e0f8243a552b9d9b448e24" dependencies = [ "indexmap", "loupe", @@ -2010,13 +1978,14 @@ dependencies = [ [[package]] name = "wasmer-vm" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469a12346a4831e7dac639b9646d8c9b24c7d2cf0cf458b77f489edb35060c1f" +checksum = "afdc46158517c2769f9938bc222a7d41b3bb330824196279d8aa2d667cd40641" dependencies = [ "backtrace", "cc", "cfg-if", + "enum-iterator", "indexmap", "libc", "loupe", @@ -2070,14 +2039,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "wormhole-bridge-terra" +name = "wormhole-bridge-terra-2" version = "0.1.0" dependencies = [ - "cosmwasm-std 1.0.0", - "cosmwasm-storage 1.0.0", + "cosmwasm-std", + "cosmwasm-storage", "cw20", "cw20-base", - "cw20-wrapped", + "cw20-wrapped-2", "generic-array", "getrandom 0.2.3", "hex", diff --git a/cosmwasm/Cargo.toml b/cosmwasm/Cargo.toml index bb456d9e6..092eb77a9 100644 --- a/cosmwasm/Cargo.toml +++ b/cosmwasm/Cargo.toml @@ -3,10 +3,6 @@ members = [ "contracts/cw20-wrapped", "contracts/wormhole", "contracts/token-bridge", - "contracts/nft-bridge", - "contracts/cw721-wrapped", - "packages/cw721", - "contracts/cw721-base", "contracts/mock-bridge-integration", ] diff --git a/cosmwasm/Dockerfile b/cosmwasm/Dockerfile index 6c058e2f8..39a648724 100644 --- a/cosmwasm/Dockerfile +++ b/cosmwasm/Dockerfile @@ -6,14 +6,13 @@ FROM cosmwasm/workspace-optimizer:0.12.6@sha256:e6565a5e87c830ef3e8775a9035006b3 COPY Cargo.lock /code/ COPY Cargo.toml /code/ COPY contracts /code/contracts -COPY packages /code/packages # Support additional root CAs COPY README.md cert.pem* /certs/ # Alpine RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/cert.pem; fi -RUN optimize_workspace.sh +RUN --mount=type=cache,target=/code/target,id=cosmwasm_target --mount=type=cache,target=/usr/local/cargo/registry optimize_workspace.sh FROM scratch as artifacts COPY --from=builder /code/artifacts / diff --git a/cosmwasm/Makefile b/cosmwasm/Makefile index e88260da3..6539982c5 100644 --- a/cosmwasm/Makefile +++ b/cosmwasm/Makefile @@ -1,6 +1,5 @@ bridge_SOURCE=wormhole token_bridge_SOURCE=token_bridge_terra -nft_bridge_SOURCE=nft_bridge SOURCE_FILES=$(shell find . -name "*.rs" -or -name "*.lock" -or -name "*.toml" | grep -v target) @@ -36,10 +35,6 @@ deploy/bridge: bridge-code-id-$(NETWORK).txt ## Deploy token bridge deploy/token_bridge: token_bridge-code-id-$(NETWORK).txt -.PHONY: deploy/nft_bridge -## Deploy NFT bridge -deploy/nft_bridge: nft_bridge-code-id-$(NETWORK).txt - %-code-id-$(NETWORK).txt: check-network tools/node_modules payer-$(NETWORK).json artifacts @echo "Deploying artifacts/$($*_SOURCE).wasm on $(NETWORK)" @node tools/deploy_single.js \ @@ -54,12 +49,7 @@ tools/node_modules: tools/package-lock.json cd tools && npm ci LocalTerra: - mkdir LocalTerra && \ - cd LocalTerra && \ - git init && \ - git remote add origin https://www.github.com/terra-money/LocalTerra.git && \ - git fetch --depth 1 origin 958ff795f261f5ff2efc7b56604e2434eb76f7c4 && \ - git checkout FETCH_HEAD + git clone --depth 1 https://www.github.com/terra-money/LocalTerra test/node_modules: test/package-lock.json cd test && npm ci @@ -67,8 +57,8 @@ test/node_modules: test/package-lock.json .PHONY: unit-test ## Run unit tests unit-test: - cargo test -p wormhole-bridge-terra - cargo test -p token-bridge-terra + cargo test -p wormhole-bridge-terra-2 + cargo test -p token-bridge-terra-2 .PHONY: test ## Run unit and integration tests diff --git a/cosmwasm/contracts/cw20-wrapped/Cargo.toml b/cosmwasm/contracts/cw20-wrapped/Cargo.toml index 43cc73945..a71405b16 100644 --- a/cosmwasm/contracts/cw20-wrapped/Cargo.toml +++ b/cosmwasm/contracts/cw20-wrapped/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "cw20-wrapped" +name = "cw20-wrapped-2" version = "0.1.0" authors = ["Yuriy Savchenko "] edition = "2018" @@ -14,12 +14,12 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-std = { version = "0.16.0" } -cosmwasm-storage = { version = "0.16.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw2 = { version = "0.8.0" } -cw20 = { version = "0.8.0" } -cw20-legacy = { version = "0.2.0", features = ["library"]} -cw-storage-plus = { version = "0.8.0" } -thiserror = { version = "1.0.20" } +cosmwasm-std = { version = "1.0.0" } +cosmwasm-storage = { version = "1.0.0" } +schemars = "0.8.8" +serde = { version = "1.0.137", default-features = false, features = ["derive"] } +cw2 = { version = "0.13.2" } +cw20 = { version = "0.13.2" } +cw20-base = { version = "0.13.2", features = ["library"] } +cw-storage-plus = { version = "0.13.2" } +thiserror = { version = "1.0.31" } diff --git a/cosmwasm/contracts/cw20-wrapped/src/contract.rs b/cosmwasm/contracts/cw20-wrapped/src/contract.rs index 26abfd039..d743f4aca 100644 --- a/cosmwasm/contracts/cw20-wrapped/src/contract.rs +++ b/cosmwasm/contracts/cw20-wrapped/src/contract.rs @@ -17,7 +17,7 @@ use cosmwasm_std::{ use cosmwasm_std::entry_point; use cw2::set_contract_version; -use cw20_legacy::{ +use cw20_base::{ allowances::{ execute_burn_from, execute_decrease_allowance, @@ -80,7 +80,7 @@ pub fn instantiate( total_supply: Uint128::new(0), // set creator as minter mint: Some(MinterData { - minter: deps.api.addr_canonicalize(info.sender.as_str())?, + minter: deps.api.addr_validate(info.sender.as_str())?, cap: None, }), }; diff --git a/cosmwasm/contracts/cw20-wrapped/tests/integration.rs b/cosmwasm/contracts/cw20-wrapped/tests/integration.rs index 28244563f..91e5c609a 100644 --- a/cosmwasm/contracts/cw20-wrapped/tests/integration.rs +++ b/cosmwasm/contracts/cw20-wrapped/tests/integration.rs @@ -17,7 +17,7 @@ use cosmwasm_std::{ }; use cosmwasm_storage::to_length_prefixed; use cw20::TokenInfoResponse; -use cw20_wrapped::{ +use cw20_wrapped_2::{ contract::{ execute, instantiate, @@ -49,7 +49,7 @@ fn get_wrapped_asset_info(storage: &S) -> WrappedAssetInfo { } fn do_init() -> OwnedDeps { - let mut deps = mock_dependencies(&[]); + let mut deps = mock_dependencies(); let init_msg = InstantiateMsg { name: "Integers".into(), symbol: "INT".into(), diff --git a/cosmwasm/contracts/cw721-base/.cargo/config b/cosmwasm/contracts/cw721-base/.cargo/config deleted file mode 100644 index 7d1a066c8..000000000 --- a/cosmwasm/contracts/cw721-base/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" diff --git a/cosmwasm/contracts/cw721-base/Cargo.toml b/cosmwasm/contracts/cw721-base/Cargo.toml deleted file mode 100644 index 5d1bcdd28..000000000 --- a/cosmwasm/contracts/cw721-base/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "cw721-base" -version = "0.10.1" -authors = ["Ethan Frey "] -edition = "2018" -description = "Basic implementation cw721 NFTs" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-nfts" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "artifacts/*", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cw0 = { version = "0.8.0" } -cw2 = { version = "0.8.0" } -cw721 = { path = "../../packages/cw721", version = "0.10.1" } -cw-storage-plus = { version = "0.8.0" } -cosmwasm-std = { version = "0.16.0" } -schemars = "0.8.6" -serde = { version = "1.0.130", default-features = false, features = ["derive"] } -thiserror = { version = "1.0.30" } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta2" } diff --git a/cosmwasm/contracts/cw721-base/NOTICE b/cosmwasm/contracts/cw721-base/NOTICE deleted file mode 100644 index 7c303abc3..000000000 --- a/cosmwasm/contracts/cw721-base/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Cw721_base -Copyright (C) 2020-2021 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/cosmwasm/contracts/cw721-base/README.md b/cosmwasm/contracts/cw721-base/README.md deleted file mode 100644 index b245c9223..000000000 --- a/cosmwasm/contracts/cw721-base/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Cw721 Basic - -This is a basic implementation of a cw721 NFT contract. It implements -the [CW721 spec](../../packages/cw721/README.md) and is designed to -be deployed as is, or imported into other contracts to easily build -cw721-compatible NFTs with custom logic. - -Implements: - -- [x] CW721 Base -- [x] Metadata extension -- [ ] Enumerable extension (AllTokens done, but not Tokens - requires [#81](https://github.com/CosmWasm/cw-plus/issues/81)) - -## Implementation - -The `ExecuteMsg` and `QueryMsg` implementations follow the [CW721 spec](../../packages/cw721/README.md) and are described there. -Beyond that, we make a few additions: - -* `InstantiateMsg` takes name and symbol (for metadata), as well as a **Minter** address. This is a special address that has full -power to mint new NFTs (but not modify existing ones) -* `ExecuteMsg::Mint{token_id, owner, token_uri}` - creates a new token with given owner and (optional) metadata. It can only be called by -the Minter set in `instantiate`. -* `QueryMsg::Minter{}` - returns the minter address for this contract. - -It requires all tokens to have defined metadata in the standard format (with no extensions). For generic NFTs this may -often be enough. - -The *Minter* can either be an external actor (eg. web server, using PubKey) or another contract. If you just want to customize -the minting behavior but not other functionality, you could extend this contract (importing code and wiring it together) -or just create a custom contract as the owner and use that contract to Mint. - -If provided, it is expected that the _token_uri_ points to a JSON file following the [ERC721 Metadata JSON Schema](https://eips.ethereum.org/EIPS/eip-721). - -## Running this contract - -You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed. - -You can run unit tests on this via: - -`cargo test` - -Once you are happy with the content, you can compile it to wasm via: - -``` -RUSTFLAGS='-C link-arg=-s' cargo wasm -cp ../../target/wasm32-unknown-unknown/release/cw721_base.wasm . -ls -l cw721_base.wasm -sha256sum cw721_base.wasm -``` - -Or for a production-ready (optimized) build, run a build command in the -the repository root: https://github.com/CosmWasm/cw-plus#compiling. - -## Importing this contract - -You can also import much of the logic of this contract to build another -CW721-compliant contract, such as tradable names, crypto kitties, -or tokenized real estate. - -Basically, you just need to write your handle function and import -`cw721_base::contract::handle_transfer`, etc and dispatch to them. -This allows you to use custom `ExecuteMsg` and `QueryMsg` with your additional -calls, but then use the underlying implementation for the standard cw721 -messages you want to support. The same with `QueryMsg`. You will most -likely want to write a custom, domain-specific `instantiate`. - -**TODO: add example when written** - -For now, you can look at [`cw721-staking`](../cw721-staking/README.md) -for an example of how to "inherit" cw721 functionality and combine it with custom logic. -The process is similar for cw721. diff --git a/cosmwasm/contracts/cw721-base/examples/schema.rs b/cosmwasm/contracts/cw721-base/examples/schema.rs deleted file mode 100644 index c315be662..000000000 --- a/cosmwasm/contracts/cw721-base/examples/schema.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; - -use cw721::{ - AllNftInfoResponse, ApprovalResponse, ApprovalsResponse, ContractInfoResponse, NftInfoResponse, - NumTokensResponse, OperatorsResponse, OwnerOfResponse, TokensResponse, -}; -use cw721_base::{ExecuteMsg, Extension, InstantiateMsg, MinterResponse, QueryMsg}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(ExecuteMsg), &out_dir, "ExecuteMsg"); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema_with_title( - &schema_for!(AllNftInfoResponse), - &out_dir, - "AllNftInfoResponse", - ); - export_schema(&schema_for!(ApprovalResponse), &out_dir); - export_schema(&schema_for!(ApprovalsResponse), &out_dir); - export_schema(&schema_for!(OperatorsResponse), &out_dir); - export_schema(&schema_for!(ContractInfoResponse), &out_dir); - export_schema(&schema_for!(MinterResponse), &out_dir); - export_schema_with_title( - &schema_for!(NftInfoResponse), - &out_dir, - "NftInfoResponse", - ); - export_schema(&schema_for!(NumTokensResponse), &out_dir); - export_schema(&schema_for!(OwnerOfResponse), &out_dir); - export_schema(&schema_for!(TokensResponse), &out_dir); -} diff --git a/cosmwasm/contracts/cw721-base/helpers.ts b/cosmwasm/contracts/cw721-base/helpers.ts deleted file mode 100644 index 10bcaa714..000000000 --- a/cosmwasm/contracts/cw721-base/helpers.ts +++ /dev/null @@ -1,393 +0,0 @@ -import axios from "axios"; -import fs from "fs"; -import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate"; -import { GasPrice, calculateFee, StdFee } from "@cosmjs/stargate"; -import { DirectSecp256k1HdWallet, makeCosmoshubPath } from "@cosmjs/proto-signing"; -import { Slip10RawIndex } from "@cosmjs/crypto"; -import path from "path"; -/* - * This is a set of helpers meant for use with @cosmjs/cli - * With these you can easily use the cw721 contract without worrying about forming messages and parsing queries. - * - * Usage: npx @cosmjs/cli@^0.26 --init https://raw.githubusercontent.com/CosmWasm/cosmwasm-plus/master/contracts/cw721-base/helpers.ts - * - * Create a client: - * const [addr, client] = await useOptions(pebblenetOptions).setup('password'); - * - * Get the mnemonic: - * await useOptions(pebblenetOptions).recoverMnemonic(password); - * - * Create contract: - * const contract = CW721(client, pebblenetOptions.fees); - * - * Upload contract: - * const codeId = await contract.upload(addr); - * - * Instantiate contract example: - * const initMsg = { - * name: "Potato Coin", - * symbol: "TATER", - * minter: addr - * }; - * const instance = await contract.instantiate(addr, codeId, initMsg, 'Potato Coin!'); - * If you want to use this code inside an app, you will need several imports from https://github.com/CosmWasm/cosmjs - */ - -interface Options { - readonly httpUrl: string - readonly networkId: string - readonly feeToken: string - readonly bech32prefix: string - readonly hdPath: readonly Slip10RawIndex[] - readonly faucetUrl?: string - readonly defaultKeyFile: string, - readonly fees: { - upload: StdFee, - init: StdFee, - exec: StdFee - } -} - -const pebblenetGasPrice = GasPrice.fromString("0.01upebble"); -const pebblenetOptions: Options = { - httpUrl: 'https://rpc.pebblenet.cosmwasm.com', - networkId: 'pebblenet-1', - bech32prefix: 'wasm', - feeToken: 'upebble', - faucetUrl: 'https://faucet.pebblenet.cosmwasm.com/credit', - hdPath: makeCosmoshubPath(0), - defaultKeyFile: path.join(process.env.HOME, ".pebblenet.key"), - fees: { - upload: calculateFee(1500000, pebblenetGasPrice), - init: calculateFee(500000, pebblenetGasPrice), - exec: calculateFee(200000, pebblenetGasPrice), - }, -} - -interface Network { - setup: (password: string, filename?: string) => Promise<[string, SigningCosmWasmClient]> - recoverMnemonic: (password: string, filename?: string) => Promise -} - -const useOptions = (options: Options): Network => { - - const loadOrCreateWallet = async (options: Options, filename: string, password: string): Promise => { - let encrypted: string; - try { - encrypted = fs.readFileSync(filename, 'utf8'); - } catch (err) { - // generate if no file exists - const wallet = await DirectSecp256k1HdWallet.generate(12, {hdPaths: [options.hdPath], prefix: options.bech32prefix}); - const encrypted = await wallet.serialize(password); - fs.writeFileSync(filename, encrypted, 'utf8'); - return wallet; - } - // otherwise, decrypt the file (we cannot put deserialize inside try or it will over-write on a bad password) - const wallet = await DirectSecp256k1HdWallet.deserialize(encrypted, password); - return wallet; - }; - - const connect = async ( - wallet: DirectSecp256k1HdWallet, - options: Options - ): Promise => { - const clientOptions = { - prefix: options.bech32prefix - } - return await SigningCosmWasmClient.connectWithSigner(options.httpUrl, wallet, clientOptions) - }; - - const hitFaucet = async ( - faucetUrl: string, - address: string, - denom: string - ): Promise => { - await axios.post(faucetUrl, { denom, address }); - } - - const setup = async (password: string, filename?: string): Promise<[string, SigningCosmWasmClient]> => { - const keyfile = filename || options.defaultKeyFile; - const wallet = await loadOrCreateWallet(pebblenetOptions, keyfile, password); - const client = await connect(wallet, pebblenetOptions); - - const [account] = await wallet.getAccounts(); - // ensure we have some tokens - if (options.faucetUrl) { - const tokens = await client.getBalance(account.address, options.feeToken) - if (tokens.amount === '0') { - console.log(`Getting ${options.feeToken} from faucet`); - await hitFaucet(options.faucetUrl, account.address, options.feeToken); - } - } - - return [account.address, client]; - } - - const recoverMnemonic = async (password: string, filename?: string): Promise => { - const keyfile = filename || options.defaultKeyFile; - const wallet = await loadOrCreateWallet(pebblenetOptions, keyfile, password); - return wallet.mnemonic; - } - - return { setup, recoverMnemonic }; -} - -type TokenId = string - -interface Balances { - readonly address: string - readonly amount: string // decimal as string -} - -interface MintInfo { - readonly minter: string - readonly cap?: string // decimal as string -} - -interface ContractInfo { - readonly name: string - readonly symbol: string -} - -interface NftInfo { - readonly name: string, - readonly description: string, - readonly image: any -} - -interface Access { - readonly owner: string, - readonly approvals: [] -} -interface AllNftInfo { - readonly access: Access, - readonly info: NftInfo -} - -interface Operators { - readonly operators: [] -} - -interface Count { - readonly count: number -} - -interface InitMsg { - readonly name: string - readonly symbol: string - readonly minter: string -} -// Better to use this interface? -interface MintMsg { - readonly token_id: TokenId - readonly owner: string - readonly name: string - readonly description?: string - readonly image?: string -} - -type Expiration = { readonly at_height: number } | { readonly at_time: number } | { readonly never: {} }; - -interface AllowanceResponse { - readonly allowance: string; // integer as string - readonly expires: Expiration; -} - -interface AllowanceInfo { - readonly allowance: string; // integer as string - readonly spender: string; // bech32 address - readonly expires: Expiration; -} - -interface AllAllowancesResponse { - readonly allowances: readonly AllowanceInfo[]; -} - -interface AllAccountsResponse { - // list of bech32 address that have a balance - readonly accounts: readonly string[]; -} - -interface TokensResponse { - readonly tokens: readonly string[]; -} - -interface CW721Instance { - readonly contractAddress: string - - // queries - allowance: (owner: string, spender: string) => Promise - allAllowances: (owner: string, startAfter?: string, limit?: number) => Promise - allAccounts: (startAfter?: string, limit?: number) => Promise - minter: () => Promise - contractInfo: () => Promise - nftInfo: (tokenId: TokenId) => Promise - allNftInfo: (tokenId: TokenId) => Promise - ownerOf: (tokenId: TokenId) => Promise - approvedForAll: (owner: string, include_expired?: boolean, start_after?: string, limit?: number) => Promise - numTokens: () => Promise - tokens: (owner: string, startAfter?: string, limit?: number) => Promise - allTokens: (startAfter?: string, limit?: number) => Promise - - // actions - mint: (senderAddress: string, tokenId: TokenId, owner: string, name: string, level: number, description?: string, image?: string) => Promise - transferNft: (senderAddress: string, recipient: string, tokenId: TokenId) => Promise - sendNft: (senderAddress: string, contract: string, token_id: TokenId, msg?: BinaryType) => Promise - approve: (senderAddress: string, spender: string, tokenId: TokenId, expires?: Expiration) => Promise - approveAll: (senderAddress: string, operator: string, expires?: Expiration) => Promise - revoke: (senderAddress: string, spender: string, tokenId: TokenId) => Promise - revokeAll: (senderAddress: string, operator: string) => Promise -} - -interface CW721Contract { - // upload a code blob and returns a codeId - upload: (senderAddress: string) => Promise - - // instantiates a cw721 contract - // codeId must come from a previous deploy - // label is the public name of the contract in listing - // if you set admin, you can run migrations on this contract (likely client.senderAddress) - instantiate: (senderAddress: string, codeId: number, initMsg: Record, label: string, admin?: string) => Promise - - use: (contractAddress: string) => CW721Instance -} - - -export const CW721 = (client: SigningCosmWasmClient, fees: Options['fees']): CW721Contract => { - const use = (contractAddress: string): CW721Instance => { - - const allowance = async (owner: string, spender: string): Promise => { - return client.queryContractSmart(contractAddress, { allowance: { owner, spender } }); - }; - - const allAllowances = async (owner: string, startAfter?: string, limit?: number): Promise => { - return client.queryContractSmart(contractAddress, { all_allowances: { owner, start_after: startAfter, limit } }); - }; - - const allAccounts = async (startAfter?: string, limit?: number): Promise => { - const accounts: AllAccountsResponse = await client.queryContractSmart(contractAddress, { all_accounts: { start_after: startAfter, limit } }); - return accounts.accounts; - }; - - const minter = async (): Promise => { - return client.queryContractSmart(contractAddress, { minter: {} }); - }; - - const contractInfo = async (): Promise => { - return client.queryContractSmart(contractAddress, { contract_info: {} }); - }; - - const nftInfo = async (token_id: TokenId): Promise => { - return client.queryContractSmart(contractAddress, { nft_info: { token_id } }); - } - - const allNftInfo = async (token_id: TokenId): Promise => { - return client.queryContractSmart(contractAddress, { all_nft_info: { token_id } }); - } - - const ownerOf = async (token_id: TokenId): Promise => { - return await client.queryContractSmart(contractAddress, { owner_of: { token_id } }); - } - - const approvedForAll = async (owner: string, include_expired?: boolean, start_after?: string, limit?: number): Promise => { - return await client.queryContractSmart(contractAddress, { approved_for_all: { owner, include_expired, start_after, limit } }) - } - - // total number of tokens issued - const numTokens = async (): Promise => { - return client.queryContractSmart(contractAddress, { num_tokens: {} }); - } - - // list all token_ids that belong to a given owner - const tokens = async (owner: string, start_after?: string, limit?: number): Promise => { - return client.queryContractSmart(contractAddress, { tokens: { owner, start_after, limit } }); - } - - const allTokens = async (start_after?: string, limit?: number): Promise => { - return client.queryContractSmart(contractAddress, { all_tokens: { start_after, limit } }); - } - - // actions - const mint = async (senderAddress: string, token_id: TokenId, owner: string, name: string, level: number, description?: string, image?: string): Promise => { - const result = await client.execute(senderAddress, contractAddress, { mint: { token_id, owner, name, level, description, image } }, fees.exec); - return result.transactionHash; - } - - // transfers ownership, returns transactionHash - const transferNft = async (senderAddress: string, recipient: string, token_id: TokenId): Promise => { - const result = await client.execute(senderAddress, contractAddress, { transfer_nft: { recipient, token_id } }, fees.exec); - return result.transactionHash; - } - - // sends an nft token to another contract (TODO: msg type any needs to be revisited once receiveNft is implemented) - const sendNft = async (senderAddress: string, contract: string, token_id: TokenId, msg?: any): Promise => { - const result = await client.execute(senderAddress, contractAddress, { send_nft: { contract, token_id, msg } }, fees.exec) - return result.transactionHash; - } - - const approve = async (senderAddress: string, spender: string, token_id: TokenId, expires?: Expiration): Promise => { - const result = await client.execute(senderAddress, contractAddress, { approve: { spender, token_id, expires } }, fees.exec); - return result.transactionHash; - } - - const approveAll = async (senderAddress: string, operator: string, expires?: Expiration): Promise => { - const result = await client.execute(senderAddress, contractAddress, { approve_all: { operator, expires } }, fees.exec) - return result.transactionHash - } - - const revoke = async (senderAddress: string, spender: string, token_id: TokenId): Promise => { - const result = await client.execute(senderAddress, contractAddress, { revoke: { spender, token_id } }, fees.exec); - return result.transactionHash; - } - - const revokeAll = async (senderAddress: string, operator: string): Promise => { - const result = await client.execute(senderAddress, contractAddress, { revoke_all: { operator } }, fees.exec) - return result.transactionHash; - } - - return { - contractAddress, - allowance, - allAllowances, - allAccounts, - minter, - contractInfo, - nftInfo, - allNftInfo, - ownerOf, - approvedForAll, - numTokens, - tokens, - allTokens, - mint, - transferNft, - sendNft, - approve, - approveAll, - revoke, - revokeAll - }; - } - - const downloadWasm = async (url: string): Promise => { - const r = await axios.get(url, { responseType: 'arraybuffer' }) - if (r.status !== 200) { - throw new Error(`Download error: ${r.status}`) - } - return r.data - } - - const upload = async (senderAddress: string): Promise => { - const sourceUrl = "https://github.com/CosmWasm/cosmwasm-plus/releases/download/v0.9.0/cw721_base.wasm"; - const wasm = await downloadWasm(sourceUrl); - const result = await client.upload(senderAddress, wasm, fees.upload); - return result.codeId; - } - - const instantiate = async (senderAddress: string, codeId: number, initMsg: Record, label: string, admin?: string): Promise => { - const result = await client.instantiate(senderAddress, codeId, initMsg, label, fees.init, { memo: `Init ${label}`, admin }); - return use(result.contractAddress); - } - - return { upload, instantiate, use }; -} diff --git a/cosmwasm/contracts/cw721-base/schema/all_nft_info_response.json b/cosmwasm/contracts/cw721-base/schema/all_nft_info_response.json deleted file mode 100644 index bfc334bf7..000000000 --- a/cosmwasm/contracts/cw721-base/schema/all_nft_info_response.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllNftInfoResponse", - "type": "object", - "required": [ - "access", - "info" - ], - "properties": { - "access": { - "description": "Who can transfer the token", - "allOf": [ - { - "$ref": "#/definitions/OwnerOfResponse" - } - ] - }, - "info": { - "description": "Data on the token itself,", - "allOf": [ - { - "$ref": "#/definitions/NftInfoResponse_for_Nullable_Empty" - } - ] - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "NftInfoResponse_for_Nullable_Empty": { - "type": "object", - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "anyOf": [ - { - "$ref": "#/definitions/Empty" - }, - { - "type": "null" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - } - }, - "OwnerOfResponse": { - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/approval_response.json b/cosmwasm/contracts/cw721-base/schema/approval_response.json deleted file mode 100644 index 4f45b42e9..000000000 --- a/cosmwasm/contracts/cw721-base/schema/approval_response.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalResponse", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "$ref": "#/definitions/Approval" - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/approvals_response.json b/cosmwasm/contracts/cw721-base/schema/approvals_response.json deleted file mode 100644 index 8d8e39ea0..000000000 --- a/cosmwasm/contracts/cw721-base/schema/approvals_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalsResponse", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/contract_info_response.json b/cosmwasm/contracts/cw721-base/schema/contract_info_response.json deleted file mode 100644 index a16712589..000000000 --- a/cosmwasm/contracts/cw721-base/schema/contract_info_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractInfoResponse", - "type": "object", - "required": [ - "name", - "symbol" - ], - "properties": { - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/execute_msg.json b/cosmwasm/contracts/cw721-base/schema/execute_msg.json deleted file mode 100644 index 5cdf6603f..000000000 --- a/cosmwasm/contracts/cw721-base/schema/execute_msg.json +++ /dev/null @@ -1,310 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "description": "This is like Cw721ExecuteMsg but we add a Mint command for an owner to make this stand-alone. You will likely want to remove mint and use other control logic in any contract that inherits this.", - "oneOf": [ - { - "description": "Transfer is a base message to move a token to another account without triggering actions", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer a token to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send any token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Mint a new NFT, can only be called by the contract minter", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "$ref": "#/definitions/MintMsg_for_Nullable_Empty" - } - }, - "additionalProperties": false - }, - { - "description": "Burn an NFT the sender has access to", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "MintMsg_for_Nullable_Empty": { - "type": "object", - "required": [ - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "anyOf": [ - { - "$ref": "#/definitions/Empty" - }, - { - "type": "null" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/instantiate_msg.json b/cosmwasm/contracts/cw721-base/schema/instantiate_msg.json deleted file mode 100644 index b024c82c1..000000000 --- a/cosmwasm/contracts/cw721-base/schema/instantiate_msg.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "minter", - "name", - "symbol" - ], - "properties": { - "minter": { - "description": "The minter is the only one who can create new NFTs. This is designed for a base NFT that is controlled by an external program or contract. You will likely replace this with custom logic in custom NFTs", - "type": "string" - }, - "name": { - "description": "Name of the NFT contract", - "type": "string" - }, - "symbol": { - "description": "Symbol of the NFT contract", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/minter_response.json b/cosmwasm/contracts/cw721-base/schema/minter_response.json deleted file mode 100644 index a20e0d767..000000000 --- a/cosmwasm/contracts/cw721-base/schema/minter_response.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "description": "Shows who can mint these tokens", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/nft_info_response.json b/cosmwasm/contracts/cw721-base/schema/nft_info_response.json deleted file mode 100644 index e6bf1d405..000000000 --- a/cosmwasm/contracts/cw721-base/schema/nft_info_response.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NftInfoResponse", - "type": "object", - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "anyOf": [ - { - "$ref": "#/definitions/Empty" - }, - { - "type": "null" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "definitions": { - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/num_tokens_response.json b/cosmwasm/contracts/cw721-base/schema/num_tokens_response.json deleted file mode 100644 index 4647c23aa..000000000 --- a/cosmwasm/contracts/cw721-base/schema/num_tokens_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NumTokensResponse", - "type": "object", - "required": [ - "count" - ], - "properties": { - "count": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/operators_response.json b/cosmwasm/contracts/cw721-base/schema/operators_response.json deleted file mode 100644 index 53703072c..000000000 --- a/cosmwasm/contracts/cw721-base/schema/operators_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/owner_of_response.json b/cosmwasm/contracts/cw721-base/schema/owner_of_response.json deleted file mode 100644 index 1258d671f..000000000 --- a/cosmwasm/contracts/cw721-base/schema/owner_of_response.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OwnerOfResponse", - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-base/schema/query_msg.json b/cosmwasm/contracts/cw721-base/schema/query_msg.json deleted file mode 100644 index cd3a95619..000000000 --- a/cosmwasm/contracts/cw721-base/schema/query_msg.json +++ /dev/null @@ -1,285 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return the owner of the given token, error if token does not exist Return type: OwnerOfResponse", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Return operator that can access all of the owner's tokens. Return type: `ApprovalResponse`", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Return approvals that a token has Return type: `ApprovalsResponse`", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "List all operators that can access all of the owner's tokens Return type: `OperatorsResponse`", - "type": "object", - "required": [ - "all_operators" - ], - "properties": { - "all_operators": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired items, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Total number of tokens issued", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns top-level metadata about the contract: `ContractInfoResponse`", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns metadata about one particular token, based on *ERC721 Metadata JSON Schema* but directly from the contract: `NftInfoResponse`", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns the result of both `NftInfo` and `OwnerOf` as one query as an optimization for clients: `AllNftInfo`", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Returns all tokens owned by the given address, [] if unset. Return type: TokensResponse.", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Requires pagination. Lists all token_ids controlled by the contract. Return type: TokensResponse.", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/cosmwasm/contracts/cw721-base/schema/tokens_response.json b/cosmwasm/contracts/cw721-base/schema/tokens_response.json deleted file mode 100644 index b8e3d75b5..000000000 --- a/cosmwasm/contracts/cw721-base/schema/tokens_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_from` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/cosmwasm/contracts/cw721-base/src/contract_tests.rs b/cosmwasm/contracts/cw721-base/src/contract_tests.rs deleted file mode 100644 index 330954564..000000000 --- a/cosmwasm/contracts/cw721-base/src/contract_tests.rs +++ /dev/null @@ -1,756 +0,0 @@ -#![cfg(test)] -use cosmwasm_std::{ - from_binary, - testing::{ - mock_dependencies, - mock_env, - mock_info, - }, - to_binary, - CosmosMsg, - DepsMut, - Empty, - Response, - WasmMsg, -}; - -use cw721::{ - Approval, - ApprovalResponse, - ContractInfoResponse, - Cw721Query, - Cw721ReceiveMsg, - Expiration, - NftInfoResponse, - OperatorsResponse, - OwnerOfResponse, -}; - -use crate::{ - ContractError, - Cw721Contract, - ExecuteMsg, - Extension, - InstantiateMsg, - MintMsg, - QueryMsg, -}; - -const MINTER: &str = "merlin"; -const CONTRACT_NAME: &str = "Magic Power"; -const SYMBOL: &str = "MGK"; - -fn setup_contract(deps: DepsMut<'_>) -> Cw721Contract<'static, Extension, Empty> { - let contract = Cw721Contract::default(); - let msg = InstantiateMsg { - name: CONTRACT_NAME.to_string(), - symbol: SYMBOL.to_string(), - minter: String::from(MINTER), - }; - let info = mock_info("creator", &[]); - let res = contract.instantiate(deps, mock_env(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - contract -} - -#[test] -fn proper_instantiation() { - let mut deps = mock_dependencies(&[]); - let contract = Cw721Contract::::default(); - - let msg = InstantiateMsg { - name: CONTRACT_NAME.to_string(), - symbol: SYMBOL.to_string(), - minter: String::from(MINTER), - }; - let info = mock_info("creator", &[]); - - // we can just call .unwrap() to assert this was a success - let res = contract - .instantiate(deps.as_mut(), mock_env(), info, msg) - .unwrap(); - assert_eq!(0, res.messages.len()); - - // it worked, let's query the state - let res = contract.minter(deps.as_ref()).unwrap(); - assert_eq!(MINTER, res.minter); - let info = contract.contract_info(deps.as_ref()).unwrap(); - assert_eq!( - info, - ContractInfoResponse { - name: CONTRACT_NAME.to_string(), - symbol: SYMBOL.to_string(), - } - ); - - let count = contract.num_tokens(deps.as_ref()).unwrap(); - assert_eq!(0, count.count); - - // list the token_ids - let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap(); - assert_eq!(0, tokens.tokens.len()); -} - -#[test] -fn minting() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - - let token_id = "petrify".to_string(); - let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id.clone(), - owner: String::from("medusa"), - token_uri: Some(token_uri.clone()), - extension: None, - }); - - // random cannot mint - let random = mock_info("random", &[]); - let err = contract - .execute(deps.as_mut(), mock_env(), random, mint_msg.clone()) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // minter can mint - let allowed = mock_info(MINTER, &[]); - let _ = contract - .execute(deps.as_mut(), mock_env(), allowed, mint_msg) - .unwrap(); - - // ensure num tokens increases - let count = contract.num_tokens(deps.as_ref()).unwrap(); - assert_eq!(1, count.count); - - // unknown nft returns error - let _ = contract - .nft_info(deps.as_ref(), "unknown".to_string()) - .unwrap_err(); - - // this nft info is correct - let info = contract.nft_info(deps.as_ref(), token_id.clone()).unwrap(); - assert_eq!( - info, - NftInfoResponse:: { - token_uri: Some(token_uri), - extension: None, - } - ); - - // owner info is correct - let owner = contract - .owner_of(deps.as_ref(), mock_env(), token_id.clone(), true) - .unwrap(); - assert_eq!( - owner, - OwnerOfResponse { - owner: String::from("medusa"), - approvals: vec![], - } - ); - - // Cannot mint same token_id again - let mint_msg2 = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id.clone(), - owner: String::from("hercules"), - token_uri: None, - extension: None, - }); - - let allowed = mock_info(MINTER, &[]); - let err = contract - .execute(deps.as_mut(), mock_env(), allowed, mint_msg2) - .unwrap_err(); - assert_eq!(err, ContractError::Claimed {}); - - // list the token_ids - let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap(); - assert_eq!(1, tokens.tokens.len()); - assert_eq!(vec![token_id], tokens.tokens); -} - -#[test] -fn burning() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - - let token_id = "petrify".to_string(); - let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id.clone(), - owner: MINTER.to_string(), - token_uri: Some(token_uri), - extension: None, - }); - - let burn_msg = ExecuteMsg::Burn { token_id }; - - // mint some NFT - let allowed = mock_info(MINTER, &[]); - let _ = contract - .execute(deps.as_mut(), mock_env(), allowed.clone(), mint_msg) - .unwrap(); - - // random not allowed to burn - let random = mock_info("random", &[]); - let err = contract - .execute(deps.as_mut(), mock_env(), random, burn_msg.clone()) - .unwrap_err(); - - assert_eq!(err, ContractError::Unauthorized {}); - - let _ = contract - .execute(deps.as_mut(), mock_env(), allowed, burn_msg) - .unwrap(); - - // ensure num tokens decreases - let count = contract.num_tokens(deps.as_ref()).unwrap(); - assert_eq!(0, count.count); - - // trying to get nft returns error - let _ = contract - .nft_info(deps.as_ref(), "petrify".to_string()) - .unwrap_err(); - - // list the token_ids - let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap(); - assert!(tokens.tokens.is_empty()); -} - -#[test] -fn transferring_nft() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - - // Mint a token - let token_id = "melt".to_string(); - let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id.clone(), - owner: String::from("venus"), - token_uri: Some(token_uri), - extension: None, - }); - - let minter = mock_info(MINTER, &[]); - contract - .execute(deps.as_mut(), mock_env(), minter, mint_msg) - .unwrap(); - - // random cannot transfer - let random = mock_info("random", &[]); - let transfer_msg = ExecuteMsg::TransferNft { - recipient: String::from("random"), - token_id: token_id.clone(), - }; - - let err = contract - .execute(deps.as_mut(), mock_env(), random, transfer_msg) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // owner can - let random = mock_info("venus", &[]); - let transfer_msg = ExecuteMsg::TransferNft { - recipient: String::from("random"), - token_id: token_id.clone(), - }; - - let res = contract - .execute(deps.as_mut(), mock_env(), random, transfer_msg) - .unwrap(); - - assert_eq!( - res, - Response::new() - .add_attribute("action", "transfer_nft") - .add_attribute("sender", "venus") - .add_attribute("recipient", "random") - .add_attribute("token_id", token_id) - ); -} - -#[test] -fn sending_nft() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - - // Mint a token - let token_id = "melt".to_string(); - let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id.clone(), - owner: String::from("venus"), - token_uri: Some(token_uri), - extension: None, - }); - - let minter = mock_info(MINTER, &[]); - contract - .execute(deps.as_mut(), mock_env(), minter, mint_msg) - .unwrap(); - - let msg = to_binary("You now have the melting power").unwrap(); - let target = String::from("another_contract"); - let send_msg = ExecuteMsg::SendNft { - contract: target.clone(), - token_id: token_id.clone(), - msg: msg.clone(), - }; - - let random = mock_info("random", &[]); - let err = contract - .execute(deps.as_mut(), mock_env(), random, send_msg.clone()) - .unwrap_err(); - assert_eq!(err, ContractError::Unauthorized {}); - - // but owner can - let random = mock_info("venus", &[]); - let res = contract - .execute(deps.as_mut(), mock_env(), random, send_msg) - .unwrap(); - - let payload = Cw721ReceiveMsg { - sender: String::from("venus"), - token_id: token_id.clone(), - msg, - }; - let expected = payload.into_cosmos_msg(target.clone()).unwrap(); - // ensure expected serializes as we think it should - match &expected { - CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, .. }) => { - assert_eq!(contract_addr, &target) - } - m => panic!("Unexpected message type: {:?}", m), - } - // and make sure this is the request sent by the contract - assert_eq!( - res, - Response::new() - .add_message(expected) - .add_attribute("action", "send_nft") - .add_attribute("sender", "venus") - .add_attribute("recipient", "another_contract") - .add_attribute("token_id", token_id) - ); -} - -#[test] -fn approving_revoking() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - - // Mint a token - let token_id = "grow".to_string(); - let token_uri = "https://www.merriam-webster.com/dictionary/grow".to_string(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id.clone(), - owner: String::from("demeter"), - token_uri: Some(token_uri), - extension: None, - }); - - let minter = mock_info(MINTER, &[]); - contract - .execute(deps.as_mut(), mock_env(), minter, mint_msg) - .unwrap(); - - // Give random transferring power - let approve_msg = ExecuteMsg::Approve { - spender: String::from("random"), - token_id: token_id.clone(), - expires: None, - }; - let owner = mock_info("demeter", &[]); - let res = contract - .execute(deps.as_mut(), mock_env(), owner, approve_msg) - .unwrap(); - assert_eq!( - res, - Response::new() - .add_attribute("action", "approve") - .add_attribute("sender", "demeter") - .add_attribute("spender", "random") - .add_attribute("token_id", token_id.clone()) - ); - - // test approval query - let res = contract - .approval( - deps.as_ref(), - mock_env(), - token_id.clone(), - String::from("random"), - true, - ) - .unwrap(); - assert_eq!( - res, - ApprovalResponse { - approval: Approval { - spender: String::from("random"), - expires: Expiration::Never {} - } - } - ); - - // random can now transfer - let random = mock_info("random", &[]); - let transfer_msg = ExecuteMsg::TransferNft { - recipient: String::from("person"), - token_id: token_id.clone(), - }; - contract - .execute(deps.as_mut(), mock_env(), random, transfer_msg) - .unwrap(); - - // Approvals are removed / cleared - let query_msg = QueryMsg::OwnerOf { - token_id: token_id.clone(), - include_expired: None, - }; - let res: OwnerOfResponse = from_binary( - &contract - .query(deps.as_ref(), mock_env(), query_msg.clone()) - .unwrap(), - ) - .unwrap(); - assert_eq!( - res, - OwnerOfResponse { - owner: String::from("person"), - approvals: vec![], - } - ); - - // Approve, revoke, and check for empty, to test revoke - let approve_msg = ExecuteMsg::Approve { - spender: String::from("random"), - token_id: token_id.clone(), - expires: None, - }; - let owner = mock_info("person", &[]); - contract - .execute(deps.as_mut(), mock_env(), owner.clone(), approve_msg) - .unwrap(); - - let revoke_msg = ExecuteMsg::Revoke { - spender: String::from("random"), - token_id, - }; - contract - .execute(deps.as_mut(), mock_env(), owner, revoke_msg) - .unwrap(); - - // Approvals are now removed / cleared - let res: OwnerOfResponse = from_binary( - &contract - .query(deps.as_ref(), mock_env(), query_msg) - .unwrap(), - ) - .unwrap(); - assert_eq!( - res, - OwnerOfResponse { - owner: String::from("person"), - approvals: vec![], - } - ); -} - -#[test] -fn approving_all_revoking_all() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - - // Mint a couple tokens (from the same owner) - let token_id1 = "grow1".to_string(); - let token_uri1 = "https://www.merriam-webster.com/dictionary/grow1".to_string(); - - let token_id2 = "grow2".to_string(); - let token_uri2 = "https://www.merriam-webster.com/dictionary/grow2".to_string(); - - let mint_msg1 = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id1.clone(), - owner: String::from("demeter"), - token_uri: Some(token_uri1), - extension: None, - }); - - let minter = mock_info(MINTER, &[]); - contract - .execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg1) - .unwrap(); - - let mint_msg2 = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id2.clone(), - owner: String::from("demeter"), - token_uri: Some(token_uri2), - extension: None, - }); - - contract - .execute(deps.as_mut(), mock_env(), minter, mint_msg2) - .unwrap(); - - // paginate the token_ids - let tokens = contract.all_tokens(deps.as_ref(), None, Some(1)).unwrap(); - assert_eq!(1, tokens.tokens.len()); - assert_eq!(vec![token_id1.clone()], tokens.tokens); - let tokens = contract - .all_tokens(deps.as_ref(), Some(token_id1.clone()), Some(3)) - .unwrap(); - assert_eq!(1, tokens.tokens.len()); - assert_eq!(vec![token_id2.clone()], tokens.tokens); - - // demeter gives random full (operator) power over her tokens - let approve_all_msg = ExecuteMsg::ApproveAll { - operator: String::from("random"), - expires: None, - }; - let owner = mock_info("demeter", &[]); - let res = contract - .execute(deps.as_mut(), mock_env(), owner, approve_all_msg) - .unwrap(); - assert_eq!( - res, - Response::new() - .add_attribute("action", "approve_all") - .add_attribute("sender", "demeter") - .add_attribute("operator", "random") - ); - - // random can now transfer - let random = mock_info("random", &[]); - let transfer_msg = ExecuteMsg::TransferNft { - recipient: String::from("person"), - token_id: token_id1, - }; - contract - .execute(deps.as_mut(), mock_env(), random.clone(), transfer_msg) - .unwrap(); - - // random can now send - let inner_msg = WasmMsg::Execute { - contract_addr: "another_contract".into(), - msg: to_binary("You now also have the growing power").unwrap(), - funds: vec![], - }; - let msg: CosmosMsg = CosmosMsg::Wasm(inner_msg); - - let send_msg = ExecuteMsg::SendNft { - contract: String::from("another_contract"), - token_id: token_id2, - msg: to_binary(&msg).unwrap(), - }; - contract - .execute(deps.as_mut(), mock_env(), random, send_msg) - .unwrap(); - - // Approve_all, revoke_all, and check for empty, to test revoke_all - let approve_all_msg = ExecuteMsg::ApproveAll { - operator: String::from("operator"), - expires: None, - }; - // person is now the owner of the tokens - let owner = mock_info("person", &[]); - contract - .execute(deps.as_mut(), mock_env(), owner, approve_all_msg) - .unwrap(); - - let res = contract - .operators( - deps.as_ref(), - mock_env(), - String::from("person"), - true, - None, - None, - ) - .unwrap(); - assert_eq!( - res, - OperatorsResponse { - operators: vec![cw721::Approval { - spender: String::from("operator"), - expires: Expiration::Never {} - }] - } - ); - - // second approval - let buddy_expires = Expiration::AtHeight(1234567); - let approve_all_msg = ExecuteMsg::ApproveAll { - operator: String::from("buddy"), - expires: Some(buddy_expires), - }; - let owner = mock_info("person", &[]); - contract - .execute(deps.as_mut(), mock_env(), owner.clone(), approve_all_msg) - .unwrap(); - - // and paginate queries - let res = contract - .operators( - deps.as_ref(), - mock_env(), - String::from("person"), - true, - None, - Some(1), - ) - .unwrap(); - assert_eq!( - res, - OperatorsResponse { - operators: vec![cw721::Approval { - spender: String::from("buddy"), - expires: buddy_expires, - }] - } - ); - let res = contract - .operators( - deps.as_ref(), - mock_env(), - String::from("person"), - true, - Some(String::from("buddy")), - Some(2), - ) - .unwrap(); - assert_eq!( - res, - OperatorsResponse { - operators: vec![cw721::Approval { - spender: String::from("operator"), - expires: Expiration::Never {} - }] - } - ); - - let revoke_all_msg = ExecuteMsg::RevokeAll { - operator: String::from("operator"), - }; - contract - .execute(deps.as_mut(), mock_env(), owner, revoke_all_msg) - .unwrap(); - - // Approvals are removed / cleared without affecting others - let res = contract - .operators( - deps.as_ref(), - mock_env(), - String::from("person"), - false, - None, - None, - ) - .unwrap(); - assert_eq!( - res, - OperatorsResponse { - operators: vec![cw721::Approval { - spender: String::from("buddy"), - expires: buddy_expires, - }] - } - ); - - // ensure the filter works (nothing should be here - let mut late_env = mock_env(); - late_env.block.height = 1234568; //expired - let res = contract - .operators( - deps.as_ref(), - late_env, - String::from("person"), - false, - None, - None, - ) - .unwrap(); - assert_eq!(0, res.operators.len()); -} - -#[test] -fn query_tokens_by_owner() { - let mut deps = mock_dependencies(&[]); - let contract = setup_contract(deps.as_mut()); - let minter = mock_info(MINTER, &[]); - - // Mint a couple tokens (from the same owner) - let token_id1 = "grow1".to_string(); - let demeter = String::from("demeter"); - let token_id2 = "grow2".to_string(); - let ceres = String::from("ceres"); - let token_id3 = "sing".to_string(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id1.clone(), - owner: demeter.clone(), - token_uri: None, - extension: None, - }); - contract - .execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg) - .unwrap(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id2.clone(), - owner: ceres.clone(), - token_uri: None, - extension: None, - }); - contract - .execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg) - .unwrap(); - - let mint_msg = ExecuteMsg::Mint(MintMsg:: { - token_id: token_id3.clone(), - owner: demeter.clone(), - token_uri: None, - extension: None, - }); - contract - .execute(deps.as_mut(), mock_env(), minter, mint_msg) - .unwrap(); - - // get all tokens in order: - let expected = vec![token_id1.clone(), token_id2.clone(), token_id3.clone()]; - let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap(); - assert_eq!(&expected, &tokens.tokens); - // paginate - let tokens = contract.all_tokens(deps.as_ref(), None, Some(2)).unwrap(); - assert_eq!(&expected[..2], &tokens.tokens[..]); - let tokens = contract - .all_tokens(deps.as_ref(), Some(expected[1].clone()), None) - .unwrap(); - assert_eq!(&expected[2..], &tokens.tokens[..]); - - // get by owner - let by_ceres = vec![token_id2]; - let by_demeter = vec![token_id1, token_id3]; - // all tokens by owner - let tokens = contract - .tokens(deps.as_ref(), demeter.clone(), None, None) - .unwrap(); - assert_eq!(&by_demeter, &tokens.tokens); - let tokens = contract.tokens(deps.as_ref(), ceres, None, None).unwrap(); - assert_eq!(&by_ceres, &tokens.tokens); - - // paginate for demeter - let tokens = contract - .tokens(deps.as_ref(), demeter.clone(), None, Some(1)) - .unwrap(); - assert_eq!(&by_demeter[..1], &tokens.tokens[..]); - let tokens = contract - .tokens(deps.as_ref(), demeter, Some(by_demeter[0].clone()), Some(3)) - .unwrap(); - assert_eq!(&by_demeter[1..], &tokens.tokens[..]); -} diff --git a/cosmwasm/contracts/cw721-base/src/error.rs b/cosmwasm/contracts/cw721-base/src/error.rs deleted file mode 100644 index db1ceaad9..000000000 --- a/cosmwasm/contracts/cw721-base/src/error.rs +++ /dev/null @@ -1,20 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("token_id already claimed")] - Claimed {}, - - #[error("Cannot set approval that is already expired")] - Expired {}, - - #[error("Approval not found for: {spender}")] - ApprovalNotFound { spender: String }, -} diff --git a/cosmwasm/contracts/cw721-base/src/execute.rs b/cosmwasm/contracts/cw721-base/src/execute.rs deleted file mode 100644 index 66d88e76a..000000000 --- a/cosmwasm/contracts/cw721-base/src/execute.rs +++ /dev/null @@ -1,397 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; - -use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; - -use cw2::set_contract_version; -use cw721::{ContractInfoResponse, CustomMsg, Cw721Execute, Cw721ReceiveMsg, Expiration}; - -use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, MintMsg}; -use crate::state::{Approval, Cw721Contract, TokenInfo}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw721-base"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -impl<'a, T, C> Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - pub fn instantiate( - &self, - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> StdResult> { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - let info = ContractInfoResponse { - name: msg.name, - symbol: msg.symbol, - }; - self.contract_info.save(deps.storage, &info)?; - let minter = deps.api.addr_validate(&msg.minter)?; - self.minter.save(deps.storage, &minter)?; - Ok(Response::default()) - } - - pub fn execute( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, - ) -> Result, ContractError> { - match msg { - ExecuteMsg::Mint(msg) => self.mint(deps, env, info, msg), - ExecuteMsg::Approve { - spender, - token_id, - expires, - } => self.approve(deps, env, info, spender, token_id, expires), - ExecuteMsg::Revoke { spender, token_id } => { - self.revoke(deps, env, info, spender, token_id) - } - ExecuteMsg::ApproveAll { operator, expires } => { - self.approve_all(deps, env, info, operator, expires) - } - ExecuteMsg::RevokeAll { operator } => self.revoke_all(deps, env, info, operator), - ExecuteMsg::TransferNft { - recipient, - token_id, - } => self.transfer_nft(deps, env, info, recipient, token_id), - ExecuteMsg::SendNft { - contract, - token_id, - msg, - } => self.send_nft(deps, env, info, contract, token_id, msg), - ExecuteMsg::Burn { token_id } => self.burn(deps, env, info, token_id), - } - } -} - -// TODO pull this into some sort of trait extension?? -impl<'a, T, C> Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - pub fn mint( - &self, - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: MintMsg, - ) -> Result, ContractError> { - let minter = self.minter.load(deps.storage)?; - - if info.sender != minter { - return Err(ContractError::Unauthorized {}); - } - - // create the token - let token = TokenInfo { - owner: deps.api.addr_validate(&msg.owner)?, - approvals: vec![], - token_uri: msg.token_uri, - extension: msg.extension, - }; - self.tokens - .update(deps.storage, &msg.token_id, |old| match old { - Some(_) => Err(ContractError::Claimed {}), - None => Ok(token), - })?; - - self.increment_tokens(deps.storage)?; - - Ok(Response::new() - .add_attribute("action", "mint") - .add_attribute("minter", info.sender) - .add_attribute("token_id", msg.token_id)) - } -} - -impl<'a, T, C> Cw721Execute for Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - type Err = ContractError; - - fn transfer_nft( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - recipient: String, - token_id: String, - ) -> Result, ContractError> { - self._transfer_nft(deps, &env, &info, &recipient, &token_id)?; - - Ok(Response::new() - .add_attribute("action", "transfer_nft") - .add_attribute("sender", info.sender) - .add_attribute("recipient", recipient) - .add_attribute("token_id", token_id)) - } - - fn send_nft( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - contract: String, - token_id: String, - msg: Binary, - ) -> Result, ContractError> { - // Transfer token - self._transfer_nft(deps, &env, &info, &contract, &token_id)?; - - let send = Cw721ReceiveMsg { - sender: info.sender.to_string(), - token_id: token_id.clone(), - msg, - }; - - // Send message - Ok(Response::new() - .add_message(send.into_cosmos_msg(contract.clone())?) - .add_attribute("action", "send_nft") - .add_attribute("sender", info.sender) - .add_attribute("recipient", contract) - .add_attribute("token_id", token_id)) - } - - fn approve( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - spender: String, - token_id: String, - expires: Option, - ) -> Result, ContractError> { - self._update_approvals(deps, &env, &info, &spender, &token_id, true, expires)?; - - Ok(Response::new() - .add_attribute("action", "approve") - .add_attribute("sender", info.sender) - .add_attribute("spender", spender) - .add_attribute("token_id", token_id)) - } - - fn revoke( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - spender: String, - token_id: String, - ) -> Result, ContractError> { - self._update_approvals(deps, &env, &info, &spender, &token_id, false, None)?; - - Ok(Response::new() - .add_attribute("action", "revoke") - .add_attribute("sender", info.sender) - .add_attribute("spender", spender) - .add_attribute("token_id", token_id)) - } - - fn approve_all( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - operator: String, - expires: Option, - ) -> Result, ContractError> { - // reject expired data as invalid - let expires = expires.unwrap_or_default(); - if expires.is_expired(&env.block) { - return Err(ContractError::Expired {}); - } - - // set the operator for us - let operator_addr = deps.api.addr_validate(&operator)?; - self.operators - .save(deps.storage, (&info.sender, &operator_addr), &expires)?; - - Ok(Response::new() - .add_attribute("action", "approve_all") - .add_attribute("sender", info.sender) - .add_attribute("operator", operator)) - } - - fn revoke_all( - &self, - deps: DepsMut, - _env: Env, - info: MessageInfo, - operator: String, - ) -> Result, ContractError> { - let operator_addr = deps.api.addr_validate(&operator)?; - self.operators - .remove(deps.storage, (&info.sender, &operator_addr)); - - Ok(Response::new() - .add_attribute("action", "revoke_all") - .add_attribute("sender", info.sender) - .add_attribute("operator", operator)) - } - - fn burn( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - token_id: String, - ) -> Result, ContractError> { - let token = self.tokens.load(deps.storage, &token_id)?; - self.check_can_send(deps.as_ref(), &env, &info, &token)?; - - self.tokens.remove(deps.storage, &token_id)?; - self.decrement_tokens(deps.storage)?; - - Ok(Response::new() - .add_attribute("action", "burn") - .add_attribute("sender", info.sender) - .add_attribute("token_id", token_id)) - } -} - -// helpers -impl<'a, T, C> Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - pub fn _transfer_nft( - &self, - deps: DepsMut, - env: &Env, - info: &MessageInfo, - recipient: &str, - token_id: &str, - ) -> Result, ContractError> { - let mut token = self.tokens.load(deps.storage, token_id)?; - // ensure we have permissions - self.check_can_send(deps.as_ref(), env, info, &token)?; - // set owner and remove existing approvals - token.owner = deps.api.addr_validate(recipient)?; - token.approvals = vec![]; - self.tokens.save(deps.storage, token_id, &token)?; - Ok(token) - } - - #[allow(clippy::too_many_arguments)] - pub fn _update_approvals( - &self, - deps: DepsMut, - env: &Env, - info: &MessageInfo, - spender: &str, - token_id: &str, - // if add == false, remove. if add == true, remove then set with this expiration - add: bool, - expires: Option, - ) -> Result, ContractError> { - let mut token = self.tokens.load(deps.storage, token_id)?; - // ensure we have permissions - self.check_can_approve(deps.as_ref(), env, info, &token)?; - - // update the approval list (remove any for the same spender before adding) - let spender_addr = deps.api.addr_validate(spender)?; - token.approvals = token - .approvals - .into_iter() - .filter(|apr| apr.spender != spender_addr) - .collect(); - - // only difference between approve and revoke - if add { - // reject expired data as invalid - let expires = expires.unwrap_or_default(); - if expires.is_expired(&env.block) { - return Err(ContractError::Expired {}); - } - let approval = Approval { - spender: spender_addr, - expires, - }; - token.approvals.push(approval); - } - - self.tokens.save(deps.storage, token_id, &token)?; - - Ok(token) - } - - /// returns true iff the sender can execute approve or reject on the contract - pub fn check_can_approve( - &self, - deps: Deps, - env: &Env, - info: &MessageInfo, - token: &TokenInfo, - ) -> Result<(), ContractError> { - // owner can approve - if token.owner == info.sender { - return Ok(()); - } - // operator can approve - let op = self - .operators - .may_load(deps.storage, (&token.owner, &info.sender))?; - match op { - Some(ex) => { - if ex.is_expired(&env.block) { - Err(ContractError::Unauthorized {}) - } else { - Ok(()) - } - } - None => Err(ContractError::Unauthorized {}), - } - } - - /// returns true iff the sender can transfer ownership of the token - pub fn check_can_send( - &self, - deps: Deps, - env: &Env, - info: &MessageInfo, - token: &TokenInfo, - ) -> Result<(), ContractError> { - // owner can send - if token.owner == info.sender { - return Ok(()); - } - - // any non-expired token approval can send - if token - .approvals - .iter() - .any(|apr| apr.spender == info.sender && !apr.is_expired(&env.block)) - { - return Ok(()); - } - - // operator can send - let op = self - .operators - .may_load(deps.storage, (&token.owner, &info.sender))?; - match op { - Some(ex) => { - if ex.is_expired(&env.block) { - Err(ContractError::Unauthorized {}) - } else { - Ok(()) - } - } - None => Err(ContractError::Unauthorized {}), - } - } -} diff --git a/cosmwasm/contracts/cw721-base/src/helpers.rs b/cosmwasm/contracts/cw721-base/src/helpers.rs deleted file mode 100644 index 437132f5d..000000000 --- a/cosmwasm/contracts/cw721-base/src/helpers.rs +++ /dev/null @@ -1,179 +0,0 @@ -use crate::{ExecuteMsg, QueryMsg}; -use cosmwasm_std::{to_binary, Addr, CosmosMsg, QuerierWrapper, StdResult, WasmMsg, WasmQuery}; -use cw721::{ - AllNftInfoResponse, Approval, ApprovalResponse, ApprovalsResponse, ContractInfoResponse, - NftInfoResponse, NumTokensResponse, OperatorsResponse, OwnerOfResponse, TokensResponse, -}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct Cw721Contract(pub Addr); - -#[allow(dead_code)] -impl Cw721Contract { - pub fn addr(&self) -> Addr { - self.0.clone() - } - - pub fn call(&self, msg: ExecuteMsg) -> StdResult { - let msg = to_binary(&msg)?; - Ok(WasmMsg::Execute { - contract_addr: self.addr().into(), - msg, - funds: vec![], - } - .into()) - } - - pub fn query( - &self, - querier: &QuerierWrapper, - req: QueryMsg, - ) -> StdResult { - let query = WasmQuery::Smart { - contract_addr: self.addr().into(), - msg: to_binary(&req)?, - } - .into(); - querier.query(&query) - } - - /*** queries ***/ - - pub fn owner_of>( - &self, - querier: &QuerierWrapper, - token_id: T, - include_expired: bool, - ) -> StdResult { - let req = QueryMsg::OwnerOf { - token_id: token_id.into(), - include_expired: Some(include_expired), - }; - self.query(querier, req) - } - - pub fn approval>( - &self, - querier: &QuerierWrapper, - token_id: T, - spender: T, - include_expired: Option, - ) -> StdResult { - let req = QueryMsg::Approval { - token_id: token_id.into(), - spender: spender.into(), - include_expired, - }; - let res: ApprovalResponse = self.query(querier, req)?; - Ok(res) - } - - pub fn approvals>( - &self, - querier: &QuerierWrapper, - token_id: T, - include_expired: Option, - ) -> StdResult { - let req = QueryMsg::Approvals { - token_id: token_id.into(), - include_expired, - }; - let res: ApprovalsResponse = self.query(querier, req)?; - Ok(res) - } - - pub fn all_operators>( - &self, - querier: &QuerierWrapper, - owner: T, - include_expired: bool, - start_after: Option, - limit: Option, - ) -> StdResult> { - let req = QueryMsg::AllOperators { - owner: owner.into(), - include_expired: Some(include_expired), - start_after, - limit, - }; - let res: OperatorsResponse = self.query(querier, req)?; - Ok(res.operators) - } - - pub fn num_tokens(&self, querier: &QuerierWrapper) -> StdResult { - let req = QueryMsg::NumTokens {}; - let res: NumTokensResponse = self.query(querier, req)?; - Ok(res.count) - } - - /// With metadata extension - pub fn contract_info(&self, querier: &QuerierWrapper) -> StdResult { - let req = QueryMsg::ContractInfo {}; - self.query(querier, req) - } - - /// With metadata extension - pub fn nft_info, U: DeserializeOwned>( - &self, - querier: &QuerierWrapper, - token_id: T, - ) -> StdResult> { - let req = QueryMsg::NftInfo { - token_id: token_id.into(), - }; - self.query(querier, req) - } - - /// With metadata extension - pub fn all_nft_info, U: DeserializeOwned>( - &self, - querier: &QuerierWrapper, - token_id: T, - include_expired: bool, - ) -> StdResult> { - let req = QueryMsg::AllNftInfo { - token_id: token_id.into(), - include_expired: Some(include_expired), - }; - self.query(querier, req) - } - - /// With enumerable extension - pub fn tokens>( - &self, - querier: &QuerierWrapper, - owner: T, - start_after: Option, - limit: Option, - ) -> StdResult { - let req = QueryMsg::Tokens { - owner: owner.into(), - start_after, - limit, - }; - self.query(querier, req) - } - - /// With enumerable extension - pub fn all_tokens( - &self, - querier: &QuerierWrapper, - start_after: Option, - limit: Option, - ) -> StdResult { - let req = QueryMsg::AllTokens { start_after, limit }; - self.query(querier, req) - } - - /// returns true if the contract supports the metadata extension - pub fn has_metadata(&self, querier: &QuerierWrapper) -> bool { - self.contract_info(querier).is_ok() - } - - /// returns true if the contract supports the enumerable extension - pub fn has_enumerable(&self, querier: &QuerierWrapper) -> bool { - self.tokens(querier, self.addr(), None, Some(1)).is_ok() - } -} diff --git a/cosmwasm/contracts/cw721-base/src/lib.rs b/cosmwasm/contracts/cw721-base/src/lib.rs deleted file mode 100644 index 4404336e9..000000000 --- a/cosmwasm/contracts/cw721-base/src/lib.rs +++ /dev/null @@ -1,51 +0,0 @@ -mod contract_tests; -mod error; -mod execute; -pub mod helpers; -pub mod msg; -mod query; -pub mod state; - -pub use crate::error::ContractError; -pub use crate::msg::{ExecuteMsg, InstantiateMsg, MintMsg, MinterResponse, QueryMsg}; -pub use crate::state::Cw721Contract; -use cosmwasm_std::Empty; - -pub type Extension = Option; - -#[cfg(not(feature = "library"))] -pub mod entry { - use super::*; - - use cosmwasm_std::entry_point; - use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; - - // This makes a conscious choice on the various generics used by the contract - #[entry_point] - pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, - ) -> StdResult { - let tract = Cw721Contract::::default(); - tract.instantiate(deps, env, info, msg) - } - - #[entry_point] - pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, - ) -> Result { - let tract = Cw721Contract::::default(); - tract.execute(deps, env, info, msg) - } - - #[entry_point] - pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - let tract = Cw721Contract::::default(); - tract.query(deps, env, msg) - } -} diff --git a/cosmwasm/contracts/cw721-base/src/msg.rs b/cosmwasm/contracts/cw721-base/src/msg.rs deleted file mode 100644 index 6d2994e7b..000000000 --- a/cosmwasm/contracts/cw721-base/src/msg.rs +++ /dev/null @@ -1,154 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Binary; -use cw721::Expiration; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg { - /// Name of the NFT contract - pub name: String, - /// Symbol of the NFT contract - pub symbol: String, - - /// The minter is the only one who can create new NFTs. - /// This is designed for a base NFT that is controlled by an external program - /// or contract. You will likely replace this with custom logic in custom NFTs - pub minter: String, -} - -/// This is like Cw721ExecuteMsg but we add a Mint command for an owner -/// to make this stand-alone. You will likely want to remove mint and -/// use other control logic in any contract that inherits this. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - /// Transfer is a base message to move a token to another account without triggering actions - TransferNft { recipient: String, token_id: String }, - /// Send is a base message to transfer a token to a contract and trigger an action - /// on the receiving contract. - SendNft { - contract: String, - token_id: String, - msg: Binary, - }, - /// Allows operator to transfer / send the token from the owner's account. - /// If expiration is set, then this allowance has a time/height limit - Approve { - spender: String, - token_id: String, - expires: Option, - }, - /// Remove previously granted Approval - Revoke { spender: String, token_id: String }, - /// Allows operator to transfer / send any token from the owner's account. - /// If expiration is set, then this allowance has a time/height limit - ApproveAll { - operator: String, - expires: Option, - }, - /// Remove previously granted ApproveAll permission - RevokeAll { operator: String }, - - /// Mint a new NFT, can only be called by the contract minter - Mint(MintMsg), - - /// Burn an NFT the sender has access to - Burn { token_id: String }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct MintMsg { - /// Unique ID of the NFT - pub token_id: String, - /// The owner of the newly minter NFT - pub owner: String, - /// Universal resource identifier for this NFT - /// Should point to a JSON file that conforms to the ERC721 - /// Metadata JSON Schema - pub token_uri: Option, - /// Any custom extension used by this contract - pub extension: T, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Return the owner of the given token, error if token does not exist - /// Return type: OwnerOfResponse - OwnerOf { - token_id: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - }, - - /// Return operator that can access all of the owner's tokens. - /// Return type: `ApprovalResponse` - Approval { - token_id: String, - spender: String, - include_expired: Option, - }, - - /// Return approvals that a token has - /// Return type: `ApprovalsResponse` - Approvals { - token_id: String, - include_expired: Option, - }, - - /// List all operators that can access all of the owner's tokens - /// Return type: `OperatorsResponse` - AllOperators { - owner: String, - /// unset or false will filter out expired items, you must set to true to see them - include_expired: Option, - start_after: Option, - limit: Option, - }, - /// Total number of tokens issued - NumTokens {}, - - /// With MetaData Extension. - /// Returns top-level metadata about the contract: `ContractInfoResponse` - ContractInfo {}, - /// With MetaData Extension. - /// Returns metadata about one particular token, based on *ERC721 Metadata JSON Schema* - /// but directly from the contract: `NftInfoResponse` - NftInfo { - token_id: String, - }, - /// With MetaData Extension. - /// Returns the result of both `NftInfo` and `OwnerOf` as one query as an optimization - /// for clients: `AllNftInfo` - AllNftInfo { - token_id: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - }, - - /// With Enumerable extension. - /// Returns all tokens owned by the given address, [] if unset. - /// Return type: TokensResponse. - Tokens { - owner: String, - start_after: Option, - limit: Option, - }, - /// With Enumerable extension. - /// Requires pagination. Lists all token_ids controlled by the contract. - /// Return type: TokensResponse. - AllTokens { - start_after: Option, - limit: Option, - }, - - // Return the minter - Minter {}, -} - -/// Shows who can mint these tokens -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct MinterResponse { - pub minter: String, -} diff --git a/cosmwasm/contracts/cw721-base/src/query.rs b/cosmwasm/contracts/cw721-base/src/query.rs deleted file mode 100644 index 7318529e4..000000000 --- a/cosmwasm/contracts/cw721-base/src/query.rs +++ /dev/null @@ -1,299 +0,0 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; - -use cosmwasm_std::{to_binary, Binary, BlockInfo, Deps, Env, Order, StdError, StdResult}; - -use cw0::maybe_addr; -use cw721::{ - AllNftInfoResponse, ApprovalResponse, ApprovalsResponse, ContractInfoResponse, CustomMsg, - Cw721Query, Expiration, NftInfoResponse, NumTokensResponse, OperatorsResponse, OwnerOfResponse, - TokensResponse, -}; -use cw_storage_plus::Bound; - -use crate::msg::{MinterResponse, QueryMsg}; -use crate::state::{Approval, Cw721Contract, TokenInfo}; - -const DEFAULT_LIMIT: u32 = 10; -const MAX_LIMIT: u32 = 30; - -impl<'a, T, C> Cw721Query for Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - fn contract_info(&self, deps: Deps) -> StdResult { - self.contract_info.load(deps.storage) - } - - fn num_tokens(&self, deps: Deps) -> StdResult { - let count = self.token_count(deps.storage)?; - Ok(NumTokensResponse { count }) - } - - fn nft_info(&self, deps: Deps, token_id: String) -> StdResult> { - let info = self.tokens.load(deps.storage, &token_id)?; - Ok(NftInfoResponse { - token_uri: info.token_uri, - extension: info.extension, - }) - } - - fn owner_of( - &self, - deps: Deps, - env: Env, - token_id: String, - include_expired: bool, - ) -> StdResult { - let info = self.tokens.load(deps.storage, &token_id)?; - Ok(OwnerOfResponse { - owner: info.owner.to_string(), - approvals: humanize_approvals(&env.block, &info, include_expired), - }) - } - - /// operators returns all operators owner given access to - fn operators( - &self, - deps: Deps, - env: Env, - owner: String, - include_expired: bool, - start_after: Option, - limit: Option, - ) -> StdResult { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start_addr = maybe_addr(deps.api, start_after)?; - let start = start_addr.map(|addr| Bound::exclusive(addr.as_ref())); - - let owner_addr = deps.api.addr_validate(&owner)?; - let res: StdResult> = self - .operators - .prefix(&owner_addr) - .range(deps.storage, start, None, Order::Ascending) - .filter(|r| { - include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block) - }) - .take(limit) - .map(parse_approval) - .collect(); - Ok(OperatorsResponse { operators: res? }) - } - - fn approval( - &self, - deps: Deps, - env: Env, - token_id: String, - spender: String, - include_expired: bool, - ) -> StdResult { - let token = self.tokens.load(deps.storage, &token_id)?; - let filtered: Vec<_> = token - .approvals - .into_iter() - .filter(|t| t.spender == spender) - .filter(|t| include_expired || !t.is_expired(&env.block)) - .map(|a| cw721::Approval { - spender: a.spender.into_string(), - expires: a.expires, - }) - .collect(); - - if filtered.is_empty() { - return Err(StdError::not_found("Approval not found")); - } - // we expect only one item - let approval = filtered[0].clone(); - - Ok(ApprovalResponse { approval }) - } - - /// approvals returns all approvals owner given access to - fn approvals( - &self, - deps: Deps, - env: Env, - token_id: String, - include_expired: bool, - ) -> StdResult { - let token = self.tokens.load(deps.storage, &token_id)?; - let approvals: Vec<_> = token - .approvals - .into_iter() - .filter(|t| include_expired || !t.is_expired(&env.block)) - .map(|a| cw721::Approval { - spender: a.spender.into_string(), - expires: a.expires, - }) - .collect(); - - Ok(ApprovalsResponse { approvals }) - } - - fn tokens( - &self, - deps: Deps, - owner: String, - start_after: Option, - limit: Option, - ) -> StdResult { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); - - let owner_addr = deps.api.addr_validate(&owner)?; - let pks: Vec<_> = self - .tokens - .idx - .owner - .prefix(owner_addr) - .keys(deps.storage, start, None, Order::Ascending) - .take(limit) - .collect(); - - let res: Result, _> = pks.iter().map(|v| String::from_utf8(v.to_vec())).collect(); - let tokens = res.map_err(StdError::invalid_utf8)?; - Ok(TokensResponse { tokens }) - } - - fn all_tokens( - &self, - deps: Deps, - start_after: Option, - limit: Option, - ) -> StdResult { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(Bound::exclusive); - - let tokens: StdResult> = self - .tokens - .range(deps.storage, start, None, Order::Ascending) - .take(limit) - .map(|item| item.map(|(k, _)| String::from_utf8_lossy(&k).to_string())) - .collect(); - Ok(TokensResponse { tokens: tokens? }) - } - - fn all_nft_info( - &self, - deps: Deps, - env: Env, - token_id: String, - include_expired: bool, - ) -> StdResult> { - let info = self.tokens.load(deps.storage, &token_id)?; - Ok(AllNftInfoResponse { - access: OwnerOfResponse { - owner: info.owner.to_string(), - approvals: humanize_approvals(&env.block, &info, include_expired), - }, - info: NftInfoResponse { - token_uri: info.token_uri, - extension: info.extension, - }, - }) - } -} - -impl<'a, T, C> Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - pub fn minter(&self, deps: Deps) -> StdResult { - let minter_addr = self.minter.load(deps.storage)?; - Ok(MinterResponse { - minter: minter_addr.to_string(), - }) - } - - pub fn query(&self, deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Minter {} => to_binary(&self.minter(deps)?), - QueryMsg::ContractInfo {} => to_binary(&self.contract_info(deps)?), - QueryMsg::NftInfo { token_id } => to_binary(&self.nft_info(deps, token_id)?), - QueryMsg::OwnerOf { - token_id, - include_expired, - } => { - to_binary(&self.owner_of(deps, env, token_id, include_expired.unwrap_or(false))?) - } - QueryMsg::AllNftInfo { - token_id, - include_expired, - } => to_binary(&self.all_nft_info( - deps, - env, - token_id, - include_expired.unwrap_or(false), - )?), - QueryMsg::AllOperators { - owner, - include_expired, - start_after, - limit, - } => to_binary(&self.operators( - deps, - env, - owner, - include_expired.unwrap_or(false), - start_after, - limit, - )?), - QueryMsg::NumTokens {} => to_binary(&self.num_tokens(deps)?), - QueryMsg::Tokens { - owner, - start_after, - limit, - } => to_binary(&self.tokens(deps, owner, start_after, limit)?), - QueryMsg::AllTokens { start_after, limit } => { - to_binary(&self.all_tokens(deps, start_after, limit)?) - } - QueryMsg::Approval { - token_id, - spender, - include_expired, - } => to_binary(&self.approval( - deps, - env, - token_id, - spender, - include_expired.unwrap_or(false), - )?), - QueryMsg::Approvals { - token_id, - include_expired, - } => { - to_binary(&self.approvals(deps, env, token_id, include_expired.unwrap_or(false))?) - } - } - } -} - -type Record> = (Vec, V); -fn parse_approval(item: StdResult>) -> StdResult { - item.and_then(|(k, expires)| { - let spender = String::from_utf8(k)?; - Ok(cw721::Approval { spender, expires }) - }) -} - -fn humanize_approvals( - block: &BlockInfo, - info: &TokenInfo, - include_expired: bool, -) -> Vec { - info.approvals - .iter() - .filter(|apr| include_expired || !apr.is_expired(block)) - .map(humanize_approval) - .collect() -} - -fn humanize_approval(approval: &Approval) -> cw721::Approval { - cw721::Approval { - spender: approval.spender.to_string(), - expires: approval.expires, - } -} diff --git a/cosmwasm/contracts/cw721-base/src/state.rs b/cosmwasm/contracts/cw721-base/src/state.rs deleted file mode 100644 index 466618d85..000000000 --- a/cosmwasm/contracts/cw721-base/src/state.rs +++ /dev/null @@ -1,141 +0,0 @@ -use schemars::JsonSchema; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use std::marker::PhantomData; - -use cosmwasm_std::{Addr, BlockInfo, StdResult, Storage}; - -use cw721::{ContractInfoResponse, CustomMsg, Cw721, Expiration}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; - -pub struct Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, -{ - pub contract_info: Item<'a, ContractInfoResponse>, - pub minter: Item<'a, Addr>, - pub token_count: Item<'a, u64>, - /// Stored as (granter, operator) giving operator full control over granter's account - pub operators: Map<'a, (&'a Addr, &'a Addr), Expiration>, - pub tokens: IndexedMap<'a, &'a str, TokenInfo, TokenIndexes<'a, T>>, - - pub(crate) _custom_response: PhantomData, -} - -// This is a signal, the implementations are in other files -impl<'a, T, C> Cw721 for Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ -} - -impl Default for Cw721Contract<'static, T, C> -where - T: Serialize + DeserializeOwned + Clone, -{ - fn default() -> Self { - Self::new( - "nft_info", - "minter", - "num_tokens", - "operators", - "tokens", - "tokens__owner", - ) - } -} - -impl<'a, T, C> Cw721Contract<'a, T, C> -where - T: Serialize + DeserializeOwned + Clone, -{ - fn new( - contract_key: &'a str, - minter_key: &'a str, - token_count_key: &'a str, - operator_key: &'a str, - tokens_key: &'a str, - tokens_owner_key: &'a str, - ) -> Self { - let indexes = TokenIndexes { - owner: MultiIndex::new(token_owner_idx, tokens_key, tokens_owner_key), - }; - Self { - contract_info: Item::new(contract_key), - minter: Item::new(minter_key), - token_count: Item::new(token_count_key), - operators: Map::new(operator_key), - tokens: IndexedMap::new(tokens_key, indexes), - _custom_response: PhantomData, - } - } - - pub fn token_count(&self, storage: &dyn Storage) -> StdResult { - Ok(self.token_count.may_load(storage)?.unwrap_or_default()) - } - - pub fn increment_tokens(&self, storage: &mut dyn Storage) -> StdResult { - let val = self.token_count(storage)? + 1; - self.token_count.save(storage, &val)?; - Ok(val) - } - - pub fn decrement_tokens(&self, storage: &mut dyn Storage) -> StdResult { - let val = self.token_count(storage)? - 1; - self.token_count.save(storage, &val)?; - Ok(val) - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct TokenInfo { - /// The owner of the newly minted NFT - pub owner: Addr, - /// Approvals are stored here, as we clear them all upon transfer and cannot accumulate much - pub approvals: Vec, - - /// Universal resource identifier for this NFT - /// Should point to a JSON file that conforms to the ERC721 - /// Metadata JSON Schema - pub token_uri: Option, - - /// You can add any custom metadata here when you extend cw721-base - pub extension: T, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Approval { - /// Account that can transfer/send the token - pub spender: Addr, - /// When the Approval expires (maybe Expiration::never) - pub expires: Expiration, -} - -impl Approval { - pub fn is_expired(&self, block: &BlockInfo) -> bool { - self.expires.is_expired(block) - } -} - -pub struct TokenIndexes<'a, T> -where - T: Serialize + DeserializeOwned + Clone, -{ - // pk goes to second tuple element - pub owner: MultiIndex<'a, (Addr, Vec), TokenInfo>, -} - -impl<'a, T> IndexList> for TokenIndexes<'a, T> -where - T: Serialize + DeserializeOwned + Clone, -{ - fn get_indexes(&'_ self) -> Box>> + '_> { - let v: Vec<&dyn Index>> = vec![&self.owner]; - Box::new(v.into_iter()) - } -} - -pub fn token_owner_idx(d: &TokenInfo, k: Vec) -> (Addr, Vec) { - (d.owner.clone(), k) -} diff --git a/cosmwasm/contracts/cw721-wrapped/.cargo/config b/cosmwasm/contracts/cw721-wrapped/.cargo/config deleted file mode 100644 index 7d1a066c8..000000000 --- a/cosmwasm/contracts/cw721-wrapped/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" diff --git a/cosmwasm/contracts/cw721-wrapped/Cargo.toml b/cosmwasm/contracts/cw721-wrapped/Cargo.toml deleted file mode 100644 index 0e2bf97f5..000000000 --- a/cosmwasm/contracts/cw721-wrapped/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "cw721-wrapped" -version = "0.10.1" -edition = "2018" -description = "Wrapped CW721 token contract" - -exclude = [ - "artifacts/*", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cw2 = { version = "0.8.0" } -cw721-base = { path = "../../contracts/cw721-base", version = "0.10.0", features = ["library"] } -cw721 = { path = "../../packages/cw721", version = "0.10.1" } -cosmwasm-std = { version = "0.16.0" } -cosmwasm-storage = { version = "0.16.0" } -schemars = "0.8.6" -serde = { version = "1.0.130", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta2" } diff --git a/cosmwasm/contracts/cw721-wrapped/examples/schema.rs b/cosmwasm/contracts/cw721-wrapped/examples/schema.rs deleted file mode 100644 index 567a76ee0..000000000 --- a/cosmwasm/contracts/cw721-wrapped/examples/schema.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::{ - env::current_dir, - fs::create_dir_all, -}; - -use cosmwasm_schema::{ - export_schema, - export_schema_with_title, - remove_schemas, - schema_for, -}; - -use cw721::{ - AllNftInfoResponse, - ApprovalResponse, - ApprovalsResponse, - ContractInfoResponse, - NftInfoResponse, - NumTokensResponse, - OperatorsResponse, - OwnerOfResponse, - TokensResponse, -}; -use cw721_base::{ - ExecuteMsg, - Extension, - InstantiateMsg, - MinterResponse, - QueryMsg, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema_with_title(&schema_for!(ExecuteMsg<()>), &out_dir, "ExecuteMsg"); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema_with_title( - &schema_for!(AllNftInfoResponse), - &out_dir, - "AllNftInfoResponse", - ); - export_schema(&schema_for!(ApprovalResponse), &out_dir); - export_schema(&schema_for!(ApprovalsResponse), &out_dir); - export_schema(&schema_for!(OperatorsResponse), &out_dir); - export_schema(&schema_for!(ContractInfoResponse), &out_dir); - export_schema(&schema_for!(MinterResponse), &out_dir); - export_schema_with_title( - &schema_for!(NftInfoResponse), - &out_dir, - "NftInfoResponse", - ); - export_schema(&schema_for!(NumTokensResponse), &out_dir); - export_schema(&schema_for!(OwnerOfResponse), &out_dir); - export_schema(&schema_for!(TokensResponse), &out_dir); -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/all_nft_info_response.json b/cosmwasm/contracts/cw721-wrapped/schema/all_nft_info_response.json deleted file mode 100644 index 152c3cf57..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/all_nft_info_response.json +++ /dev/null @@ -1,234 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllNftInfoResponse", - "type": "object", - "required": [ - "access", - "info" - ], - "properties": { - "access": { - "description": "Who can transfer the token", - "allOf": [ - { - "$ref": "#/definitions/OwnerOfResponse" - } - ] - }, - "info": { - "description": "Data on the token itself,", - "allOf": [ - { - "$ref": "#/definitions/NftInfoResponse_for_Nullable_Metadata" - } - ] - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Metadata": { - "type": "object", - "properties": { - "animation_url": { - "type": [ - "string", - "null" - ] - }, - "attributes": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Trait" - } - }, - "background_color": { - "type": [ - "string", - "null" - ] - }, - "description": { - "type": [ - "string", - "null" - ] - }, - "external_url": { - "type": [ - "string", - "null" - ] - }, - "image": { - "type": [ - "string", - "null" - ] - }, - "image_data": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": [ - "string", - "null" - ] - }, - "youtube_url": { - "type": [ - "string", - "null" - ] - } - } - }, - "NftInfoResponse_for_Nullable_Metadata": { - "type": "object", - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "anyOf": [ - { - "$ref": "#/definitions/Metadata" - }, - { - "type": "null" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - } - }, - "OwnerOfResponse": { - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Trait": { - "type": "object", - "required": [ - "trait_type", - "value" - ], - "properties": { - "display_type": { - "type": [ - "string", - "null" - ] - }, - "trait_type": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/approval_response.json b/cosmwasm/contracts/cw721-wrapped/schema/approval_response.json deleted file mode 100644 index 4f45b42e9..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/approval_response.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalResponse", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "$ref": "#/definitions/Approval" - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/approvals_response.json b/cosmwasm/contracts/cw721-wrapped/schema/approvals_response.json deleted file mode 100644 index 8d8e39ea0..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/approvals_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalsResponse", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/contract_info_response.json b/cosmwasm/contracts/cw721-wrapped/schema/contract_info_response.json deleted file mode 100644 index a16712589..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/contract_info_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractInfoResponse", - "type": "object", - "required": [ - "name", - "symbol" - ], - "properties": { - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/execute_msg.json b/cosmwasm/contracts/cw721-wrapped/schema/execute_msg.json deleted file mode 100644 index 58e2593fd..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/execute_msg.json +++ /dev/null @@ -1,389 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "description": "This is like Cw721ExecuteMsg but we add a Mint command for an owner to make this stand-alone. You will likely want to remove mint and use other control logic in any contract that inherits this.", - "oneOf": [ - { - "description": "Transfer is a base message to move a token to another account without triggering actions", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer a token to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send any token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Mint a new NFT, can only be called by the contract minter", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "$ref": "#/definitions/MintMsg_for_Nullable_Metadata" - } - }, - "additionalProperties": false - }, - { - "description": "Burn an NFT the sender has access to", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Metadata": { - "type": "object", - "properties": { - "animation_url": { - "type": [ - "string", - "null" - ] - }, - "attributes": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Trait" - } - }, - "background_color": { - "type": [ - "string", - "null" - ] - }, - "description": { - "type": [ - "string", - "null" - ] - }, - "external_url": { - "type": [ - "string", - "null" - ] - }, - "image": { - "type": [ - "string", - "null" - ] - }, - "image_data": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": [ - "string", - "null" - ] - }, - "youtube_url": { - "type": [ - "string", - "null" - ] - } - } - }, - "MintMsg_for_Nullable_Metadata": { - "type": "object", - "required": [ - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "anyOf": [ - { - "$ref": "#/definitions/Metadata" - }, - { - "type": "null" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Trait": { - "type": "object", - "required": [ - "trait_type", - "value" - ], - "properties": { - "display_type": { - "type": [ - "string", - "null" - ] - }, - "trait_type": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/instantiate_msg.json b/cosmwasm/contracts/cw721-wrapped/schema/instantiate_msg.json deleted file mode 100644 index b024c82c1..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/instantiate_msg.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "minter", - "name", - "symbol" - ], - "properties": { - "minter": { - "description": "The minter is the only one who can create new NFTs. This is designed for a base NFT that is controlled by an external program or contract. You will likely replace this with custom logic in custom NFTs", - "type": "string" - }, - "name": { - "description": "Name of the NFT contract", - "type": "string" - }, - "symbol": { - "description": "Symbol of the NFT contract", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/minter_response.json b/cosmwasm/contracts/cw721-wrapped/schema/minter_response.json deleted file mode 100644 index a20e0d767..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/minter_response.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "description": "Shows who can mint these tokens", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/nft_info_response.json b/cosmwasm/contracts/cw721-wrapped/schema/nft_info_response.json deleted file mode 100644 index fbd9b9b0c..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/nft_info_response.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NftInfoResponse", - "type": "object", - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "anyOf": [ - { - "$ref": "#/definitions/Metadata" - }, - { - "type": "null" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "definitions": { - "Metadata": { - "type": "object", - "properties": { - "animation_url": { - "type": [ - "string", - "null" - ] - }, - "attributes": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Trait" - } - }, - "background_color": { - "type": [ - "string", - "null" - ] - }, - "description": { - "type": [ - "string", - "null" - ] - }, - "external_url": { - "type": [ - "string", - "null" - ] - }, - "image": { - "type": [ - "string", - "null" - ] - }, - "image_data": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": [ - "string", - "null" - ] - }, - "youtube_url": { - "type": [ - "string", - "null" - ] - } - } - }, - "Trait": { - "type": "object", - "required": [ - "trait_type", - "value" - ], - "properties": { - "display_type": { - "type": [ - "string", - "null" - ] - }, - "trait_type": { - "type": "string" - }, - "value": { - "type": "string" - } - } - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/num_tokens_response.json b/cosmwasm/contracts/cw721-wrapped/schema/num_tokens_response.json deleted file mode 100644 index 4647c23aa..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/num_tokens_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NumTokensResponse", - "type": "object", - "required": [ - "count" - ], - "properties": { - "count": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/operators_response.json b/cosmwasm/contracts/cw721-wrapped/schema/operators_response.json deleted file mode 100644 index 53703072c..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/operators_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/owner_of_response.json b/cosmwasm/contracts/cw721-wrapped/schema/owner_of_response.json deleted file mode 100644 index 1258d671f..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/owner_of_response.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OwnerOfResponse", - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/query_msg.json b/cosmwasm/contracts/cw721-wrapped/schema/query_msg.json deleted file mode 100644 index cd3a95619..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/query_msg.json +++ /dev/null @@ -1,285 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return the owner of the given token, error if token does not exist Return type: OwnerOfResponse", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Return operator that can access all of the owner's tokens. Return type: `ApprovalResponse`", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Return approvals that a token has Return type: `ApprovalsResponse`", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "List all operators that can access all of the owner's tokens Return type: `OperatorsResponse`", - "type": "object", - "required": [ - "all_operators" - ], - "properties": { - "all_operators": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired items, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Total number of tokens issued", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns top-level metadata about the contract: `ContractInfoResponse`", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns metadata about one particular token, based on *ERC721 Metadata JSON Schema* but directly from the contract: `NftInfoResponse`", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns the result of both `NftInfo` and `OwnerOf` as one query as an optimization for clients: `AllNftInfo`", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Returns all tokens owned by the given address, [] if unset. Return type: TokensResponse.", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Requires pagination. Lists all token_ids controlled by the contract. Return type: TokensResponse.", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/cosmwasm/contracts/cw721-wrapped/schema/tokens_response.json b/cosmwasm/contracts/cw721-wrapped/schema/tokens_response.json deleted file mode 100644 index b8e3d75b5..000000000 --- a/cosmwasm/contracts/cw721-wrapped/schema/tokens_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_from` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/src/lib.rs b/cosmwasm/contracts/cw721-wrapped/src/lib.rs deleted file mode 100644 index 95b60cba7..000000000 --- a/cosmwasm/contracts/cw721-wrapped/src/lib.rs +++ /dev/null @@ -1,203 +0,0 @@ -pub mod msg; -pub mod state; - -use schemars::JsonSchema; -use serde::{ - Deserialize, - Serialize, -}; - -pub use cosmwasm_std::to_binary; -use cosmwasm_std::Empty; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] -pub struct Trait { - pub display_type: Option, - pub trait_type: String, - pub value: String, -} - -pub type Extension = Option; - -pub type Cw721MetadataContract<'a> = cw721_base::Cw721Contract<'a, Extension, Empty>; -pub type ExecuteMsg = cw721_base::ExecuteMsg; - -#[cfg(not(feature = "library"))] -pub mod entry { - - use std::convert::TryInto; - - use crate::msg::{ - InstantiateMsg, - WrappedAssetInfoResponse, - }; - pub use crate::{ - msg::QueryMsg, - state::{ - wrapped_asset_info, - wrapped_asset_info_read, - WrappedAssetInfo, - }, - }; - - use super::*; - - use cosmwasm_std::{ - entry_point, - to_binary, - Binary, - CosmosMsg, - Deps, - DepsMut, - Env, - MessageInfo, - Response, - StdError, - StdResult, - WasmMsg, - }; - use cw721::Cw721Query; - - // version info for migration info - const CONTRACT_NAME: &str = "crates.io:cw721-wrapped"; - const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - - // This is a simple type to let us handle empty extensions - - // This makes a conscious choice on the various generics used by the contract - #[entry_point] - pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, - ) -> StdResult { - let base = Cw721MetadataContract::default(); - - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - let contract_info = cw721::ContractInfoResponse { - name: msg.name, - symbol: msg.symbol, - }; - base.contract_info.save(deps.storage, &contract_info)?; - let minter = deps.api.addr_validate(&msg.minter)?; - base.minter.save(deps.storage, &minter)?; - - // save wrapped asset info - let data = - WrappedAssetInfo { - asset_chain: msg.asset_chain, - asset_address: msg.asset_address.to_vec().try_into().map_err( - |_err| -> StdError { - StdError::GenericErr { - msg: "WrongSize".to_string(), - } - }, - )?, - bridge: deps.api.addr_canonicalize(&info.sender.as_str())?, - }; - wrapped_asset_info(deps.storage).save(&data)?; - - if let Some(mint_msg) = msg.mint { - execute(deps, env, info, ExecuteMsg::Mint(mint_msg)) - .map_err(|e| StdError::generic_err(format!("{}", e)))?; - } - - if let Some(hook) = msg.init_hook { - Ok( - Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: hook.contract_addr, - msg: hook.msg, - funds: vec![], - })), - ) - } else { - Ok(Response::default()) - } - } - - #[entry_point] - pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, - ) -> Result { - Cw721MetadataContract::default().execute(deps, env, info, msg) - } - - #[entry_point] - pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - let base = Cw721MetadataContract::default(); - match msg { - QueryMsg::WrappedAssetInfo {} => to_binary(&query_wrapped_asset_info(deps)?), - QueryMsg::OwnerOf { - token_id, - include_expired, - } => { - to_binary(&base.owner_of(deps, env, token_id, include_expired.unwrap_or(false))?) - } - QueryMsg::Approval { - token_id, - spender, - include_expired, - } => to_binary(&base.approval( - deps, - env, - token_id, - spender, - include_expired.unwrap_or(false), - )?), - QueryMsg::Approvals { - token_id, - include_expired, - } => { - to_binary(&base.approvals(deps, env, token_id, include_expired.unwrap_or(false))?) - } - QueryMsg::AllOperators { - owner, - include_expired, - start_after, - limit, - } => to_binary(&base.operators( - deps, - env, - owner, - include_expired.unwrap_or(false), - start_after, - limit, - )?), - QueryMsg::NumTokens {} => to_binary(&base.num_tokens(deps)?), - QueryMsg::Tokens { - owner, - start_after, - limit, - } => to_binary(&base.tokens(deps, owner, start_after, limit)?), - QueryMsg::AllTokens { start_after, limit } => { - to_binary(&base.all_tokens(deps, start_after, limit)?) - } - QueryMsg::Minter {} => to_binary(&base.minter(deps)?), - QueryMsg::ContractInfo {} => to_binary(&base.contract_info(deps)?), - QueryMsg::NftInfo { token_id } => to_binary(&base.nft_info(deps, token_id)?), - QueryMsg::AllNftInfo { - token_id, - include_expired, - } => to_binary(&base.all_nft_info( - deps, - env, - token_id, - include_expired.unwrap_or(false), - )?), - } - } - - pub fn query_wrapped_asset_info(deps: Deps) -> StdResult { - let info = wrapped_asset_info_read(deps.storage).load()?; - Ok(WrappedAssetInfoResponse { - asset_chain: info.asset_chain, - asset_address: info.asset_address, - bridge: deps.api.addr_humanize(&info.bridge)?, - }) - } -} diff --git a/cosmwasm/contracts/cw721-wrapped/src/msg.rs b/cosmwasm/contracts/cw721-wrapped/src/msg.rs deleted file mode 100644 index f5061c8a1..000000000 --- a/cosmwasm/contracts/cw721-wrapped/src/msg.rs +++ /dev/null @@ -1,135 +0,0 @@ -pub use cw721_base::MintMsg; -use schemars::JsonSchema; -use serde::{ - Deserialize, - Serialize, -}; - -use cosmwasm_std::{ - Addr, - Binary, - Empty, -}; - -pub use cw721_base::msg::ExecuteMsg; - -type HumanAddr = String; - -/// The cw721_base crate allows an extension point which we don't care about -pub type NoExt = Option; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg { - /// Name of the NFT contract - pub name: String, - /// Symbol of the NFT contract - pub symbol: String, - - /// Native chain of the NFT - pub asset_chain: u16, - - /// Native address of the NFT - pub asset_address: Binary, - - /// The minter is the only one who can create new NFTs. - /// This is designed for a base NFT that is controlled by an external program - /// or contract. You will likely replace this with custom logic in custom NFTs - pub minter: String, - - /// Mint a new NFT upon creation - pub mint: Option>, - - /// Generic callback - used to register the newly instantiated asset - pub init_hook: Option, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InitHook { - pub msg: Binary, - pub contract_addr: HumanAddr, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Generic information about the wrapped asset - WrappedAssetInfo {}, - - /// Return the owner of the given token, error if token does not exist - /// Return type: OwnerOfResponse - OwnerOf { - token_id: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - }, - - /// Return operator that can access all of the owner's tokens. - /// Return type: `ApprovalResponse` - Approval { - token_id: String, - spender: String, - include_expired: Option, - }, - - /// Return approvals that a token has - /// Return type: `ApprovalsResponse` - Approvals { - token_id: String, - include_expired: Option, - }, - - /// List all operators that can access all of the owner's tokens - /// Return type: `OperatorsResponse` - AllOperators { - owner: String, - /// unset or false will filter out expired items, you must set to true to see them - include_expired: Option, - start_after: Option, - limit: Option, - }, - /// Total number of tokens issued - NumTokens {}, - - /// With MetaData Extension. - /// Returns top-level metadata about the contract: `ContractInfoResponse` - ContractInfo {}, - - /// Returns metadata about one particular token, based on *ERC721 Metadata JSON Schema* - /// but directly from the contract: `NftInfoResponse` - NftInfo { - token_id: String, - }, - - /// Returns the result of both `NftInfo` and `OwnerOf` as one query as an optimization - /// for clients: `AllNftInfo` - AllNftInfo { - token_id: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - }, - - /// Returns all tokens owned by the given address, [] if unset. - /// Return type: TokensResponse. - Tokens { - owner: String, - start_after: Option, - limit: Option, - }, - - /// Requires pagination. Lists all token_ids controlled by the contract. - /// Return type: TokensResponse. - AllTokens { - start_after: Option, - limit: Option, - }, - - // Return the minter - Minter {}, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct WrappedAssetInfoResponse { - pub asset_chain: u16, // Asset chain id - pub asset_address: Binary, // Asset smart contract address in the original chain - pub bridge: Addr, // Bridge address, authorized to mint and burn wrapped tokens -} diff --git a/cosmwasm/contracts/cw721-wrapped/src/state.rs b/cosmwasm/contracts/cw721-wrapped/src/state.rs deleted file mode 100644 index 749242321..000000000 --- a/cosmwasm/contracts/cw721-wrapped/src/state.rs +++ /dev/null @@ -1,35 +0,0 @@ -use schemars::JsonSchema; -use serde::{ - Deserialize, - Serialize, -}; - -use cosmwasm_std::{ - Binary, - CanonicalAddr, - Storage, -}; -use cosmwasm_storage::{ - singleton, - singleton_read, - ReadonlySingleton, - Singleton, -}; - -pub const KEY_WRAPPED_ASSET: &[u8] = b"wrappedAsset"; - -// Created at initialization and reference original asset and bridge address -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct WrappedAssetInfo { - pub asset_chain: u16, // Asset chain id - pub asset_address: Binary, // Asset smart contract address on the original chain - pub bridge: CanonicalAddr, // Bridge address, authorized to mint and burn wrapped tokens -} - -pub fn wrapped_asset_info(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_WRAPPED_ASSET) -} - -pub fn wrapped_asset_info_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, KEY_WRAPPED_ASSET) -} diff --git a/cosmwasm/contracts/mock-bridge-integration/Cargo.toml b/cosmwasm/contracts/mock-bridge-integration/Cargo.toml index 2aaeef86a..15d2b1b69 100644 --- a/cosmwasm/contracts/mock-bridge-integration/Cargo.toml +++ b/cosmwasm/contracts/mock-bridge-integration/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "mock-bridge-integration" +name = "mock-bridge-integration-2" version = "0.1.0" edition = "2018" description = "Mock Bridge Integration for Transfer w/ Payload" @@ -13,15 +13,15 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-std = { version = "0.16.0" } -cosmwasm-storage = { version = "0.16.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw20 = "0.8.0" -cw20-base = { version = "0.8.0", features = ["library"] } -cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] } -terraswap = "2.4.0" -thiserror = { version = "1.0.20" } +cosmwasm-std = { version = "1.0.0" } +cosmwasm-storage = { version = "1.0.0" } +schemars = "0.8.8" +serde = { version = "1.0.137", default-features = false, features = ["derive"] } +cw20 = "0.13.2" +cw20-base = { version = "0.13.2", features = ["library"] } +cw20-wrapped-2 = { path = "../cw20-wrapped", features = ["library"] } +terraswap = "2.6.1" +thiserror = { version = "1.0.31" } k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] } sha3 = { version = "0.9.1", default-features = false } generic-array = { version = "0.14.4" } @@ -29,9 +29,9 @@ hex = "0.4.2" lazy_static = "1.4.0" bigint = "4" -wormhole-bridge-terra = { path = "../wormhole", features = ["library"] } -token-bridge-terra = { path = "../token-bridge", features = ["library"] } +wormhole-bridge-terra-2 = { path = "../wormhole", features = ["library"] } +token-bridge-terra-2 = { path = "../token-bridge", features = ["library"] } [dev-dependencies] -cosmwasm-vm = { version = "0.16.0", default-features = false } +cosmwasm-vm = { version = "1.0.0", default-features = false } serde_json = "1.0" diff --git a/cosmwasm/contracts/mock-bridge-integration/src/contract.rs b/cosmwasm/contracts/mock-bridge-integration/src/contract.rs index 768d67e77..bfe7582a9 100644 --- a/cosmwasm/contracts/mock-bridge-integration/src/contract.rs +++ b/cosmwasm/contracts/mock-bridge-integration/src/contract.rs @@ -31,7 +31,7 @@ use crate::{ }, }; -use token_bridge_terra::{ +use token_bridge_terra_2::{ msg::{ ExecuteMsg as TokenBridgeExecuteMsg, QueryMsg as TokenBridgeQueryMessage, @@ -79,7 +79,7 @@ pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> StdResult { } fn complete_transfer_with_payload( - mut deps: DepsMut, + deps: DepsMut, _env: Env, info: MessageInfo, data: &Binary, @@ -117,4 +117,4 @@ fn parse_transfer_vaa( })?, }))?; Ok(transfer_info) -} \ No newline at end of file +} diff --git a/cosmwasm/contracts/nft-bridge/.cargo/config b/cosmwasm/contracts/nft-bridge/.cargo/config deleted file mode 100644 index 2d5cce4ea..000000000 --- a/cosmwasm/contracts/nft-bridge/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib --features backtraces" -integration-test = "test --test integration" \ No newline at end of file diff --git a/cosmwasm/contracts/nft-bridge/Cargo.toml b/cosmwasm/contracts/nft-bridge/Cargo.toml deleted file mode 100644 index f462beb17..000000000 --- a/cosmwasm/contracts/nft-bridge/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "nft-bridge" -version = "0.1.0" -edition = "2018" -description = "Wormhole NFT bridge" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all init/handle/query exports -library = [] - -[dependencies] -cosmwasm-std = { version = "0.16.0" } -cosmwasm-storage = { version = "0.16.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw721-wrapped = { path = "../cw721-wrapped", features = ["library"] } -cw721-base = { path = "../../contracts/cw721-base", version = "0.10.0", features = ["library"] } -cw721 = { path = "../../packages/cw721" } -wormhole-bridge-terra = { path = "../wormhole", features = ["library"] } -sha3 = { version = "0.9.1", default-features = false } -hex = "0.4.2" -bigint = "4" - -[dev-dependencies] -serde_json = "1.0" -lazy_static = "1.4.0" diff --git a/cosmwasm/contracts/nft-bridge/src/contract.rs b/cosmwasm/contracts/nft-bridge/src/contract.rs deleted file mode 100644 index c07d31838..000000000 --- a/cosmwasm/contracts/nft-bridge/src/contract.rs +++ /dev/null @@ -1,589 +0,0 @@ -use crate::{ - msg::WrappedRegistryResponse, - state::{ - spl_cache, - spl_cache_read, - wrapped_asset, - BoundedVec, - SplCacheItem, - }, - token_id::{ - from_external_token_id, - to_external_token_id, - }, - CHAIN_ID, -}; -use cosmwasm_std::{ - entry_point, - to_binary, - Binary, - CanonicalAddr, - CosmosMsg, - Deps, - DepsMut, - Empty, - Env, - MessageInfo, - QueryRequest, - Response, - StdError, - StdResult, - WasmMsg, - WasmQuery, Order, -}; - -use crate::{ - msg::{ - ExecuteMsg, - InstantiateMsg, - MigrateMsg, - QueryMsg, - }, - state::{ - bridge_contracts, - bridge_contracts_read, - config, - config_read, - wrapped_asset_address, - wrapped_asset_address_read, - wrapped_asset_read, - Action, - ConfigInfo, - RegisterChain, - TokenBridgeMessage, - TransferInfo, - UpgradeContract, - }, -}; -use wormhole::{ - byte_utils::{ - extend_address_to_32, - extend_address_to_32_array, - get_string_from_32, - string_to_array, - ByteUtils, - }, - error::ContractError, -}; - -use wormhole::msg::{ - ExecuteMsg as WormholeExecuteMsg, - QueryMsg as WormholeQueryMsg, -}; - -use wormhole::state::{ - vaa_archive_add, - vaa_archive_check, - GovernancePacket, - ParsedVAA, -}; - -use sha3::{ - Digest, - Keccak256, -}; - -type HumanAddr = String; - -const WRAPPED_ASSET_UPDATING: &str = "updating"; - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult { - Ok(Response::new()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> StdResult { - // Save general wormhole info - let state = ConfigInfo { - gov_chain: msg.gov_chain, - gov_address: msg.gov_address.as_slice().to_vec(), - wormhole_contract: msg.wormhole_contract, - wrapped_asset_code_id: msg.wrapped_asset_code_id, - }; - config(deps.storage).save(&state)?; - - Ok(Response::default()) -} - -pub fn parse_vaa(deps: DepsMut, block_time: u64, data: &Binary) -> StdResult { - let cfg = config_read(deps.storage).load()?; - let vaa: ParsedVAA = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: cfg.wormhole_contract, - msg: to_binary(&WormholeQueryMsg::VerifyVAA { - vaa: data.clone(), - block_time, - })?, - }))?; - Ok(vaa) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { - match msg { - ExecuteMsg::InitiateTransfer { - contract_addr, - token_id, - recipient_chain, - recipient, - nonce, - } => handle_initiate_transfer( - deps, - env, - info, - contract_addr, - token_id, - recipient_chain, - recipient.to_array()?, - nonce, - ), - ExecuteMsg::SubmitVaa { data } => submit_vaa(deps, env, info, &data), - ExecuteMsg::RegisterAssetHook { asset_id } => { - handle_register_asset(deps, env, info, asset_id.as_slice()) - } - } -} - -fn submit_vaa( - mut deps: DepsMut, - env: Env, - info: MessageInfo, - data: &Binary, -) -> StdResult { - let state = config_read(deps.storage).load()?; - - let vaa = parse_vaa(deps.branch(), env.block.time.seconds(), data)?; - let data = vaa.payload; - - if vaa_archive_check(deps.storage, vaa.hash.as_slice()) { - return ContractError::VaaAlreadyExecuted.std_err(); - } - vaa_archive_add(deps.storage, vaa.hash.as_slice())?; - - // check if vaa is from governance - if state.gov_chain == vaa.emitter_chain && state.gov_address == vaa.emitter_address { - return handle_governance_payload(deps, env, &data); - } - - let message = TokenBridgeMessage::deserialize(&data)?; - - match message.action { - Action::TRANSFER => handle_complete_transfer( - deps, - env, - info, - vaa.emitter_chain, - vaa.emitter_address, - TransferInfo::deserialize(&message.payload)?, - ), - _ => ContractError::InvalidVAAAction.std_err(), - } -} - -fn handle_governance_payload(deps: DepsMut, env: Env, data: &[u8]) -> StdResult { - let gov_packet = GovernancePacket::deserialize(data)?; - let module = get_string_from_32(&gov_packet.module); - - if module != "NFTBridge" { - return Err(StdError::generic_err("this is not a valid module")); - } - - if gov_packet.chain != 0 && gov_packet.chain != CHAIN_ID { - return Err(StdError::generic_err( - "the governance VAA is for another chain", - )); - } - - match gov_packet.action { - 1u8 => handle_register_chain(deps, env, RegisterChain::deserialize(&gov_packet.payload)?), - 2u8 => handle_upgrade_contract( - deps, - env, - UpgradeContract::deserialize(&gov_packet.payload)?, - ), - _ => ContractError::InvalidVAAAction.std_err(), - } -} - -fn handle_upgrade_contract( - _deps: DepsMut, - env: Env, - upgrade_contract: UpgradeContract, -) -> StdResult { - Ok(Response::new() - .add_message(CosmosMsg::Wasm(WasmMsg::Migrate { - contract_addr: env.contract.address.to_string(), - new_code_id: upgrade_contract.new_contract, - msg: to_binary(&MigrateMsg {})?, - })) - .add_attribute("action", "contract_upgrade")) -} - -fn handle_register_chain( - deps: DepsMut, - _env: Env, - register_chain: RegisterChain, -) -> StdResult { - let RegisterChain { - chain_id, - chain_address, - } = register_chain; - - let existing = bridge_contracts_read(deps.storage).load(&chain_id.to_be_bytes()); - if existing.is_ok() { - return Err(StdError::generic_err( - "bridge contract already exists for this chain", - )); - } - - let mut bucket = bridge_contracts(deps.storage); - bucket.save(&chain_id.to_be_bytes(), &chain_address)?; - - Ok(Response::new() - .add_attribute("chain_id", chain_id.to_string()) - .add_attribute("chain_address", hex::encode(chain_address))) -} - -fn handle_complete_transfer( - deps: DepsMut, - env: Env, - _info: MessageInfo, - emitter_chain: u16, - emitter_address: Vec, - transfer_info: TransferInfo, -) -> StdResult { - let cfg = config_read(deps.storage).load()?; - - let expected_contract = - bridge_contracts_read(deps.storage).load(&emitter_chain.to_be_bytes())?; - - // must be sent by a registered token bridge contract - if expected_contract != emitter_address { - return Err(StdError::generic_err("invalid emitter")); - } - - if transfer_info.recipient_chain != CHAIN_ID { - return Err(StdError::generic_err( - "this transfer is not directed at this chain", - )); - } - - let token_chain = transfer_info.nft_chain; - let target_address = &(&transfer_info.recipient[..]).get_address(0); - - let mut messages = vec![]; - - let recipient = deps - .api - .addr_humanize(target_address) - .or_else(|_| ContractError::WrongTargetAddressFormat.std_err())?; - - let contract_addr; - - let token_id = from_external_token_id( - deps.storage, - token_chain, - &transfer_info.nft_address, - &transfer_info.token_id, - )?; - - if token_chain != CHAIN_ID { - // NFT is not native to this chain, so we need a wrapper - let asset_address = transfer_info.nft_address; - let asset_id = build_asset_id(token_chain, &asset_address); - - let token_uri = String::from_utf8(transfer_info.uri.to_vec()) - .map_err(|_| StdError::generic_err("could not parse uri string"))?; - - let mint_msg = cw721_base::msg::MintMsg { - token_id, - owner: recipient.to_string(), - token_uri: Some(token_uri), - extension: None, - }; - - // Check if this asset is already deployed - if let Ok(wrapped_addr) = wrapped_asset_read(deps.storage).load(&asset_id) { - contract_addr = wrapped_addr; - // Asset already deployed, just mint - - messages.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - msg: to_binary(&cw721_base::msg::ExecuteMsg::Mint(mint_msg))?, - funds: vec![], - })); - } else { - contract_addr = env.contract.address.clone().into_string(); - wrapped_asset(deps.storage) - .save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?; - - let (name, symbol) = if token_chain == 1 { - let spl_cache_item = SplCacheItem { - name: transfer_info.name, - symbol: transfer_info.symbol, - }; - spl_cache(deps.storage).save(&transfer_info.token_id, &spl_cache_item)?; - // Solana NFTs all use the same NFT contract, so unify the name - ( - "Wormhole Bridged Solana-NFT".to_string(), - "WORMSPLNFT".to_string(), - ) - } else { - ( - get_string_from_32(&transfer_info.name), - get_string_from_32(&transfer_info.symbol), - ) - }; - messages.push(CosmosMsg::Wasm(WasmMsg::Instantiate { - admin: Some(contract_addr.clone()), - code_id: cfg.wrapped_asset_code_id, - msg: to_binary(&cw721_wrapped::msg::InstantiateMsg { - name, - symbol, - asset_chain: token_chain, - asset_address: (&transfer_info.nft_address[..]).into(), - minter: env.contract.address.into_string(), - mint: Some(mint_msg), - init_hook: Some(cw721_wrapped::msg::InitHook { - msg: cw721_wrapped::to_binary(&ExecuteMsg::RegisterAssetHook { - asset_id: asset_id.to_vec().into(), - }) - .map_err(|_| StdError::generic_err("couldn't convert to binary"))?, - contract_addr: contract_addr.clone(), - }), - })?, - funds: vec![], - label: String::new(), - })); - } - } else { - // Native NFT, transfer from custody - let token_address = (&transfer_info.nft_address[..]).get_address(0); - - contract_addr = deps.api.addr_humanize(&token_address)?.to_string(); - - messages.push(CosmosMsg::::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.clone(), - msg: to_binary(&cw721_base::msg::ExecuteMsg::>::TransferNft { - recipient: recipient.to_string(), - token_id, - })?, - funds: vec![], - })); - } - Ok(Response::new() - .add_messages(messages) - .add_attribute("action", "complete_transfer") - .add_attribute("recipient", recipient) - .add_attribute("contract", contract_addr)) -} - -#[allow(clippy::too_many_arguments)] -fn handle_initiate_transfer( - deps: DepsMut, - env: Env, - info: MessageInfo, - asset: HumanAddr, - token_id: String, - recipient_chain: u16, - recipient: [u8; 32], - nonce: u32, -) -> StdResult { - if recipient_chain == CHAIN_ID { - return ContractError::SameSourceAndTarget.std_err(); - } - - let asset_chain: u16; - let asset_address: [u8; 32]; - - let cfg: ConfigInfo = config_read(deps.storage).load()?; - let asset_canonical: CanonicalAddr = deps.api.addr_canonicalize(&asset)?; - - let mut messages: Vec = vec![]; - - if wrapped_asset_address_read(deps.storage).load(asset_canonical.as_slice()).is_ok() { - // This is a deployed wrapped asset, burn it - messages.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: asset.clone(), - msg: to_binary(&cw721_wrapped::msg::ExecuteMsg::Burn::> { - token_id: token_id.clone(), - })?, - funds: vec![], - })); - - let wrapped_token_info: cw721_wrapped::msg::WrappedAssetInfoResponse = deps - .querier - .custom_query(&QueryRequest::::Wasm(WasmQuery::Smart { - contract_addr: asset.clone(), - msg: to_binary(&cw721_wrapped::msg::QueryMsg::WrappedAssetInfo {})?, - }))?; - - asset_address = wrapped_token_info.asset_address.to_array()?; - asset_chain = wrapped_token_info.asset_chain; - } else { - // Native NFT, lock it up - messages.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: asset.clone(), - msg: to_binary(&cw721_base::msg::ExecuteMsg::>::TransferNft { - recipient: env.contract.address.to_string(), - token_id: token_id.clone(), - })?, - funds: vec![], - })); - - asset_chain = CHAIN_ID; - asset_address = extend_address_to_32_array(&asset_canonical); - }; - - let external_token_id = - to_external_token_id(deps.storage, asset_chain, &asset_address, token_id.clone())?; - - let symbol: [u8; 32]; - let name: [u8; 32]; - - if asset_chain == 1 { - let SplCacheItem { - name: cached_name, - symbol: cached_symbol, - } = spl_cache_read(deps.storage).load(&external_token_id)?; - symbol = cached_symbol; - name = cached_name; - } else { - let response: cw721::ContractInfoResponse = - deps.querier - .custom_query(&QueryRequest::::Wasm(WasmQuery::Smart { - contract_addr: asset.clone(), - msg: to_binary(&cw721_base::msg::QueryMsg::ContractInfo {})?, - }))?; - name = string_to_array(&response.name); - symbol = string_to_array(&response.symbol); - } - - let cw721::NftInfoResponse::> { token_uri, .. } = - deps.querier - .custom_query(&QueryRequest::::Wasm(WasmQuery::Smart { - contract_addr: asset, - msg: to_binary(&cw721_base::msg::QueryMsg::NftInfo { - token_id: token_id.clone(), - })?, - }))?; - - let transfer_info = TransferInfo { - nft_address: asset_address, - nft_chain: asset_chain, - symbol, - name, - token_id: external_token_id, - uri: BoundedVec::new(token_uri.unwrap().into())?, - recipient, - recipient_chain, - }; - - let token_bridge_message = TokenBridgeMessage { - action: Action::TRANSFER, - payload: transfer_info.serialize(), - }; - - messages.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: cfg.wormhole_contract, - msg: to_binary(&WormholeExecuteMsg::PostMessage { - message: Binary::from(token_bridge_message.serialize()), - nonce, - })?, - funds: vec![], - })); - - Ok(Response::new() - .add_messages(messages) - .add_attribute("transfer.token_chain", asset_chain.to_string()) - .add_attribute("transfer.token", hex::encode(asset_address)) - .add_attribute("transfer.token_id", token_id) - .add_attribute("transfer.external_token_id", hex::encode(external_token_id)) - .add_attribute( - "transfer.sender", - hex::encode(extend_address_to_32( - &deps.api.addr_canonicalize(info.sender.as_str())?, - )), - ) - .add_attribute("transfer.recipient_chain", recipient_chain.to_string()) - .add_attribute("transfer.recipient", hex::encode(recipient)) - .add_attribute("transfer.nonce", nonce.to_string()) - .add_attribute("transfer.block_time", env.block.time.seconds().to_string())) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::WrappedRegistry { chain, address } => { - to_binary(&query_wrapped_registry(deps, chain, address.as_slice())?) - } - QueryMsg::AllWrappedAssets { } => { - to_binary(&query_all_wrapped_assets(deps)?) - } - } -} - -/// Handle wrapped asset registration messages -fn handle_register_asset( - deps: DepsMut, - _env: Env, - info: MessageInfo, - asset_id: &[u8], -) -> StdResult { - let mut bucket = wrapped_asset(deps.storage); - let result = bucket - .load(asset_id) - .map_err(|_| ContractError::RegistrationForbidden.std())?; - if result != WRAPPED_ASSET_UPDATING { - return ContractError::AssetAlreadyRegistered.std_err(); - } - - bucket.save(asset_id, &info.sender.to_string())?; - - let contract_address: CanonicalAddr = deps.api.addr_canonicalize(info.sender.as_str())?; - wrapped_asset_address(deps.storage).save(contract_address.as_slice(), &asset_id.to_vec())?; - - Ok(Response::new() - .add_attribute("action", "register_asset") - .add_attribute("asset_id", format!("{:?}", asset_id)) - .add_attribute("contract_addr", info.sender)) -} - -pub fn query_wrapped_registry( - deps: Deps, - chain: u16, - address: &[u8], -) -> StdResult { - let asset_id = build_asset_id(chain, address); - // Check if this asset is already deployed - match wrapped_asset_read(deps.storage).load(&asset_id) { - Ok(address) => Ok(WrappedRegistryResponse { address }), - Err(_) => ContractError::AssetNotFound.std_err(), - } -} - -fn query_all_wrapped_assets(deps: Deps) -> StdResult> { - let bucket = wrapped_asset_address_read(deps.storage); - let mut result = vec![]; - for item in bucket.range(None, None, Order::Ascending) { - let contract_address = item?.0.into(); - result.push(deps.api.addr_humanize(&contract_address)?.to_string()) - } - Ok(result) -} - - -fn build_asset_id(chain: u16, address: &[u8]) -> Vec { - let mut asset_id: Vec = vec![]; - asset_id.extend_from_slice(&chain.to_be_bytes()); - asset_id.extend_from_slice(address); - - let mut hasher = Keccak256::new(); - hasher.update(asset_id); - hasher.finalize().to_vec() -} diff --git a/cosmwasm/contracts/nft-bridge/src/lib.rs b/cosmwasm/contracts/nft-bridge/src/lib.rs deleted file mode 100644 index 6aab89fc5..000000000 --- a/cosmwasm/contracts/nft-bridge/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod contract; -pub mod msg; -pub mod state; -pub mod token_id; - -// Chain ID of Terra -const CHAIN_ID: u16 = 3; diff --git a/cosmwasm/contracts/nft-bridge/src/msg.rs b/cosmwasm/contracts/nft-bridge/src/msg.rs deleted file mode 100644 index b5696a8e3..000000000 --- a/cosmwasm/contracts/nft-bridge/src/msg.rs +++ /dev/null @@ -1,61 +0,0 @@ -use cosmwasm_std::Binary; -use schemars::JsonSchema; -use serde::{ - Deserialize, - Serialize, -}; - -type HumanAddr = String; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg { - // governance contract details - pub gov_chain: u16, - pub gov_address: Binary, - - pub wormhole_contract: HumanAddr, - pub wrapped_asset_code_id: u64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - RegisterAssetHook { - asset_id: Binary, - }, - - InitiateTransfer { - contract_addr: String, - token_id: String, - recipient_chain: u16, - recipient: Binary, - nonce: u32, - }, - - SubmitVaa { - data: Binary, - }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - WrappedRegistry { chain: u16, address: Binary }, - AllWrappedAssets { }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct WrappedRegistryResponse { - pub address: HumanAddr, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum WormholeQueryMsg { - VerifyVAA { vaa: Binary, block_time: u64 }, -} diff --git a/cosmwasm/contracts/nft-bridge/src/state.rs b/cosmwasm/contracts/nft-bridge/src/state.rs deleted file mode 100644 index 1e92efccf..000000000 --- a/cosmwasm/contracts/nft-bridge/src/state.rs +++ /dev/null @@ -1,272 +0,0 @@ -use std::convert::TryInto; - -use schemars::JsonSchema; -use serde::{ - Deserialize, - Serialize, -}; - -use cosmwasm_std::{ - StdError, - StdResult, - Storage, -}; -use cosmwasm_storage::{ - bucket, - bucket_read, - singleton, - singleton_read, - Bucket, - ReadonlyBucket, - ReadonlySingleton, - Singleton, -}; - -use wormhole::byte_utils::ByteUtils; - -type HumanAddr = String; - -pub static CONFIG_KEY: &[u8] = b"config"; -pub static WRAPPED_ASSET_KEY: &[u8] = b"wrapped_asset"; -pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address"; -pub static BRIDGE_CONTRACTS_KEY: &[u8] = b"bridge_contracts"; -pub static TOKEN_ID_HASHES_KEY: &[u8] = b"token_id_hashes"; -pub static SPL_CACHE_KEY: &[u8] = b"spl_cache"; - -// Guardian set information -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct ConfigInfo { - // governance contract details - pub gov_chain: u16, - pub gov_address: Vec, - - pub wormhole_contract: HumanAddr, - pub wrapped_asset_code_id: u64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct SplCacheItem { - pub name: [u8; 32], - pub symbol: [u8; 32], -} - -pub fn config(storage: &mut dyn Storage) -> Singleton { - singleton(storage, CONFIG_KEY) -} - -pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, CONFIG_KEY) -} - -pub fn bridge_contracts(storage: &mut dyn Storage) -> Bucket> { - bucket(storage, BRIDGE_CONTRACTS_KEY) -} - -pub fn bridge_contracts_read(storage: &dyn Storage) -> ReadonlyBucket> { - bucket_read(storage, BRIDGE_CONTRACTS_KEY) -} - -pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket { - bucket(storage, WRAPPED_ASSET_KEY) -} - -pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, WRAPPED_ASSET_KEY) -} - -pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket> { - bucket(storage, WRAPPED_ASSET_ADDRESS_KEY) -} - -pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket> { - bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY) -} - -pub fn spl_cache(storage: &mut dyn Storage) -> Bucket { - bucket(storage, SPL_CACHE_KEY) -} - -pub fn spl_cache_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, SPL_CACHE_KEY) -} - -pub fn token_id_hashes(storage: &mut dyn Storage, chain: u16, address: [u8; 32]) -> Bucket { - Bucket::multilevel( - storage, - &[TOKEN_ID_HASHES_KEY, &chain.to_be_bytes(), &address], - ) -} - -pub fn token_id_hashes_read( - storage: &mut dyn Storage, - chain: u16, - address: [u8; 32], -) -> ReadonlyBucket { - ReadonlyBucket::multilevel( - storage, - &[TOKEN_ID_HASHES_KEY, &chain.to_be_bytes(), &address], - ) -} - -pub struct Action; - -impl Action { - pub const TRANSFER: u8 = 1; -} - -// 0 u8 action -// 1 [u8] payload -pub struct TokenBridgeMessage { - pub action: u8, - pub payload: Vec, -} - -impl TokenBridgeMessage { - pub fn deserialize(data: &[u8]) -> StdResult { - let action = data.get_u8(0); - let payload = &data[1..]; - - Ok(TokenBridgeMessage { - action, - payload: payload.to_vec(), - }) - } - - pub fn serialize(&self) -> Vec { - [self.action.to_be_bytes().to_vec(), self.payload.clone()].concat() - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[repr(transparent)] -pub struct BoundedVec { - vec: Vec, -} - -impl BoundedVec { - pub fn new(vec: Vec) -> StdResult { - if vec.len() > N { - return Result::Err(StdError::GenericErr { - msg: format!("vector length exceeds {}", N), - }); - }; - Ok(Self { vec }) - } - - #[inline] - pub fn to_vec(&self) -> Vec - where - T: Clone, - { - self.vec.clone() - } - - #[inline] - pub fn len(&self) -> usize { - self.vec.len() - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.vec.is_empty() - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct TransferInfo { - pub nft_address: [u8; 32], - pub nft_chain: u16, - pub symbol: [u8; 32], - pub name: [u8; 32], - pub token_id: [u8; 32], - pub uri: BoundedVec, // max 200 bytes due to Solana - pub recipient: [u8; 32], - pub recipient_chain: u16, -} - -impl TransferInfo { - pub fn deserialize(data: &[u8]) -> StdResult { - let mut offset: usize = 0; // offset into data in bytes - let nft_address = data.get_const_bytes::<32>(offset); - offset += 32; - let nft_chain = data.get_u16(offset); - offset += 2; - let symbol = data.get_const_bytes::<32>(offset); - offset += 32; - let name = data.get_const_bytes::<32>(offset); - offset += 32; - let token_id = data.get_const_bytes::<32>(offset); - offset += 32; - let uri_length: usize = data.get_u8(offset).into(); - offset += 1; - let uri = data.get_bytes(offset, uri_length).to_vec(); - offset += uri_length; - let recipient = data.get_const_bytes::<32>(offset); - offset += 32; - let recipient_chain = data.get_u16(offset); - offset += 2; - - if data.len() != offset { - return Result::Err(StdError::GenericErr { - msg: format!( - "Invalid transfer length, expected {}, but got {}", - offset, - data.len() - ), - }); - } - - Ok(TransferInfo { - nft_address, - nft_chain, - symbol, - name, - token_id, - uri: BoundedVec::new(uri.to_vec())?, - recipient, - recipient_chain, - }) - } - pub fn serialize(&self) -> Vec { - [ - self.nft_address.to_vec(), - self.nft_chain.to_be_bytes().to_vec(), - self.symbol.to_vec(), - self.name.to_vec(), - self.token_id.to_vec(), - vec![self.uri.len().try_into().unwrap()], // won't panic, because uri.len() is less than 200 - self.uri.to_vec(), - self.recipient.to_vec(), - self.recipient_chain.to_be_bytes().to_vec(), - ] - .concat() - } -} - -pub struct UpgradeContract { - pub new_contract: u64, -} - -pub struct RegisterChain { - pub chain_id: u16, - pub chain_address: Vec, -} - -impl UpgradeContract { - pub fn deserialize(data: &[u8]) -> StdResult { - let new_contract = data.get_u64(24); - Ok(UpgradeContract { new_contract }) - } -} - -impl RegisterChain { - pub fn deserialize(data: &[u8]) -> StdResult { - let chain_id = data.get_u16(0); - let chain_address = data[2..].to_vec(); - - Ok(RegisterChain { - chain_id, - chain_address, - }) - } -} diff --git a/cosmwasm/contracts/nft-bridge/src/token_id.rs b/cosmwasm/contracts/nft-bridge/src/token_id.rs deleted file mode 100644 index ada86a333..000000000 --- a/cosmwasm/contracts/nft-bridge/src/token_id.rs +++ /dev/null @@ -1,97 +0,0 @@ -use bigint::U256; -use cosmwasm_std::{ - StdError, - StdResult, - Storage, -}; - -use sha3::{ - digest::{consts::U32, generic_array::GenericArray}, - Digest, Keccak256, -}; -use wormhole::byte_utils::ByteUtils; - -use crate::{ - state::{ - token_id_hashes, - token_id_hashes_read, - }, - CHAIN_ID, -}; - -// NOTE: [External and internal token id conversion] -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// The CW721 NFT standard allows token ids to be arbitrarily long (utf8) -// strings, while the token_ids in VAA payloads are always 32 bytes (and not -// necessarily valid utf8). -// -// We call a token id that's in string format an "internal id", and a token id -// that's in 32 byte format an "external id". Note that whether a token id is in -// internal format or external format doesn't imply which chain the token id -// originates from. We can have a terra (native) token id in both internal and -// external formats, and likewise we can have an ethereum token in in both -// internal and external formats. -// -// To support seamless transfers through the bridge, we need a way to have a -// 1-to-1 mapping from internal ids to external ids. -// When a foreign (such as ethereum or solana) token id first comes through, we -// simply render it into a string by formatting it as a decimal number. Then, -// when we want to transfer such a token back through the bridge, we simply -// parse the string back into a u256 (32 byte) number. -// -// When a native token id first leaves through the bridge, we turn its id into a -// 32 byte hash (keccak256). This hash is the external id. We store a mapping -// -// (chain_id, nft_address, keccak256(internal_id)) => internal_id -// -// so that we can turn it back into an internal id when it comes back through -// the bridge. When the token is sent back, we could choose to delete the hash -// from the store, but we do not. This way, external token verifiers will be -// able to verify NFT origins even for NFTs that have been transferred back. -// -// If two token ids within the same contract have the same keccak256 hash, then -// it's possible to lose tokens, but this is very unlikely. - -pub fn from_external_token_id( - storage: &mut dyn Storage, - nft_chain: u16, - nft_address: &[u8; 32], - token_id_external: &[u8; 32], -) -> StdResult { - if nft_chain == CHAIN_ID { - token_id_hashes_read(storage, nft_chain, *nft_address).load(token_id_external) - } else { - Ok(format!("{}", U256::from_big_endian(token_id_external))) - } -} - -fn hash(token_id: &str) -> GenericArray { - let mut hasher = Keccak256::new(); - hasher.update(token_id); - hasher.finalize() -} - -pub fn to_external_token_id( - storage: &mut dyn Storage, - nft_chain: u16, - nft_address: &[u8; 32], - token_id_internal: String, -) -> StdResult<[u8; 32]> { - if nft_chain == CHAIN_ID { - let hash = hash(&token_id_internal); - token_id_hashes(storage, nft_chain, *nft_address).save(&hash, &token_id_internal)?; - Ok(hash.as_slice().get_const_bytes(0)) - } else { - let mut bytes = [0; 32]; - U256::from_dec_str(&token_id_internal) - .map_err(|_| { - StdError::generic_err(format!( - "{} could not be parsed as a decimal number", - token_id_internal - )) - })? - .to_big_endian(&mut bytes); - Ok(bytes) - } -} diff --git a/cosmwasm/contracts/token-bridge/Cargo.toml b/cosmwasm/contracts/token-bridge/Cargo.toml index 3dea0a0ea..68721eb82 100644 --- a/cosmwasm/contracts/token-bridge/Cargo.toml +++ b/cosmwasm/contracts/token-bridge/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "token-bridge-terra" +name = "token-bridge-terra-2" version = "0.1.0" authors = ["Yuriy Savchenko "] edition = "2018" @@ -14,16 +14,16 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-std = { version = "0.16.0" } -cosmwasm-storage = { version = "0.16.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw20 = "0.8.0" -cw20-base = { version = "0.8.0", features = ["library"] } -cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] } -terraswap = "2.4.0" -wormhole-bridge-terra = { path = "../wormhole", features = ["library"] } -thiserror = { version = "1.0.20" } +cosmwasm-std = { version = "1.0.0" } +cosmwasm-storage = { version = "1.0.0" } +schemars = "0.8.8" +serde = { version = "1.0.137", default-features = false, features = ["derive"] } +cw20 = "0.13.2" +cw20-base = { version = "0.13.2", features = ["library"] } +cw20-wrapped-2 = { path = "../cw20-wrapped", features = ["library"] } +terraswap = "2.6.1" +wormhole-bridge-terra-2 = { path = "../wormhole", features = ["library"] } +thiserror = { version = "1.0.31" } k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] } sha3 = { version = "0.9.1", default-features = false } generic-array = { version = "0.14.4" } diff --git a/cosmwasm/contracts/token-bridge/src/contract.rs b/cosmwasm/contracts/token-bridge/src/contract.rs index c7d171ff8..02e835fe6 100644 --- a/cosmwasm/contracts/token-bridge/src/contract.rs +++ b/cosmwasm/contracts/token-bridge/src/contract.rs @@ -6,17 +6,13 @@ use cw20_base::msg::{ ExecuteMsg as TokenMsg, QueryMsg as TokenQuery, }; -use cw20_wrapped::msg::{ +use cw20_wrapped_2::msg::{ ExecuteMsg as WrappedMsg, InitHook, InstantiateMsg as WrappedInit, QueryMsg as WrappedQuery, WrappedAssetInfoResponse, }; -use sha3::{ - Digest, - Keccak256, -}; use std::{ cmp::{ max, @@ -32,6 +28,7 @@ use terraswap::asset::{ use wormhole::{ byte_utils::{ extend_address_to_32, + extend_address_to_32_array, extend_string_to_32, get_string_from_32, ByteUtils, @@ -49,14 +46,15 @@ use wormhole::{ }, }; +#[allow(unused_imports)] +use cosmwasm_std::entry_point; + use cosmwasm_std::{ coin, - entry_point, to_binary, BankMsg, Binary, CanonicalAddr, - Coin, CosmosMsg, Deps, DepsMut, @@ -77,6 +75,7 @@ use cosmwasm_std::{ use crate::{ msg::{ ExecuteMsg, + ExternalIdResponse, InstantiateMsg, MigrateMsg, QueryMsg, @@ -89,11 +88,11 @@ use crate::{ bridge_deposit, config, config_read, + is_wrapped_asset, + is_wrapped_asset_read, receive_native, send_native, wrapped_asset, - wrapped_asset_address, - wrapped_asset_address_read, wrapped_asset_read, wrapped_asset_seq, wrapped_asset_seq_read, @@ -108,15 +107,17 @@ use crate::{ TransferWithPayloadInfo, UpgradeContract, }, + token_address::{ + ContractId, + ExternalTokenId, + TokenId, + WrappedCW20, + }, + CHAIN_ID, }; type HumanAddr = String; -// Chain ID of Terra -const CHAIN_ID: u16 = 3; - -const WRAPPED_ASSET_UPDATING: &str = "updating"; - pub enum TransferType { WithoutPayload, WithPayload { payload: A }, @@ -180,7 +181,7 @@ pub fn reply(deps: DepsMut, env: Env, _msg: Reply) -> StdResult { // Fetch CW20 Balance post-transfer. let new_balance: BalanceResponse = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: state.token_address.clone(), + contract_addr: state.token_address.to_string(), msg: to_binary(&TokenQuery::Balance { address: env.contract.address.to_string(), })?, @@ -225,26 +226,13 @@ pub fn reply(deps: DepsMut, env: Env, _msg: Reply) -> StdResult { })?, }); - send_native(deps.storage, &state.token_canonical, real_amount)?; + let external_id = ExternalTokenId::from_native_cw20(&state.token_address)?; + send_native(deps.storage, &external_id, real_amount)?; Ok(Response::default() .add_message(message) .add_attribute("action", "reply_handler")) } -pub fn coins_after_tax(deps: DepsMut, coins: Vec) -> StdResult> { - let mut res = vec![]; - for coin in coins { - let asset = Asset { - amount: coin.amount.clone(), - info: AssetInfo::NativeToken { - denom: coin.denom.clone(), - }, - }; - res.push(asset.deduct_tax(&deps.querier)?); - } - Ok(res) -} - fn parse_vaa(deps: Deps, block_time: u64, data: &Binary) -> StdResult { let cfg = config_read(deps.storage).load()?; let vaa: ParsedVAA = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { @@ -260,9 +248,10 @@ fn parse_vaa(deps: Deps, block_time: u64, data: &Binary) -> StdResult #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { match msg { - ExecuteMsg::RegisterAssetHook { asset_id } => { - handle_register_asset(deps, env, info, &asset_id.as_slice()) - } + ExecuteMsg::RegisterAssetHook { + chain, + token_address, + } => handle_register_asset(deps, env, info, chain, token_address), ExecuteMsg::InitiateTransfer { asset, recipient_chain, @@ -275,7 +264,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S info, asset, recipient_chain, - recipient.into(), + recipient.to_array()?, fee, TransferType::WithoutPayload, nonce, @@ -293,7 +282,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S info, asset, recipient_chain, - recipient.into(), + recipient.to_array()?, fee, TransferType::WithPayload { payload: payload.into(), @@ -348,7 +337,7 @@ fn withdraw_tokens( )?; messages.push(CosmosMsg::Bank(BankMsg::Send { to_address: info.sender.to_string(), - amount: coins_after_tax(deps, vec![coin(deposited_amount, &denom)])?, + amount: vec![coin(deposited_amount, &denom)], })); } @@ -362,23 +351,41 @@ fn handle_register_asset( deps: DepsMut, _env: Env, info: MessageInfo, - asset_id: &[u8], + chain: u16, + token_address: ExternalTokenId, ) -> StdResult { - let mut bucket = wrapped_asset(deps.storage); - let result = bucket.load(asset_id); - let result = result.map_err(|_| ContractError::RegistrationForbidden.std())?; - if result != HumanAddr::from(WRAPPED_ASSET_UPDATING) { + // We need to ensure that this registration request was initiated by the + // token bridge contract. We do this by checking that the wrapped asset + // already has an associated sequence number, but no address entry yet. + // This is a necessary and sufficient condition, because having the sequence + // number means that [`handle_attest_meta`] has been called, and not having + // an address entry yet means precisely that the callback hasn't finished + // yet. + + let _ = wrapped_asset_seq_read(deps.storage, chain) + .load(&token_address.serialize()) + .map_err(|_| ContractError::RegistrationForbidden.std())?; + + let mut bucket = wrapped_asset(deps.storage, chain); + let result = bucket.load(&token_address.serialize()).ok(); + if let Some(_) = result { return ContractError::AssetAlreadyRegistered.std_err(); } - bucket.save(asset_id, &info.sender.to_string())?; + bucket.save( + &token_address.serialize(), + &WrappedCW20 { + human_address: info.sender.clone(), + }, + )?; let contract_address: CanonicalAddr = deps.api.addr_canonicalize(&info.sender.as_str())?; - wrapped_asset_address(deps.storage).save(contract_address.as_slice(), &asset_id.to_vec())?; + is_wrapped_asset(deps.storage).save(contract_address.as_slice(), &())?; Ok(Response::new() .add_attribute("action", "register_asset") - .add_attribute("asset_id", format!("{:?}", asset_id)) + .add_attribute("token_chain", format!("{:?}", chain)) + .add_attribute("token_address", format!("{:?}", token_address)) .add_attribute("contract_addr", info.sender)) } @@ -400,26 +407,44 @@ fn handle_attest_meta( return Err(StdError::generic_err("invalid emitter")); } - if CHAIN_ID == meta.token_chain { - return Err(StdError::generic_err( - "this asset is native to this chain and should not be attested", - )); - } + let token_id = meta + .token_address + .to_token_id(deps.storage, emitter_chain)?; + + let token_address: [u8; 32] = match token_id { + TokenId::Bank { denom } => Err(StdError::generic_err(format!( + "{} is native to this chain and should not be attested", + denom + ))), + TokenId::Contract(ContractId::NativeCW20 { contract_address }) => { + Err(StdError::generic_err(format!( + "Contract {} is native to this chain and should not be attested", + contract_address + ))) + } + TokenId::Contract(ContractId::ForeignToken { + chain_id: _, + foreign_address, + }) => Ok(foreign_address), + }?; let cfg = config_read(deps.storage).load()?; - let asset_id = build_asset_id(meta.token_chain, &meta.token_address.as_slice()); - // If a CW20 wrapped already exists and this message has a newer sequence ID // we allow updating the metadata. If not, we create a brand new token. - let message = if let Ok(contract) = wrapped_asset_read(deps.storage).load(&asset_id) { + let message = if let Ok(contract) = + wrapped_asset_read(deps.storage, meta.token_chain).load(token_address.as_slice()) + { // Prevent anyone from re-attesting with old VAAs. - if sequence <= wrapped_asset_seq_read(deps.storage).load(&asset_id)? { + if sequence + <= wrapped_asset_seq_read(deps.storage, meta.token_chain) + .load(token_address.as_slice())? + { return Err(StdError::generic_err( "this asset has already been attested", )); } CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract, + contract_addr: contract.into_string(), msg: to_binary(&WrappedMsg::UpdateMetadata { name: get_string_from_32(&meta.name), symbol: get_string_from_32(&meta.symbol), @@ -427,7 +452,6 @@ fn handle_attest_meta( funds: vec![], }) } else { - wrapped_asset(deps.storage).save(&asset_id, &HumanAddr::from(WRAPPED_ASSET_UPDATING))?; CosmosMsg::Wasm(WasmMsg::Instantiate { admin: Some(env.contract.address.clone().into_string()), code_id: cfg.wrapped_asset_code_id, @@ -435,21 +459,22 @@ fn handle_attest_meta( name: get_string_from_32(&meta.name), symbol: get_string_from_32(&meta.symbol), asset_chain: meta.token_chain, - asset_address: meta.token_address.to_vec().into(), + asset_address: token_address.into(), decimals: min(meta.decimals, 8u8), mint: None, init_hook: Some(InitHook { contract_addr: env.contract.address.to_string(), msg: to_binary(&ExecuteMsg::RegisterAssetHook { - asset_id: asset_id.to_vec().into(), + chain: meta.token_chain, + token_address: meta.token_address.clone(), })?, }), })?, funds: vec![], - label: String::new(), + label: "Wormhole Wrapped CW20".to_string(), }) }; - wrapped_asset_seq(deps.storage).save(&asset_id, &sequence)?; + wrapped_asset_seq(deps.storage, meta.token_chain).save(&token_address, &sequence)?; Ok(Response::new().add_message(message)) } @@ -484,12 +509,16 @@ fn handle_create_asset_meta_token( msg: to_binary(&TokenQuery::TokenInfo {})?, }); - let asset_canonical = deps.api.addr_canonicalize(&asset_address)?; + let asset_human = deps.api.addr_validate(&asset_address)?; + let token_id = TokenId::Contract(ContractId::NativeCW20 { + contract_address: asset_human, + }); + let external_id = token_id.store(deps.storage)?; let token_info: TokenInfoResponse = deps.querier.query(&request)?; let meta: AssetMeta = AssetMeta { token_chain: CHAIN_ID, - token_address: extend_address_to_32(&asset_canonical), + token_address: external_id, decimals: token_info.decimals, symbol: extend_string_to_32(&token_info.symbol), name: extend_string_to_32(&token_info.name), @@ -508,7 +537,7 @@ fn handle_create_asset_meta_token( nonce, })?, // forward coins sent to this message - funds: coins_after_tax(deps, info.funds.clone())?, + funds: info.funds.clone(), })) .add_attribute("meta.token_chain", CHAIN_ID.to_string()) .add_attribute("meta.token", asset_address) @@ -524,12 +553,14 @@ fn handle_create_asset_meta_native_token( nonce: u32, ) -> StdResult { let cfg = config_read(deps.storage).load()?; - let mut asset_id = extend_address_to_32(&build_native_id(&denom).into()); - asset_id[0] = 1; + let symbol = format_native_denom_symbol(&denom); + let token_id = TokenId::Bank { denom }; + let external_id = token_id.store(deps.storage)?; + let meta: AssetMeta = AssetMeta { token_chain: CHAIN_ID, - token_address: asset_id.clone(), + token_address: external_id.clone(), decimals: 6, symbol: extend_string_to_32(&symbol), name: extend_string_to_32(&symbol), @@ -546,105 +577,115 @@ fn handle_create_asset_meta_native_token( nonce, })?, // forward coins sent to this message - funds: coins_after_tax(deps, info.funds.clone())?, + funds: info.funds.clone(), })) .add_attribute("meta.token_chain", CHAIN_ID.to_string()) .add_attribute("meta.symbol", symbol) - .add_attribute("meta.asset_id", hex::encode(asset_id)) + .add_attribute("meta.asset_id", hex::encode(external_id.serialize())) .add_attribute("meta.nonce", nonce.to_string()) .add_attribute("meta.block_time", env.block.time.seconds().to_string())) } fn handle_complete_transfer_with_payload( - deps: DepsMut, + mut deps: DepsMut, env: Env, info: MessageInfo, data: &Binary, relayer_address: &HumanAddr, ) -> StdResult { - let state = config_read(deps.storage).load()?; + let (vaa, payload) = parse_and_archive_vaa(deps.branch(), env.clone(), data)?; - let vaa = parse_vaa(deps.as_ref(), env.block.time.seconds(), data)?; - let data = vaa.payload; - - if vaa_archive_check(deps.storage, vaa.hash.as_slice()) { - return ContractError::VaaAlreadyExecuted.std_err(); - } - vaa_archive_add(deps.storage, vaa.hash.as_slice())?; - - // check if vaa is from governance - if is_governance_emitter(&state, vaa.emitter_chain, &vaa.emitter_address) { - return ContractError::InvalidVAAAction.std_err(); - } - - let message = TokenBridgeMessage::deserialize(&data)?; - - match message.action { - Action::TRANSFER_WITH_PAYLOAD => handle_complete_transfer( - deps, - env, - info, - vaa.emitter_chain, - vaa.emitter_address, - TransferType::WithPayload { payload: () }, - &message.payload, - relayer_address, - ), - _ => ContractError::InvalidVAAAction.std_err(), - } -} - -fn submit_vaa( - deps: DepsMut, - env: Env, - info: MessageInfo, - data: &Binary, -) -> StdResult { - let state = config_read(deps.storage).load()?; - - let vaa = parse_vaa(deps.as_ref(), env.block.time.seconds(), data)?; - let data = vaa.payload; - - if vaa_archive_check(deps.storage, vaa.hash.as_slice()) { - return ContractError::VaaAlreadyExecuted.std_err(); - } - vaa_archive_add(deps.storage, vaa.hash.as_slice())?; - - // check if vaa is from governance - if is_governance_emitter(&state, vaa.emitter_chain, &vaa.emitter_address) { - return handle_governance_payload(deps, env, &data); - } - - let message = TokenBridgeMessage::deserialize(&data)?; - - match message.action { - Action::TRANSFER => { - let sender = info.sender.to_string(); - handle_complete_transfer( + if let Either::Right(message) = payload { + match message.action { + Action::TRANSFER_WITH_PAYLOAD => handle_complete_transfer( deps, env, info, vaa.emitter_chain, vaa.emitter_address, - TransferType::WithoutPayload, + TransferType::WithPayload { payload: () }, &message.payload, - &sender, - ) + relayer_address, + ), + _ => ContractError::InvalidVAAAction.std_err(), } - Action::ATTEST_META => handle_attest_meta( - deps, - env, - vaa.emitter_chain, - vaa.emitter_address, - vaa.sequence, - &message.payload, - ), - _ => ContractError::InvalidVAAAction.std_err(), + } else { + return ContractError::InvalidVAAAction.std_err(); } } -fn handle_governance_payload(deps: DepsMut, env: Env, data: &Vec) -> StdResult { - let gov_packet = GovernancePacket::deserialize(&data)?; +enum Either { + Left(A), + Right(B), +} + +fn parse_and_archive_vaa( + deps: DepsMut, + env: Env, + data: &Binary, +) -> StdResult<(ParsedVAA, Either)> { + let state = config_read(deps.storage).load()?; + + let vaa = parse_vaa(deps.as_ref(), env.block.time.seconds(), data)?; + + if vaa_archive_check(deps.storage, vaa.hash.as_slice()) { + return ContractError::VaaAlreadyExecuted.std_err(); + } + vaa_archive_add(deps.storage, vaa.hash.as_slice())?; + + // check if vaa is from governance + if is_governance_emitter(&state, vaa.emitter_chain, &vaa.emitter_address) { + let gov_packet = GovernancePacket::deserialize(&vaa.payload)?; + return Ok((vaa, Either::Left(gov_packet))); + } + + let message = TokenBridgeMessage::deserialize(&vaa.payload)?; + return Ok((vaa, Either::Right(message))); +} + +fn submit_vaa( + mut deps: DepsMut, + env: Env, + info: MessageInfo, + data: &Binary, +) -> StdResult { + let (vaa, payload) = parse_and_archive_vaa(deps.branch(), env.clone(), data)?; + match payload { + Either::Left(governance_packet) => { + return handle_governance_payload(deps, env, &governance_packet) + } + Either::Right(message) => match message.action { + Action::TRANSFER => { + let sender = info.sender.to_string(); + handle_complete_transfer( + deps, + env, + info, + vaa.emitter_chain, + vaa.emitter_address, + TransferType::WithoutPayload, + &message.payload, + &sender, + ) + } + Action::ATTEST_META => handle_attest_meta( + deps, + env, + vaa.emitter_chain, + vaa.emitter_address, + vaa.sequence, + &message.payload, + ), + _ => ContractError::InvalidVAAAction.std_err(), + }, + } +} + +fn handle_governance_payload( + deps: DepsMut, + env: Env, + gov_packet: &GovernancePacket, +) -> StdResult { let module = get_string_from_32(&gov_packet.module); if module != "TokenBridge" { @@ -708,23 +749,28 @@ fn handle_complete_transfer( relayer_address: &HumanAddr, ) -> StdResult { let transfer_info = TransferInfo::deserialize(&data)?; - match transfer_info.token_address.as_slice()[0] { - 1 => handle_complete_transfer_token_native( + let token_id = transfer_info + .token_address + .to_token_id(deps.storage, transfer_info.token_chain)?; + match token_id { + TokenId::Bank { denom } => handle_complete_transfer_token_native( deps, env, info, emitter_chain, emitter_address, + denom, transfer_type, data, relayer_address, ), - _ => handle_complete_transfer_token( + TokenId::Contract(contract) => handle_complete_transfer_token( deps, env, info, emitter_chain, emitter_address, + contract, transfer_type, data, relayer_address, @@ -738,6 +784,7 @@ fn handle_complete_transfer_token( info: MessageInfo, emitter_chain: u16, emitter_address: Vec, + token_contract: ContractId, transfer_type: TransferType<()>, data: &Vec, relayer_address: &HumanAddr, @@ -763,7 +810,6 @@ fn handle_complete_transfer_token( )); } - let token_chain = transfer_info.token_chain; let target_address = (&transfer_info.recipient.as_slice()).get_address(0); let recipient = deps.api.addr_humanize(&target_address)?; @@ -785,16 +831,20 @@ fn handle_complete_transfer_token( return ContractError::AmountTooHigh.std_err(); } - if token_chain != CHAIN_ID { - let asset_address = transfer_info.token_address; - let asset_id = build_asset_id(token_chain, &asset_address); + let external_id = ExternalTokenId::from_token_id(&TokenId::Contract(token_contract.clone()))?; - // Check if this asset is already deployed - let contract_addr = wrapped_asset_read(deps.storage).load(&asset_id).ok(); + match token_contract { + ContractId::ForeignToken { + chain_id, + foreign_address, + } => { + // Check if this asset is already deployed + let contract_addr = wrapped_asset_read(deps.storage, chain_id).load(&foreign_address). + or_else(|_| Err(StdError::generic_err("Wrapped asset not deployed. To deploy, invoke CreateWrapped with the associated AssetMeta")))?; + + let contract_addr = contract_addr.into_string(); - return if let Some(contract_addr) = contract_addr { // Asset already deployed, just mint - let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: contract_addr.clone(), msg: to_binary(&WrappedMsg::Mint { @@ -822,67 +872,63 @@ fn handle_complete_transfer_token( .add_attribute("amount", amount.to_string()) .add_attribute("relayer", relayer_address) .add_attribute("fee", fee.to_string())) - } else { - Err(StdError::generic_err("Wrapped asset not deployed. To deploy, invoke CreateWrapped with the associated AssetMeta")) - }; - } else { - let token_address = transfer_info.token_address.as_slice().get_address(0); + } + ContractId::NativeCW20 { contract_address } => { + // note -- here the amount is the amount the recipient will receive; + // amount + fee is the total sent + receive_native(deps.storage, &external_id, Uint128::new(amount + fee))?; - let contract_addr = deps.api.addr_humanize(&token_address)?; + // undo normalization to 8 decimals + let token_info: TokenInfoResponse = + deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: contract_address.to_string(), + msg: to_binary(&TokenQuery::TokenInfo {})?, + }))?; - // note -- here the amount is the amount the recipient will receive; - // amount + fee is the total sent - receive_native(deps.storage, &token_address, Uint128::new(amount + fee))?; + let decimals = token_info.decimals; + let multiplier = 10u128.pow((max(decimals, 8u8) - 8u8) as u32); + amount = amount.checked_mul(multiplier).unwrap(); + fee = fee.checked_mul(multiplier).unwrap(); - // undo normalization to 8 decimals - let token_info: TokenInfoResponse = - deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: contract_addr.to_string(), - msg: to_binary(&TokenQuery::TokenInfo {})?, - }))?; - - let decimals = token_info.decimals; - let multiplier = 10u128.pow((max(decimals, 8u8) - 8u8) as u32); - amount = amount.checked_mul(multiplier).unwrap(); - fee = fee.checked_mul(multiplier).unwrap(); - - let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.to_string(), - msg: to_binary(&TokenMsg::Transfer { - recipient: recipient.to_string(), - amount: Uint128::from(amount), - })?, - funds: vec![], - })]; - - if fee != 0 { - messages.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: contract_addr.to_string(), + let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_address.to_string(), msg: to_binary(&TokenMsg::Transfer { - recipient: relayer_address.to_string(), - amount: Uint128::from(fee), + recipient: recipient.to_string(), + amount: Uint128::from(amount), })?, funds: vec![], - })) - } + })]; - Ok(Response::new() - .add_messages(messages) - .add_attribute("action", "complete_transfer_native") - .add_attribute("recipient", recipient) - .add_attribute("contract", contract_addr) - .add_attribute("amount", amount.to_string()) - .add_attribute("relayer", relayer_address) - .add_attribute("fee", fee.to_string())) + if fee != 0 { + messages.push(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: contract_address.to_string(), + msg: to_binary(&TokenMsg::Transfer { + recipient: relayer_address.to_string(), + amount: Uint128::from(fee), + })?, + funds: vec![], + })) + } + + Ok(Response::new() + .add_messages(messages) + .add_attribute("action", "complete_transfer_native") + .add_attribute("recipient", recipient) + .add_attribute("contract", contract_address) + .add_attribute("amount", amount.to_string()) + .add_attribute("relayer", relayer_address) + .add_attribute("fee", fee.to_string())) + } } } fn handle_complete_transfer_token_native( - mut deps: DepsMut, + deps: DepsMut, _env: Env, info: MessageInfo, emitter_chain: u16, emitter_address: Vec, + denom: String, transfer_type: TransferType<()>, data: &Vec, relayer_address: &HumanAddr, @@ -929,29 +975,18 @@ fn handle_complete_transfer_token_native( return ContractError::AmountTooHigh.std_err(); } - // Wipe the native byte marker and extract the serialized denom. - let mut token_address = transfer_info.token_address.clone(); - let token_address = token_address.as_mut_slice(); - token_address[0] = 0; - - let mut denom = token_address.to_vec(); - denom.retain(|&c| c != 0); - let denom = String::from_utf8(denom).unwrap(); - - // note -- here the amount is the amount the recipient will receive; - // amount + fee is the total sent - let token_address = (&*token_address).get_address(0); - receive_native(deps.storage, &token_address, Uint128::new(amount + fee))?; + let external_address = ExternalTokenId::from_bank_token(&denom)?; + receive_native(deps.storage, &external_address, Uint128::new(amount + fee))?; let mut messages = vec![CosmosMsg::Bank(BankMsg::Send { to_address: recipient.to_string(), - amount: coins_after_tax(deps.branch(), vec![coin(amount, &denom)])?, + amount: vec![coin(amount, &denom)], })]; if fee != 0 { messages.push(CosmosMsg::Bank(BankMsg::Send { to_address: relayer_address.to_string(), - amount: coins_after_tax(deps, vec![coin(fee, &denom)])?, + amount: vec![coin(fee, &denom)], })); } @@ -971,7 +1006,7 @@ fn handle_initiate_transfer( info: MessageInfo, asset: Asset, recipient_chain: u16, - recipient: Vec, + recipient: [u8; 32], fee: Uint128, transfer_type: TransferType>, nonce: u32, @@ -1005,13 +1040,13 @@ fn handle_initiate_transfer( } fn handle_initiate_transfer_token( - mut deps: DepsMut, + deps: DepsMut, env: Env, info: MessageInfo, asset: HumanAddr, mut amount: Uint128, recipient_chain: u16, - recipient: Vec, + recipient: [u8; 32], mut fee: Uint128, transfer_type: TransferType>, nonce: u32, @@ -1024,7 +1059,7 @@ fn handle_initiate_transfer_token( } let asset_chain: u16; - let asset_address: Vec; + let asset_address: [u8; 32]; let cfg: ConfigInfo = config_read(deps.storage).load()?; let asset_canonical: CanonicalAddr = deps.api.addr_canonicalize(&asset)?; @@ -1032,7 +1067,7 @@ fn handle_initiate_transfer_token( let mut messages: Vec = vec![]; let mut submessages: Vec = vec![]; - match wrapped_asset_address_read(deps.storage).load(asset_canonical.as_slice()) { + match is_wrapped_asset_read(deps.storage).load(asset_canonical.as_slice()) { Ok(_) => { // If the fee is too large the user will receive nothing. if fee > amount { @@ -1052,17 +1087,16 @@ fn handle_initiate_transfer_token( contract_addr: asset, msg: to_binary(&WrappedQuery::WrappedAssetInfo {})?, }); - let wrapped_token_info: WrappedAssetInfoResponse = - deps.querier.custom_query(&request)?; + let wrapped_token_info: WrappedAssetInfoResponse = deps.querier.query(&request)?; asset_chain = wrapped_token_info.asset_chain; - asset_address = wrapped_token_info.asset_address.into(); + asset_address = wrapped_token_info.asset_address.to_array()?; let transfer_info = TransferInfo { token_chain: asset_chain, - token_address: asset_address.clone(), + token_address: ExternalTokenId::from_foreign_token(asset_chain, asset_address), amount: (0, amount.u128()), recipient_chain, - recipient: recipient.clone(), + recipient, fee: (0, fee.u128()), }; @@ -1088,7 +1122,7 @@ fn handle_initiate_transfer_token( nonce, })?, // forward coins sent to this message - funds: coins_after_tax(deps.branch(), info.funds.clone())?, + funds: info.funds.clone(), })); } Err(_) => { @@ -1130,8 +1164,14 @@ fn handle_initiate_transfer_token( 1, )); - asset_address = extend_address_to_32(&asset_canonical); + asset_address = extend_address_to_32_array(&asset_canonical); asset_chain = CHAIN_ID; + let address_human = deps.api.addr_humanize(&asset_canonical)?; + // we store here just in case the token is transferred out before it's attested + let external_id = TokenId::Contract(ContractId::NativeCW20 { + contract_address: address_human, + }) + .store(deps.storage)?; // convert to normalized amounts before recording & posting vaa amount = Uint128::new(amount.u128().checked_div(multiplier).unwrap()); @@ -1139,7 +1179,7 @@ fn handle_initiate_transfer_token( let transfer_info = TransferInfo { token_chain: asset_chain, - token_address: asset_address.clone(), + token_address: external_id, amount: (0, amount.u128()), recipient_chain, recipient: recipient.clone(), @@ -1180,12 +1220,13 @@ fn handle_initiate_transfer_token( }, }; + let token_address = deps.api.addr_validate(&asset)?; + // Wrap up state to be captured by the submessage reply. wrapped_transfer_tmp(deps.storage).save(&TransferState { previous_balance: balance.balance.to_string(), account: info.sender.to_string(), - token_address: asset, - token_canonical: asset_canonical.clone(), + token_address, message: token_bridge_message.serialize(), multiplier: Uint128::new(multiplier).to_string(), nonce, @@ -1211,14 +1252,12 @@ fn handle_initiate_transfer_token( .add_attribute("transfer.block_time", env.block.time.seconds().to_string())) } -/// All ISO-4217 currency codes are 3 letters, so we can safely slice anything that is not ULUNA. -/// https://www.xe.com/iso4217.php fn format_native_denom_symbol(denom: &str) -> String { if denom == "uluna" { return "LUNA".to_string(); } - // UUSD -> US -> UST - denom.to_uppercase()[1..3].to_string() + "T" + //TODO: is there better formatting to do here? + denom.to_uppercase().to_string() } fn handle_initiate_transfer_native_token( @@ -1228,7 +1267,7 @@ fn handle_initiate_transfer_native_token( denom: String, amount: Uint128, recipient_chain: u16, - recipient: Vec, + recipient: [u8; 32], fee: Uint128, transfer_type: TransferType>, nonce: u32, @@ -1255,17 +1294,14 @@ fn handle_initiate_transfer_native_token( let mut messages: Vec = vec![]; let asset_chain: u16 = CHAIN_ID; - let mut asset_address: Vec = build_native_id(&denom); + // we store here just in case the token is transferred out before it's attested + let asset_address = TokenId::Bank { denom }.store(deps.storage)?; - send_native(deps.storage, &asset_address[..].into(), amount)?; - - // Mark the first byte of the address to distinguish it as native. - asset_address = extend_address_to_32(&asset_address.into()); - asset_address[0] = 1; + send_native(deps.storage, &asset_address, amount)?; let transfer_info = TransferInfo { token_chain: asset_chain, - token_address: asset_address.to_vec(), + token_address: asset_address.clone(), amount: (0, amount.u128()), recipient_chain, recipient: recipient.clone(), @@ -1294,13 +1330,13 @@ fn handle_initiate_transfer_native_token( message: Binary::from(token_bridge_message.serialize()), nonce, })?, - funds: coins_after_tax(deps, info.funds.clone())?, + funds: info.funds.clone(), })); Ok(Response::new() .add_messages(messages) .add_attribute("transfer.token_chain", asset_chain.to_string()) - .add_attribute("transfer.token", hex::encode(asset_address)) + .add_attribute("transfer.token", hex::encode(asset_address.serialize())) .add_attribute( "transfer.sender", hex::encode(extend_address_to_32(&sender)), @@ -1319,18 +1355,27 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { to_binary(&query_wrapped_registry(deps, chain, address.as_slice())?) } QueryMsg::TransferInfo { vaa } => to_binary(&query_transfer_info(deps, env, &vaa)?), + QueryMsg::ExternalId { external_id } => to_binary(&query_external_id(deps, external_id)?), } } +fn query_external_id(deps: Deps, external_id: Binary) -> StdResult { + let external_id = ExternalTokenId::deserialize(external_id.to_array()?); + Ok(ExternalIdResponse { + token_id: external_id.to_token_id(deps.storage, CHAIN_ID)?, + }) +} + pub fn query_wrapped_registry( deps: Deps, chain: u16, address: &[u8], ) -> StdResult { - let asset_id = build_asset_id(chain, address); // Check if this asset is already deployed - match wrapped_asset_read(deps.storage).load(&asset_id) { - Ok(address) => Ok(WrappedRegistryResponse { address }), + match wrapped_asset_read(deps.storage, chain).load(&address) { + Ok(address) => Ok(WrappedRegistryResponse { + address: address.into_string(), + }), Err(_) => ContractError::AssetNotFound.std_err(), } } @@ -1355,7 +1400,7 @@ fn query_transfer_info(deps: Deps, env: Env, vaa: &Binary) -> StdResult StdResult Vec { - let chain = &chain.to_be_bytes(); - let mut asset_id = Vec::with_capacity(chain.len() + address.len()); - asset_id.extend_from_slice(chain); - asset_id.extend_from_slice(address); - - let mut hasher = Keccak256::new(); - hasher.update(asset_id); - hasher.finalize().to_vec() -} - -// Produce a 20 byte asset "address" from a native terra denom. -pub fn build_native_id(denom: &str) -> Vec { - let n = denom.len(); - assert!(n < 20); - let mut asset_address = Vec::with_capacity(20); - asset_address.resize(20 - n, 0u8); - asset_address.extend_from_slice(denom.as_bytes()); - asset_address -} - fn is_governance_emitter(cfg: &ConfigInfo, emitter_chain: u16, emitter_address: &Vec) -> bool { cfg.gov_chain == emitter_chain && cfg.gov_address == emitter_address.clone() } diff --git a/cosmwasm/contracts/token-bridge/src/lib.rs b/cosmwasm/contracts/token-bridge/src/lib.rs index e4ccd9f8c..122c7098f 100644 --- a/cosmwasm/contracts/token-bridge/src/lib.rs +++ b/cosmwasm/contracts/token-bridge/src/lib.rs @@ -4,6 +4,10 @@ extern crate lazy_static; pub mod contract; pub mod msg; pub mod state; +pub mod token_address; #[cfg(test)] mod testing; + +// Chain ID of Terra 2.0 +pub const CHAIN_ID: u16 = 18; diff --git a/cosmwasm/contracts/token-bridge/src/msg.rs b/cosmwasm/contracts/token-bridge/src/msg.rs index c08471aa5..3002fd91e 100644 --- a/cosmwasm/contracts/token-bridge/src/msg.rs +++ b/cosmwasm/contracts/token-bridge/src/msg.rs @@ -12,6 +12,11 @@ use terraswap::asset::{ AssetInfo, }; +use crate::token_address::{ + ExternalTokenId, + TokenId, +}; + type HumanAddr = String; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -28,7 +33,8 @@ pub struct InstantiateMsg { #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { RegisterAssetHook { - asset_id: Binary, + chain: u16, + token_address: ExternalTokenId, }, DepositTokens {}, @@ -77,6 +83,7 @@ pub struct MigrateMsg {} pub enum QueryMsg { WrappedRegistry { chain: u16, address: Binary }, TransferInfo { vaa: Binary }, + ExternalId { external_id: Binary }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -89,10 +96,16 @@ pub struct WrappedRegistryResponse { #[serde(rename_all = "snake_case")] pub struct TransferInfoResponse { pub amount: Uint128, - pub token_address: Vec, + pub token_address: [u8; 32], pub token_chain: u16, - pub recipient: Vec, + pub recipient: [u8; 32], pub recipient_chain: u16, pub fee: Uint128, pub payload: Vec, } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct ExternalIdResponse { + pub token_id: TokenId, +} diff --git a/cosmwasm/contracts/token-bridge/src/state.rs b/cosmwasm/contracts/token-bridge/src/state.rs index 63e8b374a..6dc423af9 100644 --- a/cosmwasm/contracts/token-bridge/src/state.rs +++ b/cosmwasm/contracts/token-bridge/src/state.rs @@ -5,7 +5,7 @@ use serde::{ }; use cosmwasm_std::{ - CanonicalAddr, + Addr, StdError, StdResult, Storage, @@ -24,6 +24,8 @@ use cosmwasm_storage::{ use wormhole::byte_utils::ByteUtils; +use crate::token_address::{ExternalTokenId, WrappedCW20}; + type HumanAddr = String; pub static CONFIG_KEY: &[u8] = b"config"; @@ -34,6 +36,8 @@ pub static WRAPPED_ASSET_ADDRESS_KEY: &[u8] = b"wrapped_asset_address"; pub static BRIDGE_CONTRACTS: &[u8] = b"bridge_contracts"; pub static BRIDGE_DEPOSITS: &[u8] = b"bridge_deposits"; pub static NATIVE_COUNTER: &[u8] = b"native_counter"; +pub static BANK_TOKEN_HASHES_KEY: &[u8] = b"bank_token_hashes"; +pub static NATIVE_CW20_HASHES_KEY: &[u8] = b"native_cw20_hashes"; // Guardian set information #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -70,30 +74,46 @@ pub fn bridge_contracts_read(storage: &dyn Storage) -> ReadonlyBucket> { bucket_read(storage, BRIDGE_CONTRACTS) } -pub fn wrapped_asset(storage: &mut dyn Storage) -> Bucket { - bucket(storage, WRAPPED_ASSET_KEY) +pub fn wrapped_asset(storage: &mut dyn Storage, chain: u16) -> Bucket { + Bucket::multilevel(storage, &[WRAPPED_ASSET_KEY, &chain.to_be_bytes()]) } -pub fn wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, WRAPPED_ASSET_KEY) +pub fn wrapped_asset_read(storage: &dyn Storage, chain: u16) -> ReadonlyBucket { + ReadonlyBucket::multilevel(storage, &[WRAPPED_ASSET_KEY, &chain.to_be_bytes()]) } -pub fn wrapped_asset_seq(storage: &mut dyn Storage) -> Bucket { - bucket(storage, WRAPPED_ASSET_SEQ_KEY) +pub fn wrapped_asset_seq(storage: &mut dyn Storage, chain: u16) -> Bucket { + Bucket::multilevel(storage, &[WRAPPED_ASSET_KEY, &chain.to_be_bytes()]) } -pub fn wrapped_asset_seq_read(storage: &mut dyn Storage) -> ReadonlyBucket { - bucket_read(storage, WRAPPED_ASSET_SEQ_KEY) +pub fn wrapped_asset_seq_read(storage: &mut dyn Storage, chain: u16) -> ReadonlyBucket { + ReadonlyBucket::multilevel(storage, &[WRAPPED_ASSET_KEY, &chain.to_be_bytes()]) } -pub fn wrapped_asset_address(storage: &mut dyn Storage) -> Bucket> { +pub fn is_wrapped_asset(storage: &mut dyn Storage) -> Bucket<()> { bucket(storage, WRAPPED_ASSET_ADDRESS_KEY) } -pub fn wrapped_asset_address_read(storage: &dyn Storage) -> ReadonlyBucket> { +pub fn is_wrapped_asset_read(storage: &dyn Storage) -> ReadonlyBucket<()> { bucket_read(storage, WRAPPED_ASSET_ADDRESS_KEY) } +pub fn bank_token_hashes(storage: &mut dyn Storage) -> Bucket { + bucket(storage, BANK_TOKEN_HASHES_KEY) +} + +pub fn bank_token_hashes_read(storage: &dyn Storage) -> ReadonlyBucket { + bucket_read(storage, BANK_TOKEN_HASHES_KEY) +} + +pub fn native_c20_hashes(storage: &mut dyn Storage) -> Bucket { + bucket(storage, NATIVE_CW20_HASHES_KEY) +} + +pub fn native_c20_hashes_read(storage: &dyn Storage) -> ReadonlyBucket { + bucket_read(storage, NATIVE_CW20_HASHES_KEY) +} + type Serialized128 = String; /// Structure to keep track of an active CW20 transfer, required to pass state through to the reply @@ -105,8 +125,7 @@ pub struct TransferState { pub multiplier: Serialized128, pub nonce: u32, pub previous_balance: Serialized128, - pub token_address: HumanAddr, - pub token_canonical: CanonicalAddr, + pub token_address: Addr, } pub fn wrapped_transfer_tmp(storage: &mut dyn Storage) -> Singleton { @@ -115,31 +134,31 @@ pub fn wrapped_transfer_tmp(storage: &mut dyn Storage) -> Singleton StdResult<()> { let mut counter_bucket = bucket(storage, NATIVE_COUNTER); let new_total = amount + counter_bucket - .load(asset_address.as_slice()) + .load(asset_address.serialize().as_slice()) .unwrap_or(Uint128::zero()); if new_total > Uint128::new(u64::MAX as u128) { return Err(StdError::generic_err( "transfer exceeds max outstanding bridged token amount", )); } - counter_bucket.save(asset_address.as_slice(), &new_total) + counter_bucket.save(asset_address.serialize().as_slice(), &new_total) } pub fn receive_native( storage: &mut dyn Storage, - asset_address: &CanonicalAddr, + asset_address: &ExternalTokenId, amount: Uint128, ) -> StdResult<()> { let mut counter_bucket = bucket(storage, NATIVE_COUNTER); - let total: Uint128 = counter_bucket.load(asset_address.as_slice())?; + let total: Uint128 = counter_bucket.load(asset_address.serialize().as_slice())?; let result = total.checked_sub(amount)?; - counter_bucket.save(asset_address.as_slice(), &result) + counter_bucket.save(asset_address.serialize().as_slice(), &result) } pub struct Action; @@ -185,9 +204,9 @@ impl TokenBridgeMessage { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct TransferInfo { pub amount: (u128, u128), - pub token_address: Vec, + pub token_address: ExternalTokenId, pub token_chain: u16, - pub recipient: Vec, + pub recipient: [u8; 32], pub recipient_chain: u16, pub fee: (u128, u128), } @@ -196,9 +215,9 @@ impl TransferInfo { pub fn deserialize(data: &Vec) -> StdResult { let data = data.as_slice(); let amount = data.get_u256(0); - let token_address = data.get_bytes32(32).to_vec(); + let token_address = ExternalTokenId::deserialize(data.get_const_bytes::<32>(32)); let token_chain = data.get_u16(64); - let recipient = data.get_bytes32(66).to_vec(); + let recipient = data.get_const_bytes::<32>(66); let recipient_chain = data.get_u16(98); let fee = data.get_u256(100); @@ -215,7 +234,7 @@ impl TransferInfo { [ self.amount.0.to_be_bytes().to_vec(), self.amount.1.to_be_bytes().to_vec(), - self.token_address.clone(), + self.token_address.serialize().to_vec(), self.token_chain.to_be_bytes().to_vec(), self.recipient.to_vec(), self.recipient_chain.to_be_bytes().to_vec(), @@ -265,7 +284,7 @@ impl TransferWithPayloadInfo { // 67 [32]uint8 Name pub struct AssetMeta { - pub token_address: Vec, + pub token_address: ExternalTokenId, pub token_chain: u16, pub decimals: u8, pub symbol: Vec, @@ -275,7 +294,7 @@ pub struct AssetMeta { impl AssetMeta { pub fn deserialize(data: &Vec) -> StdResult { let data = data.as_slice(); - let token_address = data.get_bytes32(0).to_vec(); + let token_address = ExternalTokenId::deserialize(data.get_const_bytes::<32>(0)); let token_chain = data.get_u16(32); let decimals = data.get_u8(34); let symbol = data.get_bytes32(35).to_vec(); @@ -292,7 +311,7 @@ impl AssetMeta { pub fn serialize(&self) -> Vec { [ - self.token_address.clone(), + self.token_address.serialize().to_vec(), self.token_chain.to_be_bytes().to_vec(), self.decimals.to_be_bytes().to_vec(), self.symbol.clone(), diff --git a/cosmwasm/contracts/token-bridge/src/testing/tests.rs b/cosmwasm/contracts/token-bridge/src/testing/tests.rs index 84d4372ca..a563afca7 100644 --- a/cosmwasm/contracts/token-bridge/src/testing/tests.rs +++ b/cosmwasm/contracts/token-bridge/src/testing/tests.rs @@ -1,3 +1,5 @@ +use std::convert::TryInto; + use cosmwasm_std::{ Binary, StdResult, @@ -6,16 +8,13 @@ use cosmwasm_std::{ use wormhole::state::ParsedVAA; use crate::{ - contract::{ - build_asset_id, - build_native_id, - }, state::{ Action, TokenBridgeMessage, TransferInfo, TransferWithPayloadInfo, }, + token_address::ExternalTokenId, }; #[test] @@ -52,27 +51,31 @@ fn binary_check() -> StdResult<()> { #[test] fn build_native_and_asset_ids() -> StdResult<()> { - let denom = "uusd"; - let native_id = build_native_id(denom); + let external_id_uluna = ExternalTokenId::from_bank_token(&"uluna".to_string())?; - let expected_native_id = vec![ - 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 117u8, - 117u8, 115u8, 100u8, - ]; - assert_eq!(&native_id, &expected_native_id, "native_id != expected"); + let expected_external_id: [u8; 32] = [1, 250, 108, 111, 188, 54, 216, 194, 69, 176, 168, 82, 164, 62, 181, 214, 68, 232, 180, 196, 119, 178, 123, 250, 185, 83, 124, 16, 148, 89, 57, 218]; + assert_eq!( + &external_id_uluna.serialize(), + &expected_external_id, + "external_id != expected" + ); // weth let chain = 2u16; let token_address = "000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"; - let token_address = hex::decode(token_address).unwrap(); - let asset_id = build_asset_id(chain, token_address.as_slice()); + let token_address: [u8; 32] = hex::decode(token_address) + .unwrap() + .as_slice() + .try_into() + .unwrap(); + let external_id_weth = ExternalTokenId::from_foreign_token(chain, token_address); - let expected_asset_id = vec![ - 171u8, 106u8, 233u8, 80u8, 14u8, 139u8, 124u8, 78u8, 181u8, 77u8, 142u8, 76u8, 109u8, 81u8, - 55u8, 100u8, 139u8, 159u8, 42u8, 85u8, 172u8, 234u8, 0u8, 114u8, 11u8, 82u8, 40u8, 40u8, - 50u8, 73u8, 211u8, 135u8, - ]; - assert_eq!(&asset_id, &expected_asset_id, "asset_id != expected"); + let expected_asset_id: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 42, 170, 57, 178, 35, 254, 141, 10, 14, 92, 79, 39, 234, 217, 8, 60, 117, 108, 194]; + assert_eq!( + &external_id_weth.serialize(), + &expected_asset_id, + "asset_id != expected" + ); Ok(()) } @@ -105,7 +108,8 @@ fn deserialize_transfer_vaa() -> StdResult<()> { let token_address = "0100000000000000000000000000000000000000000000000000000075757364"; let token_address = hex::decode(token_address).unwrap(); assert_eq!( - info.token_address, token_address, + info.token_address.serialize().to_vec(), + token_address, "info.token_address != expected" ); @@ -117,7 +121,11 @@ fn deserialize_transfer_vaa() -> StdResult<()> { let recipient = "000000000000000000000000f7f7dde848e7450a029cd0a9bd9bdae4b5147db3"; let recipient = hex::decode(recipient).unwrap(); - assert_eq!(info.recipient, recipient, "info.recipient != expected"); + assert_eq!( + info.recipient.to_vec(), + recipient, + "info.recipient != expected" + ); let recipient_chain = 3u16; assert_eq!( @@ -162,7 +170,8 @@ fn deserialize_transfer_with_payload_vaa() -> StdResult<()> { let token_address = "0100000000000000000000000000000000000000000000000000000075757364"; let token_address = hex::decode(token_address).unwrap(); assert_eq!( - info.token_address, token_address, + info.token_address.serialize().to_vec(), + token_address, "info.token_address != expected" ); @@ -174,7 +183,11 @@ fn deserialize_transfer_with_payload_vaa() -> StdResult<()> { let recipient = "0000000000000000000000008cec800d24df11e556e708461c98122df4a2c3b1"; let recipient = hex::decode(recipient).unwrap(); - assert_eq!(info.recipient, recipient, "info.recipient != expected"); + assert_eq!( + info.recipient.to_vec(), + recipient, + "info.recipient != expected" + ); let recipient_chain = 3u16; assert_eq!( diff --git a/cosmwasm/contracts/token-bridge/src/token_address.rs b/cosmwasm/contracts/token-bridge/src/token_address.rs new file mode 100644 index 000000000..6b3a8bd9d --- /dev/null +++ b/cosmwasm/contracts/token-bridge/src/token_address.rs @@ -0,0 +1,228 @@ +use cosmwasm_std::{ + Addr, + StdError, + StdResult, + Storage, +}; + +use schemars::JsonSchema; +use serde::{ + Deserialize, + Serialize, +}; +use sha3::{ + Digest, + Keccak256, +}; + +use crate::{ + state::{ + bank_token_hashes, + bank_token_hashes_read, + native_c20_hashes, + native_c20_hashes_read, + }, + CHAIN_ID, +}; + +/// Represent the external view of a token address. +/// This is the value that goes into the VAA. +/// +/// When given an external 32 byte address, there are 3 options: +/// I. This is a token native to this chain +/// a. it's a token managed by the Bank cosmos module +/// (e.g. the staking denom "uluna" on Terra) +/// b. it's a CW20 token +/// II. This is a token address from another chain +/// +/// Thus, interpreting an external token id requires knowing whether the token +/// in question originates from this chain, or another chain. This information +/// will always be available from the context. +/// +/// I. ////////////////////////////////////////////////////////////////////////// +/// +/// In the first case (native tokens), the layout of is the following: +/// +/// | 1 byte | 31 bytes | +/// +--------+-----------------------------------------------------------------+ +/// | MARKER | HASH | +/// +--------+-----------------------------------------------------------------+ +/// +/// The left-most byte (MARKER) tells us whether it's a Bank token (1), or a CW20 (0). +/// Since denom names can be arbitarily long, and CW20 addresses are 32 byes, we +/// cannot directly encode them into the remaining 31 bytes. Instead, we hash +/// the data (either the denom or the CW20 address), and put the last 31 bytes +/// of the hash into the address (HASH). In particular, this choice reduces the +/// space of the hash function by 8 bits, but assuming the hash is resistant to +/// differential attacks, we consider giving up on these 8 bits safe. +/// +/// In order to be able to recover the denom and the contract address later, we +/// store a mapping from these 32 bytes (MARKER+HASH) to denoms and CW20 +/// addresses (c.f. [`native_cw20_hashes`] & [`bank_token_hashes`] in state.rs) +/// +/// II. ///////////////////////////////////////////////////////////////////////// +/// +/// In the second case (foreign tokens), the whole 32 bytes correspond to the +/// external token address. In this case, the corresponding token will be a +/// wrapped asset, whose address is stored in storage as a mapping (c.f. +/// [`wrapped_asset`] in state.rs) +/// +/// (chain_id, external_id) => wrapped_asset_address +/// +/// For internal consumption of these addresses, we first convert them to +/// [`TokenId`] (see below). +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[repr(transparent)] +pub struct ExternalTokenId { + bytes: [u8; 32], +} + +/// The intention is that [`ExternalTokenId`] should always be converted to/from +/// [`TokenId`] through the functions defined in this module. This is why its +/// internal contents are private. The following functions are called +/// [`serialize`] and [`deserialize`] to signify that they should only be used +/// when converting back and forth the wire format. +impl ExternalTokenId { + pub fn serialize(&self) -> [u8; 32] { + self.bytes + } + + pub fn deserialize(data: [u8; 32]) -> Self { + Self { bytes: data } + } +} + +impl ExternalTokenId { + pub fn to_token_id(&self, storage: &dyn Storage, origin_chain: u16) -> StdResult { + if origin_chain == CHAIN_ID { + let marker_byte = self.bytes[0]; + match marker_byte { + 1 => { + let denom = bank_token_hashes_read(storage).load(&self.bytes)?; + Ok(TokenId::Bank { denom }) + } + 0 => { + let human_address = native_c20_hashes_read(storage).load(&self.bytes)?; + Ok(TokenId::Contract(ContractId::NativeCW20 { + contract_address: human_address, + })) + } + b => Err(StdError::generic_err(format!("Unknown marker byte: {}", b))), + } + } else { + Ok(TokenId::Contract(ContractId::ForeignToken { + chain_id: origin_chain, + foreign_address: self.bytes, + })) + } + } + + pub fn from_native_cw20(contract_address: &Addr) -> StdResult { + let mut hash = hash(contract_address.as_bytes()); + // override first byte with marker byte + hash[0] = 0; + Ok(ExternalTokenId { bytes: hash }) + } + + pub fn from_foreign_token(chain_id: u16, foreign_address: [u8; 32]) -> ExternalTokenId { + assert!(chain_id != CHAIN_ID, "Expected a foreign chain id."); + ExternalTokenId { + bytes: foreign_address, + } + } + + pub fn from_bank_token(denom: &String) -> StdResult { + let mut hash = hash(&denom.as_bytes()); + // override first byte with marker byte + hash[0] = 1; + Ok(ExternalTokenId { bytes: hash }) + } + + pub fn from_token_id(token_id: &TokenId) -> StdResult { + match token_id { + TokenId::Bank { denom } => Self::from_bank_token(denom), + TokenId::Contract(contract) => match contract { + ContractId::NativeCW20 { contract_address } => { + Self::from_native_cw20(contract_address) + } + ContractId::ForeignToken { + chain_id, + foreign_address, + } => Ok(Self::from_foreign_token(*chain_id, *foreign_address)), + }, + } + } +} + +/// Internal view of an address. This type is similar to [`AssetInfo`], but more +/// granular. We do differentiate between bank tokens and CW20 tokens, but in +/// the latter case, we further differentiate between native CW20s and wrapped +/// CW20s (see [`ContractId`]). +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub enum TokenId { + Bank { denom: String }, + Contract(ContractId), +} + +impl TokenId { + /// Given a [`TokenId`], we can always directly construct an + /// [`ExternalTokenId`], but the converse is not true, since the + /// construction of external ids involves hashing, and is thus irreversible. + /// To maintain the bijection (modulo hash collisions), we store the hash + /// preimages in storage, so given an external id, the necessary information + /// can always be queried to reconstruct the token id. + /// This information must be stored when the token id is first converted to + /// an external id, i.e. when an attestation is generated for the token. + pub fn store(&self, storage: &mut dyn Storage) -> StdResult { + let external_id = ExternalTokenId::from_token_id(self)?; + match self { + TokenId::Bank { denom } => bank_token_hashes(storage).save(&external_id.bytes, denom), + TokenId::Contract(contract) => match contract { + ContractId::NativeCW20 { contract_address } => { + native_c20_hashes(storage).save(&external_id.bytes, &contract_address) + } + ContractId::ForeignToken { + chain_id: _, + foreign_address: _, + } => Err(StdError::generic_err( + "Foreign tokens are not stored in storage", + )), + }, + }?; + Ok(external_id) + } +} + +/// A contract id is either a native cw20 address, or a foreign token. The +/// reason we represent the foreign address here instead of storing the wrapped +/// CW20 contract's address directly is that the wrapped asset might not be +/// deployed yet. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +pub enum ContractId { + NativeCW20 { + contract_address: Addr, + }, + /// A wrapped token might not exist yet. + ForeignToken { + chain_id: u16, + foreign_address: [u8; 32], + }, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[repr(transparent)] +pub struct WrappedCW20 { + pub human_address: Addr, +} + +impl WrappedCW20 { + pub fn into_string(self) -> String { + self.human_address.into_string() + } +} + +fn hash(bytes: &[u8]) -> [u8; 32] { + let mut hasher = Keccak256::new(); + hasher.update(bytes); + hasher.finalize().into() +} diff --git a/cosmwasm/contracts/wormhole/Cargo.toml b/cosmwasm/contracts/wormhole/Cargo.toml index 534d284d4..0ec7ef873 100644 --- a/cosmwasm/contracts/wormhole/Cargo.toml +++ b/cosmwasm/contracts/wormhole/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "wormhole-bridge-terra" +name = "wormhole-bridge-terra-2" version = "0.1.0" authors = ["Yuriy Savchenko "] edition = "2018" @@ -15,14 +15,14 @@ backtraces = ["cosmwasm-std/backtraces"] library = [] [dependencies] -cosmwasm-std = { version = "0.16.0" } -cosmwasm-storage = { version = "0.16.0" } -schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } -cw20 = "0.8.0" -cw20-base = { version = "0.8.0", features = ["library"] } -cw20-wrapped = { path = "../cw20-wrapped", features = ["library"] } -thiserror = { version = "1.0.20" } +cosmwasm-std = { version = "1.0.0" } +cosmwasm-storage = { version = "1.0.0" } +schemars = "0.8.8" +serde = { version = "1.0.137", default-features = false, features = ["derive"] } +cw20 = "0.13.2" +cw20-base = { version = "0.13.2", features = ["library"] } +cw20-wrapped-2 = { path = "../cw20-wrapped", features = ["library"] } +thiserror = { version = "1.0.31" } k256 = { version = "0.9.4", default-features = false, features = ["ecdsa"] } getrandom = { version = "0.2", features = ["custom"] } sha3 = { version = "0.9.1", default-features = false } diff --git a/cosmwasm/contracts/wormhole/src/byte_utils.rs b/cosmwasm/contracts/wormhole/src/byte_utils.rs index b31b6c850..63321c0f0 100644 --- a/cosmwasm/contracts/wormhole/src/byte_utils.rs +++ b/cosmwasm/contracts/wormhole/src/byte_utils.rs @@ -43,8 +43,12 @@ impl ByteUtils for &[u8] { (self.get_u128_be(index), self.get_u128_be(index + 128 / 8)) } fn get_address(&self, index: usize) -> CanonicalAddr { - // 32 bytes are reserved for addresses, but only the last 20 bytes are taken by the actual address - CanonicalAddr::from(&self[index + 32 - 20..index + 32]) + // 32 bytes are reserved for addresses, but wasmd uses both 32 and 20 bytes + // https://github.com/CosmWasm/wasmd/blob/ac92fdcf37388cc8dc24535f301f64395f8fb3da/x/wasm/types/types.go#L325 + if self.get_u128_be(index) >> 32 == 0 { + return CanonicalAddr::from(&self[index + 12..index + 32]) + } + return CanonicalAddr::from(&self[index..index + 32]) } fn get_bytes32(&self, index: usize) -> &[u8] { &self[index..index + 32] @@ -61,13 +65,13 @@ impl ByteUtils for &[u8] { } } -/// Left-pad a 20 byte address with 0s +/// Left-pad a <= 32 byte address with 0s pub fn extend_address_to_32(addr: &CanonicalAddr) -> Vec { extend_address_to_32_array(addr).to_vec() } pub fn extend_address_to_32_array(addr: &CanonicalAddr) -> [u8; 32] { - let mut v: Vec = vec![0; 12]; + let mut v: Vec = vec![0; 32 - addr.len()]; v.extend(addr.as_slice()); let mut result: [u8; 32] = [0; 32]; result.copy_from_slice(&v); diff --git a/cosmwasm/contracts/wormhole/src/contract.rs b/cosmwasm/contracts/wormhole/src/contract.rs index e49e3a0e8..ec1c71f37 100644 --- a/cosmwasm/contracts/wormhole/src/contract.rs +++ b/cosmwasm/contracts/wormhole/src/contract.rs @@ -76,8 +76,8 @@ use std::convert::TryFrom; type HumanAddr = String; -// Chain ID of Terra -const CHAIN_ID: u16 = 3; +// Chain ID of Terra 2.0 +const CHAIN_ID: u16 = 18; // Lock assets fee amount and denomination const FEE_AMOUNT: u128 = 0; diff --git a/cosmwasm/contracts/wormhole/tests/integration.rs b/cosmwasm/contracts/wormhole/tests/integration.rs index 71ddbb53d..f087cbc5e 100644 --- a/cosmwasm/contracts/wormhole/tests/integration.rs +++ b/cosmwasm/contracts/wormhole/tests/integration.rs @@ -40,7 +40,7 @@ fn get_config_info(storage: &S) -> ConfigInfo { } fn do_init(guardians: &[GuardianAddress]) -> OwnedDeps { - let mut deps = mock_dependencies(&[]); + let mut deps = mock_dependencies(); let init_msg = InstantiateMsg { gov_chain: 0, gov_address: GOV_ADDR.into(), diff --git a/cosmwasm/devnet/Dockerfile b/cosmwasm/devnet/Dockerfile index 1e5b2f8e7..a27cb4c91 100644 --- a/cosmwasm/devnet/Dockerfile +++ b/cosmwasm/devnet/Dockerfile @@ -1,3 +1,3 @@ -FROM terramoney/localterra-core:bombay@sha256:0f93576ae0716f835b2adbd5ac550ef90063b536e99c4dd682b6dd905927f261 +FROM terramoney/localterra-core:2.0.1@sha256:73faa857d32b869b6bd3bf062351bd47ca5440d758dc07d5481424b9a9bdaede ADD config /root/.terra/config diff --git a/cosmwasm/devnet/config/app.toml b/cosmwasm/devnet/config/app.toml index 59c583aab..28b137181 100644 --- a/cosmwasm/devnet/config/app.toml +++ b/cosmwasm/devnet/config/app.toml @@ -8,11 +8,11 @@ # The minimum gas prices a validator is willing to accept for processing a # transaction. A transaction's fees must meet the minimum of any denomination # specified in this config (e.g. 0.25token1;0.0001token2). -minimum-gas-prices = "0.01133uluna,0.15uusd,0.104938usdr,169.77ukrw,428.571umnt,0.125ueur,0.98ucny,16.37ujpy,0.11ugbp,10.88uinr,0.19ucad,0.14uchf,0.19uaud,0.2usgd,4.62uthb,1.25usek" +minimum-gas-prices = "0.15uluna" # default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals # nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) -# everything: all saved states will be deleted, storing only the current state; pruning at 10 block intervals +# everything: all saved states will be deleted, storing only the current and previous state; pruning at 10 block intervals # custom: allow pruning options to be manually specified through 'pruning-keep-recent', 'pruning-keep-every', and 'pruning-interval' pruning = "default" @@ -44,7 +44,7 @@ halt-time = 0 # It has no bearing on application state pruning which is determined by the # "pruning-*" configurations. # -# Note: Tendermint block pruning is dependant on this parameter in conjunction +# Note: Tendermint block pruning is dependant on this parameter in conunction # with the unbonding (safety threshold) period, state pruning and state sync # snapshot parameters to determine the correct minimum value of # ResponseCommit.RetainHeight. @@ -60,6 +60,10 @@ inter-block-cache = true # ["message.sender", "message.recipient"] index-events = [] +# IavlCacheSize set the size of the iavl tree cache. +# Default cache size is 50mb. +iavl-cache-size = 781250 + ############################################################################### ### Telemetry Configuration ### ############################################################################### @@ -116,7 +120,7 @@ max-open-connections = 1000 rpc-read-timeout = 10 # RPCWriteTimeout defines the Tendermint RPC write timeout (in seconds). -rpc-write-timeout = 30 +rpc-write-timeout = 0 # RPCMaxBodyBytes defines the Tendermint maximum response body (in bytes). rpc-max-body-bytes = 1000000 @@ -192,15 +196,8 @@ snapshot-interval = 0 snapshot-keep-recent = 2 [wasm] -# The maximum gas amount can be spent for contract query. -# The contract query will invoke contract execution vm, -# so we need to restrict the max usage to prevent DoS attack -contract-query-gas-limit = "3000000" - -# The flag to specify whether print contract logs or not -contract-debug-mode = "false" - -# The WASM VM memory cache size in MiB not bytes -contract-memory-cache-size = "500" - -contract-logging-whitelist = "*" +# This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries +query_gas_limit = 300000 +# This is the number of wasm vm instances we keep cached in memory for speed-up +# Warning: this is currently unstable and may lead to crashes, best to keep for 0 unless testing locally +lru_size = 0 diff --git a/cosmwasm/devnet/config/config.toml b/cosmwasm/devnet/config/config.toml index 2848518b6..7a1f9a1e9 100644 --- a/cosmwasm/devnet/config/config.toml +++ b/cosmwasm/devnet/config/config.toml @@ -12,7 +12,7 @@ # TCP or UNIX socket address of the ABCI application, # or the name of an ABCI application compiled in with the Tendermint binary -proxy_app = "tcp://127.0.0.1:26656" +proxy_app = "tcp://127.0.0.1:26658" # A custom human readable name for this node moniker = "localterra" @@ -47,7 +47,7 @@ db_backend = "goleveldb" db_dir = "data" # Output level for logging, including package level options -log_level = "debug" +log_level = "info" # Output format: 'plain' (colored text) or 'json' log_format = "plain" @@ -136,14 +136,41 @@ max_subscription_clients = 100 # the estimated # maximum number of broadcast_tx_commit calls per block. max_subscriptions_per_client = 5 +# Experimental parameter to specify the maximum number of events a node will +# buffer, per subscription, before returning an error and closing the +# subscription. Must be set to at least 100, but higher values will accommodate +# higher event throughput rates (and will use more memory). +experimental_subscription_buffer_size = 200 + +# Experimental parameter to specify the maximum number of RPC responses that +# can be buffered per WebSocket client. If clients cannot read from the +# WebSocket endpoint fast enough, they will be disconnected, so increasing this +# parameter may reduce the chances of them being disconnected (but will cause +# the node to use more memory). +# +# Must be at least the same as "experimental_subscription_buffer_size", +# otherwise connections could be dropped unnecessarily. This value should +# ideally be somewhat higher than "experimental_subscription_buffer_size" to +# accommodate non-subscription-related RPC responses. +experimental_websocket_write_buffer_size = 200 + +# If a WebSocket client cannot read fast enough, at present we may +# silently drop events instead of generating an error or disconnecting the +# client. +# +# Enabling this experimental parameter will cause the WebSocket connection to +# be closed instead if it cannot read fast enough, allowing for greater +# predictability in subscription behaviour. +experimental_close_on_slow_client = false + # How long to wait for a tx to be committed during /broadcast_tx_commit. # WARNING: Using a value larger than 10s will result in increasing the # global HTTP write timeout, which applies to all connections and endpoints. # See https://github.com/tendermint/tendermint/issues/3435 -timeout_broadcast_tx_commit = "10s" +timeout_broadcast_tx_commit = "30s" # Maximum size of request body, in bytes -max_body_bytes = 4194304 +max_body_bytes = 1000000 # Maximum size of request header, in bytes max_header_bytes = 1048576 @@ -172,12 +199,13 @@ pprof_laddr = "localhost:6060" [p2p] # Address to listen for incoming connections -laddr = "tcp://0.0.0.0:26660" +laddr = "tcp://0.0.0.0:26656" # Address to advertise to peers for them to dial # If empty, will use the same port as the laddr, # and will introspect on the listener or use UPnP -# to figure out the address. +# to figure out the address. ip and port are required +# example: 159.89.10.97:26656 external_address = "" # Comma separated list of seed nodes to connect to @@ -302,6 +330,13 @@ discovery_time = "15s" # Will create a new, randomly named directory within, and remove it when done. temp_dir = "" +# The timeout duration before re-requesting a chunk, possibly from a different +# peer (default: 1 minute). +chunk_request_timeout = "10s" + +# The number of concurrent chunk fetchers to run (default: 1). +chunk_fetchers = "4" + ####################################################### ### Fast Sync Configuration Connections ### ####################################################### diff --git a/cosmwasm/devnet/config/genesis.json b/cosmwasm/devnet/config/genesis.json index 6e5ad6489..029f9043a 100644 --- a/cosmwasm/devnet/config/genesis.json +++ b/cosmwasm/devnet/config/genesis.json @@ -1,5 +1,5 @@ { - "genesis_time": "2021-05-26T10:02:06.396784Z", + "genesis_time": "2022-05-16T04:54:32.922225Z", "chain_id": "localterra", "initial_height": "1", "consensus_params": { @@ -14,9 +14,7 @@ "max_bytes": "1048576" }, "validator": { - "pub_key_types": [ - "ed25519" - ] + "pub_key_types": ["ed25519"] }, "version": {} }, @@ -122,299 +120,107 @@ { "address": "terra199vw7724lzkwz6lf2hsx04lrxfkz09tg8dlp6r", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra18wlvftxzj6zt0xugy2lr9nxzu402690ltaf4ss", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1fmcjjt6yc9wqup2r06urnrd928jhrde6gcld6n", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1dcegyrekltswvyy0xy69ydgxn9x8x32zdtapd8", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1333veey879eeqcff8j3gfcgwt8cfrg9mq20v6f", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1e8ryd9ezefuucd4mje33zdms9m2s90m57878v9", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra17tv2hvwpg0ukqgd2y5ct2w54fyan7z0zxrm2f9", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1757tkx08n0cqrw7p86ny9lnxsqeth0wgp0em95", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra17lmam6zguazs5q5u6z5mmx76uj63gldnse2pdp", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] }, { "address": "terra1lkccuqgj6sjwjn8gsa9xlklqv4pmrqg9dx2fxc", "coins": [ - { - "denom": "ueur", - "amount": "10000000000000000" - }, - { - "denom": "ukrw", - "amount": "1000000000000000000" - }, { "denom": "uluna", "amount": "1000000000000000" - }, - { - "denom": "usdr", - "amount": "10000000000000000" - }, - { - "denom": "uusd", - "amount": "10000000000000000" } ] } ], "supply": [ - { - "denom": "ueur", - "amount": "110000000000000000" - }, - { - "denom": "ukrw", - "amount": "11000000000000000000" - }, { "denom": "uluna", "amount": "11000000000000000" - }, - { - "denom": "usdr", - "amount": "110000000000000000" - }, - { - "denom": "uusd", - "amount": "110000000000000000" } ], "denom_metadata": [] @@ -548,10 +354,7 @@ "clients_consensus": [], "clients_metadata": [], "params": { - "allowed_clients": [ - "06-solomachine", - "07-tendermint" - ] + "allowed_clients": ["06-solomachine", "07-tendermint"] }, "create_localhost": false, "next_client_sequence": "0" @@ -572,13 +375,6 @@ "next_channel_sequence": "0" } }, - "market": { - "params": { - "base_pool": "7000000000000.000000000000000000", - "pool_recovery_period": "200", - "min_stability_spread": "0.005000000000000000" - } - }, "mint": { "minter": { "inflation": "0.130000000000000000", @@ -586,48 +382,13 @@ }, "params": { "mint_denom": "uluna", - "inflation_rate_change": "0.000000000000000000", + "inflation_rate_change": "0.130000000000000000", "inflation_max": "0.200000000000000000", "inflation_min": "0.070000000000000000", "goal_bonded": "0.670000000000000000", "blocks_per_year": "6311520" } }, - "oracle": { - "params": { - "vote_period": "5", - "vote_threshold": "0.500000000000000000", - "reward_band": "0.020000000000000000", - "reward_distribution_window": "5256000", - "whitelist": [ - { - "name": "ukrw", - "tobin_tax": "0.002500000000000000" - }, - { - "name": "usdr", - "tobin_tax": "0.002500000000000000" - }, - { - "name": "uusd", - "tobin_tax": "0.002500000000000000" - }, - { - "name": "ueur", - "tobin_tax": "0.002500000000000000" - } - ], - "slash_fraction": "0.000100000000000000", - "slash_window": "100800", - "min_valid_per_window": "0.050000000000000000" - }, - "feeder_delegations": [], - "exchange_rates": [], - "miss_counters": [], - "aggregate_exchange_rate_prevotes": [], - "aggregate_exchange_rate_votes": [], - "tobin_taxes": [] - }, "params": null, "slashing": { "params": { @@ -664,51 +425,20 @@ "receive_enabled": true } }, - "treasury": { - "params": { - "tax_policy": { - "rate_min": "0.000000000000000000", - "rate_max": "0.000000000000000000", - "cap": { - "denom": "usdr", - "amount": "0" - }, - "change_rate_max": "0.000000000000000000" - }, - "reward_policy": { - "rate_min": "0.000000000000000000", - "rate_max": "1.000000000000000000", - "cap": { - "denom": "unused", - "amount": "0" - }, - "change_rate_max": "0.000000000000000000" - }, - "seigniorage_burden_target": "0.670000000000000000", - "mining_increment": "1.070000000000000000", - "window_short": "4", - "window_long": "52", - "window_probation": "12" - }, - "tax_rate": "0.001000000000000000", - "reward_weight": "0.050000000000000000", - "tax_caps": [], - "tax_proceeds": [], - "epoch_initial_issuance": [], - "epoch_states": [] - }, "upgrade": {}, "vesting": null, "wasm": { "params": { - "max_contract_size": "614400", - "max_contract_gas": "20000000", - "max_contract_msg_size": "4096" + "code_upload_access": { + "permission": "Everybody", + "address": "" + }, + "instantiate_default_permission": "Everybody" }, - "last_code_id": "0", - "last_instance_id": "0", "codes": [], - "contracts": [] + "contracts": [], + "sequences": [], + "gen_msgs": [] } } } diff --git a/cosmwasm/packages/cw721/.cargo/config b/cosmwasm/packages/cw721/.cargo/config deleted file mode 100644 index b613a59f1..000000000 --- a/cosmwasm/packages/cw721/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" diff --git a/cosmwasm/packages/cw721/Cargo.toml b/cosmwasm/packages/cw721/Cargo.toml deleted file mode 100644 index 1b741ca4e..000000000 --- a/cosmwasm/packages/cw721/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "cw721" -version = "0.10.1" -authors = ["Ethan Frey "] -edition = "2018" -description = "Definition and types for the CosmWasm-721 NFT interface" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-nfts" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[dependencies] -cw0 = { version = "0.8.0" } -cosmwasm-std = { version = "0.16.0" } -schemars = "0.8.6" -serde = { version = "1.0.130", default-features = false, features = ["derive"] } - -[dev-dependencies] -cosmwasm-schema = { version = "1.0.0-beta2" } diff --git a/cosmwasm/packages/cw721/NOTICE b/cosmwasm/packages/cw721/NOTICE deleted file mode 100644 index c956affaf..000000000 --- a/cosmwasm/packages/cw721/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW721: A CosmWasm spec for non-fungible token contracts -Copyright (C) 2020-2021 Confio OÜ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/cosmwasm/packages/cw721/README.md b/cosmwasm/packages/cw721/README.md deleted file mode 100644 index 6d065ae81..000000000 --- a/cosmwasm/packages/cw721/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# CW721 Spec: Non Fungible Tokens - -CW721 is a specification for non-fungible tokens based on CosmWasm. -The name and design is based on Ethereum's ERC721 standard, -with some enhancements. The types in here can be imported by -contracts that wish to implement this spec, or by contracts that call -to any standard cw721 contract. - -The specification is split into multiple sections, a contract may only -implement some of this functionality, but must implement the base. - -## Base - -This handles ownership, transfers, and allowances. These must be supported -as is by all CW721 contracts. Note that all tokens must have an owner, -as well as an ID. The ID is an arbitrary string, unique within the contract. - -### Messages - -`TransferNft{recipient, token_id}` - -This transfers ownership of the token to `recipient` account. This is -designed to send to an address controlled by a private key and *does not* -trigger any actions on the recipient if it is a contract. - -Requires `token_id` to point to a valid token, and `env.sender` to be -the owner of it, or have an allowance to transfer it. - -`SendNft{contract, token_id, msg}` - -This transfers ownership of the token to `contract` account. `contract` -must be an address controlled by a smart contract, which implements -the CW721Receiver interface. The `msg` will be passed to the recipient -contract, along with the token_id. - -Requires `token_id` to point to a valid token, and `env.sender` to be -the owner of it, or have an allowance to transfer it. - -`Approve{spender, token_id, expires}` - Grants permission to `spender` to -transfer or send the given token. This can only be performed when -`env.sender` is the owner of the given `token_id` or an `operator`. -There can multiple spender accounts per token, and they are cleared once -the token is transfered or sent. - -`Revoke{spender, token_id}` - This revokes a previously granted permission -to transfer the given `token_id`. This can only be granted when -`env.sender` is the owner of the given `token_id` or an `operator`. - -`ApproveAll{operator, expires}` - Grant `operator` permission to transfer or send -all tokens owned by `env.sender`. This approval is tied to the owner, not the -tokens and applies to any future token that the owner receives as well. - -`RevokeAll{operator}` - Revoke a previous `ApproveAll` permission granted -to the given `operator`. - -### Queries - -`OwnerOf{token_id}` - Returns the owner of the given token, -as well as anyone with approval on this particular token. -If the token is unknown, returns an error. Return type is -`OwnerResponse{owner}`. - -`ApprovedForAll{owner, include_expired}` - List all operators that can -access all of the owner's tokens. Return type is `ApprovedForAllResponse`. -If `include_expired` is set, show expired owners in the results, otherwise, -ignore them. - -`NumTokens{}` - Total number of tokens issued - -### Receiver - -The counter-part to `SendNft` is `ReceiveNft`, which must be implemented by -any contract that wishes to manage CW721 tokens. This is generally *not* -implemented by any CW721 contract. - -`ReceiveNft{sender, token_id, msg}` - This is designed to handle `SendNft` -messages. The address of the contract is stored in `env.sender` -so it cannot be faked. The contract should ensure the sender matches -the token contract it expects to handle, and not allow arbitrary addresses. - -The `sender` is the original account requesting to move the token -and `msg` is a `Binary` data that can be decoded into a contract-specific -message. This can be empty if we have only one default action, -or it may be a `ReceiveMsg` variant to clarify the intention. For example, -if I send to an exchange, I can specify the price I want to list the token -for. - -## Metadata - -### Queries - -`ContractInfo{}` - This returns top-level metadata about the contract. -Namely, `name` and `symbol`. - -`NftInfo{token_id}` - This returns metadata about one particular token. -The return value is based on *ERC721 Metadata JSON Schema*, but directly -from the contract, not as a Uri. Only the image link is a Uri. - -`AllNftInfo{token_id}` - This returns the result of both `NftInfo` -and `OwnerOf` as one query as an optimization for clients, which may -want both info to display one NFT. - -## Enumerable - -### Queries - -Pagination is acheived via `start_after` and `limit`. Limit is a request -set by the client, if unset, the contract will automatically set it to -`DefaultLimit` (suggested 10). If set, it will be used up to a `MaxLimit` -value (suggested 30). Contracts can define other `DefaultLimit` and `MaxLimit` -values without violating the CW721 spec, and clients should not rely on -any particular values. - -If `start_after` is unset, the query returns the first results, ordered by -lexogaphically by `token_id`. If `start_after` is set, then it returns the -first `limit` tokens *after* the given one. This allows straight-forward -pagination by taking the last result returned (a `token_id`) and using it -as the `start_after` value in a future query. - -`Tokens{owner, start_after, limit}` - List all token_ids that belong to a given owner. -Return type is `TokensResponse{tokens: Vec}`. - -`AllTokens{start_after, limit}` - Requires pagination. Lists all token_ids controlled by -the contract. diff --git a/cosmwasm/packages/cw721/examples/schema.rs b/cosmwasm/packages/cw721/examples/schema.rs deleted file mode 100644 index c0c47e835..000000000 --- a/cosmwasm/packages/cw721/examples/schema.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; -use cosmwasm_std::Empty; - -use cw721::{ - AllNftInfoResponse, ApprovalResponse, ApprovalsResponse, ContractInfoResponse, Cw721ExecuteMsg, - Cw721QueryMsg, Cw721ReceiveMsg, NftInfoResponse, NumTokensResponse, OperatorsResponse, - OwnerOfResponse, TokensResponse, -}; - -type Extension = Option; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(Cw721ExecuteMsg), &out_dir); - export_schema(&schema_for!(Cw721QueryMsg), &out_dir); - export_schema(&schema_for!(Cw721ReceiveMsg), &out_dir); - export_schema_with_title( - &schema_for!(AllNftInfoResponse), - &out_dir, - "AllNftInfoResponse", - ); - export_schema(&schema_for!(ApprovalResponse), &out_dir); - export_schema(&schema_for!(ApprovalsResponse), &out_dir); - export_schema(&schema_for!(OperatorsResponse), &out_dir); - export_schema(&schema_for!(ContractInfoResponse), &out_dir); - export_schema(&schema_for!(OwnerOfResponse), &out_dir); - export_schema_with_title( - &schema_for!(NftInfoResponse), - &out_dir, - "NftInfoResponse", - ); - export_schema(&schema_for!(NumTokensResponse), &out_dir); - export_schema(&schema_for!(TokensResponse), &out_dir); -} diff --git a/cosmwasm/packages/cw721/schema/all_nft_info_response.json b/cosmwasm/packages/cw721/schema/all_nft_info_response.json deleted file mode 100644 index bfc334bf7..000000000 --- a/cosmwasm/packages/cw721/schema/all_nft_info_response.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllNftInfoResponse", - "type": "object", - "required": [ - "access", - "info" - ], - "properties": { - "access": { - "description": "Who can transfer the token", - "allOf": [ - { - "$ref": "#/definitions/OwnerOfResponse" - } - ] - }, - "info": { - "description": "Data on the token itself,", - "allOf": [ - { - "$ref": "#/definitions/NftInfoResponse_for_Nullable_Empty" - } - ] - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "NftInfoResponse_for_Nullable_Empty": { - "type": "object", - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "anyOf": [ - { - "$ref": "#/definitions/Empty" - }, - { - "type": "null" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - } - }, - "OwnerOfResponse": { - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/approval_response.json b/cosmwasm/packages/cw721/schema/approval_response.json deleted file mode 100644 index 4f45b42e9..000000000 --- a/cosmwasm/packages/cw721/schema/approval_response.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalResponse", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "$ref": "#/definitions/Approval" - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/approvals_response.json b/cosmwasm/packages/cw721/schema/approvals_response.json deleted file mode 100644 index 8d8e39ea0..000000000 --- a/cosmwasm/packages/cw721/schema/approvals_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalsResponse", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/contract_info_response.json b/cosmwasm/packages/cw721/schema/contract_info_response.json deleted file mode 100644 index a16712589..000000000 --- a/cosmwasm/packages/cw721/schema/contract_info_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractInfoResponse", - "type": "object", - "required": [ - "name", - "symbol" - ], - "properties": { - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/cw721_execute_msg.json b/cosmwasm/packages/cw721/schema/cw721_execute_msg.json deleted file mode 100644 index ccb3fa8c5..000000000 --- a/cosmwasm/packages/cw721/schema/cw721_execute_msg.json +++ /dev/null @@ -1,236 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw721ExecuteMsg", - "oneOf": [ - { - "description": "Transfer is a base message to move a token to another account without triggering actions", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer a token to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send any token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/cw721_query_msg.json b/cosmwasm/packages/cw721/schema/cw721_query_msg.json deleted file mode 100644 index 383e1b437..000000000 --- a/cosmwasm/packages/cw721/schema/cw721_query_msg.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw721QueryMsg", - "oneOf": [ - { - "description": "Return the owner of the given token, error if token does not exist Return type: OwnerOfResponse", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Return operator that can access all of the owner's tokens. Return type: `ApprovedResponse`", - "type": "object", - "required": [ - "approved" - ], - "properties": { - "approved": { - "type": "object", - "required": [ - "operator", - "owner" - ], - "properties": { - "operator": { - "type": "string" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "List all operators that can access all of the owner's tokens. Return type: `ApprovedForAllResponse`", - "type": "object", - "required": [ - "approved_for_all" - ], - "properties": { - "approved_for_all": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Total number of tokens issued", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns top-level metadata about the contract: `ContractInfoResponse`", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns metadata about one particular token, based on *ERC721 Metadata JSON Schema* but directly from the contract: `NftInfoResponse`", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With MetaData Extension. Returns the result of both `NftInfo` and `OwnerOf` as one query as an optimization for clients: `AllNftInfo`", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "description": "unset or false will filter out expired approvals, you must set to true to see them", - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Returns all tokens owned by the given address, [] if unset. Return type: TokensResponse.", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "With Enumerable extension. Requires pagination. Lists all token_ids controlled by the contract. Return type: TokensResponse.", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/cosmwasm/packages/cw721/schema/cw721_receive_msg.json b/cosmwasm/packages/cw721/schema/cw721_receive_msg.json deleted file mode 100644 index 36f0a3a31..000000000 --- a/cosmwasm/packages/cw721/schema/cw721_receive_msg.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw721ReceiveMsg", - "description": "Cw721ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "msg", - "sender", - "token_id" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/nft_info_response.json b/cosmwasm/packages/cw721/schema/nft_info_response.json deleted file mode 100644 index e6bf1d405..000000000 --- a/cosmwasm/packages/cw721/schema/nft_info_response.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NftInfoResponse", - "type": "object", - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "anyOf": [ - { - "$ref": "#/definitions/Empty" - }, - { - "type": "null" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "definitions": { - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/num_tokens_response.json b/cosmwasm/packages/cw721/schema/num_tokens_response.json deleted file mode 100644 index 4647c23aa..000000000 --- a/cosmwasm/packages/cw721/schema/num_tokens_response.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NumTokensResponse", - "type": "object", - "required": [ - "count" - ], - "properties": { - "count": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/cosmwasm/packages/cw721/schema/operators_response.json b/cosmwasm/packages/cw721/schema/operators_response.json deleted file mode 100644 index 53703072c..000000000 --- a/cosmwasm/packages/cw721/schema/operators_response.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/owner_of_response.json b/cosmwasm/packages/cw721/schema/owner_of_response.json deleted file mode 100644 index 1258d671f..000000000 --- a/cosmwasm/packages/cw721/schema/owner_of_response.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OwnerOfResponse", - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/cosmwasm/packages/cw721/schema/tokens_response.json b/cosmwasm/packages/cw721/schema/tokens_response.json deleted file mode 100644 index b8e3d75b5..000000000 --- a/cosmwasm/packages/cw721/schema/tokens_response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_from` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/cosmwasm/packages/cw721/src/lib.rs b/cosmwasm/packages/cw721/src/lib.rs deleted file mode 100644 index b1ac94efc..000000000 --- a/cosmwasm/packages/cw721/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -mod msg; -mod query; -mod receiver; -mod traits; - -pub use cw0::Expiration; - -pub use crate::msg::Cw721ExecuteMsg; -pub use crate::query::{ - AllNftInfoResponse, Approval, ApprovalResponse, ApprovalsResponse, ContractInfoResponse, - Cw721QueryMsg, NftInfoResponse, NumTokensResponse, OperatorsResponse, OwnerOfResponse, - TokensResponse, -}; -pub use crate::receiver::Cw721ReceiveMsg; -pub use crate::traits::{CustomMsg, Cw721, Cw721Execute, Cw721Query}; diff --git a/cosmwasm/packages/cw721/src/msg.rs b/cosmwasm/packages/cw721/src/msg.rs deleted file mode 100644 index 67c0ff6c7..000000000 --- a/cosmwasm/packages/cw721/src/msg.rs +++ /dev/null @@ -1,36 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Binary; -use cw0::Expiration; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum Cw721ExecuteMsg { - /// Transfer is a base message to move a token to another account without triggering actions - TransferNft { recipient: String, token_id: String }, - /// Send is a base message to transfer a token to a contract and trigger an action - /// on the receiving contract. - SendNft { - contract: String, - token_id: String, - msg: Binary, - }, - /// Allows operator to transfer / send the token from the owner's account. - /// If expiration is set, then this allowance has a time/height limit - Approve { - spender: String, - token_id: String, - expires: Option, - }, - /// Remove previously granted Approval - Revoke { spender: String, token_id: String }, - /// Allows operator to transfer / send any token from the owner's account. - /// If expiration is set, then this allowance has a time/height limit - ApproveAll { - operator: String, - expires: Option, - }, - /// Remove previously granted ApproveAll permission - RevokeAll { operator: String }, -} diff --git a/cosmwasm/packages/cw721/src/query.rs b/cosmwasm/packages/cw721/src/query.rs deleted file mode 100644 index aada541a8..000000000 --- a/cosmwasm/packages/cw721/src/query.rs +++ /dev/null @@ -1,132 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cw0::Expiration; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum Cw721QueryMsg { - /// Return the owner of the given token, error if token does not exist - /// Return type: OwnerOfResponse - OwnerOf { - token_id: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - }, - - /// Return operator that can access all of the owner's tokens. - /// Return type: `ApprovedResponse` - Approved { owner: String, operator: String }, - - /// List all operators that can access all of the owner's tokens. - /// Return type: `ApprovedForAllResponse` - ApprovedForAll { - owner: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - start_after: Option, - limit: Option, - }, - /// Total number of tokens issued - NumTokens {}, - - /// With MetaData Extension. - /// Returns top-level metadata about the contract: `ContractInfoResponse` - ContractInfo {}, - /// With MetaData Extension. - /// Returns metadata about one particular token, based on *ERC721 Metadata JSON Schema* - /// but directly from the contract: `NftInfoResponse` - NftInfo { token_id: String }, - /// With MetaData Extension. - /// Returns the result of both `NftInfo` and `OwnerOf` as one query as an optimization - /// for clients: `AllNftInfo` - AllNftInfo { - token_id: String, - /// unset or false will filter out expired approvals, you must set to true to see them - include_expired: Option, - }, - - /// With Enumerable extension. - /// Returns all tokens owned by the given address, [] if unset. - /// Return type: TokensResponse. - Tokens { - owner: String, - start_after: Option, - limit: Option, - }, - /// With Enumerable extension. - /// Requires pagination. Lists all token_ids controlled by the contract. - /// Return type: TokensResponse. - AllTokens { - start_after: Option, - limit: Option, - }, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct OwnerOfResponse { - /// Owner of the token - pub owner: String, - /// If set this address is approved to transfer/send the token as well - pub approvals: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Approval { - /// Account that can transfer/send the token - pub spender: String, - /// When the Approval expires (maybe Expiration::never) - pub expires: Expiration, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct ApprovalResponse { - pub approval: Approval, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct ApprovalsResponse { - pub approvals: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct OperatorsResponse { - pub operators: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct NumTokensResponse { - pub count: u64, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct ContractInfoResponse { - pub name: String, - pub symbol: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct NftInfoResponse { - /// Universal resource identifier for this NFT - /// Should point to a JSON file that conforms to the ERC721 - /// Metadata JSON Schema - pub token_uri: Option, - /// You can add any custom metadata here when you extend cw721-base - pub extension: T, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct AllNftInfoResponse { - /// Who can transfer the token - pub access: OwnerOfResponse, - /// Data on the token itself, - pub info: NftInfoResponse, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct TokensResponse { - /// Contains all token_ids in lexicographical ordering - /// If there are more than `limit`, use `start_from` in future queries - /// to achieve pagination. - pub tokens: Vec, -} diff --git a/cosmwasm/packages/cw721/src/receiver.rs b/cosmwasm/packages/cw721/src/receiver.rs deleted file mode 100644 index e16f66ae1..000000000 --- a/cosmwasm/packages/cw721/src/receiver.rs +++ /dev/null @@ -1,43 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{to_binary, Binary, CosmosMsg, StdResult, WasmMsg}; - -/// Cw721ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct Cw721ReceiveMsg { - pub sender: String, - pub token_id: String, - pub msg: Binary, -} - -impl Cw721ReceiveMsg { - /// serializes the message - pub fn into_binary(self) -> StdResult { - let msg = ReceiverExecuteMsg::ReceiveNft(self); - to_binary(&msg) - } - - /// creates a cosmos_msg sending this struct to the named contract - pub fn into_cosmos_msg, C>(self, contract_addr: T) -> StdResult> - where - C: Clone + std::fmt::Debug + PartialEq + JsonSchema, - { - let msg = self.into_binary()?; - let execute = WasmMsg::Execute { - contract_addr: contract_addr.into(), - msg, - funds: vec![], - }; - Ok(execute.into()) - } -} - -/// This is just a helper to properly serialize the above message. -/// The actual receiver should include this variant in the larger ExecuteMsg enum -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -enum ReceiverExecuteMsg { - ReceiveNft(Cw721ReceiveMsg), -} diff --git a/cosmwasm/packages/cw721/src/traits.rs b/cosmwasm/packages/cw721/src/traits.rs deleted file mode 100644 index eb36aa794..000000000 --- a/cosmwasm/packages/cw721/src/traits.rs +++ /dev/null @@ -1,166 +0,0 @@ -use schemars::JsonSchema; -use serde::de::DeserializeOwned; -use serde::Serialize; - -use crate::query::ApprovalResponse; -use crate::{ - AllNftInfoResponse, ApprovalsResponse, ContractInfoResponse, NftInfoResponse, - NumTokensResponse, OperatorsResponse, OwnerOfResponse, TokensResponse, -}; -use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdResult}; -use cw0::Expiration; - -// TODO: move this somewhere else... ideally cosmwasm-std -pub trait CustomMsg: Clone + std::fmt::Debug + PartialEq + JsonSchema {} - -impl CustomMsg for Empty {} - -pub trait Cw721: Cw721Execute + Cw721Query -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ -} - -pub trait Cw721Execute -where - T: Serialize + DeserializeOwned + Clone, - C: CustomMsg, -{ - type Err: ToString; - - fn transfer_nft( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - recipient: String, - token_id: String, - ) -> Result, Self::Err>; - - fn send_nft( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - contract: String, - token_id: String, - msg: Binary, - ) -> Result, Self::Err>; - - fn approve( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - spender: String, - token_id: String, - expires: Option, - ) -> Result, Self::Err>; - - fn revoke( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - spender: String, - token_id: String, - ) -> Result, Self::Err>; - - fn approve_all( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - operator: String, - expires: Option, - ) -> Result, Self::Err>; - - fn revoke_all( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - operator: String, - ) -> Result, Self::Err>; - - fn burn( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - token_id: String, - ) -> Result, Self::Err>; -} - -pub trait Cw721Query -where - T: Serialize + DeserializeOwned + Clone, -{ - // TODO: use custom error? - // How to handle the two derived error types? - - fn contract_info(&self, deps: Deps) -> StdResult; - - fn num_tokens(&self, deps: Deps) -> StdResult; - - fn nft_info(&self, deps: Deps, token_id: String) -> StdResult>; - - fn owner_of( - &self, - deps: Deps, - env: Env, - token_id: String, - include_expired: bool, - ) -> StdResult; - - fn operators( - &self, - deps: Deps, - env: Env, - owner: String, - include_expired: bool, - start_after: Option, - limit: Option, - ) -> StdResult; - - fn approval( - &self, - deps: Deps, - env: Env, - token_id: String, - spender: String, - include_expired: bool, - ) -> StdResult; - - fn approvals( - &self, - deps: Deps, - env: Env, - token_id: String, - include_expired: bool, - ) -> StdResult; - - fn tokens( - &self, - deps: Deps, - owner: String, - start_after: Option, - limit: Option, - ) -> StdResult; - - fn all_tokens( - &self, - deps: Deps, - start_after: Option, - limit: Option, - ) -> StdResult; - - fn all_nft_info( - &self, - deps: Deps, - env: Env, - token_id: String, - include_expired: bool, - ) -> StdResult>; -} diff --git a/cosmwasm/test/package-lock.json b/cosmwasm/test/package-lock.json index 19c9b01ea..2c891db57 100644 --- a/cosmwasm/test/package-lock.json +++ b/cosmwasm/test/package-lock.json @@ -9,9 +9,11 @@ "version": "0.1.0", "license": "ISC", "dependencies": { + "@certusone/wormhole-sdk": "^0.3.7", "@cosmjs/encoding": "^0.26.2", - "@terra-money/terra.js": "^3.0.9", + "@terra-money/terra.js": "^3.1.3", "elliptic": "^6.5.4", + "ethers": "^5.6.8", "ts-jest": "^27.1.4", "web3-eth-abi": "^1.7.1", "web3-utils": "^1.7.1", @@ -477,6 +479,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", + "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -531,6 +544,31 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "peer": true }, + "node_modules/@certusone/wormhole-sdk": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.3.7.tgz", + "integrity": "sha512-C+PqzRITASWJJ9XnGOUnUssGL6yV4B5ivkfHsBLR4WChmSSY8ENnYr92WMj/mH+sw55sQsEAycCjqZEsrIlaAQ==", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.0", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.24.0", + "@terra-money/terra.js": "^3.0.7", + "algosdk": "^1.15.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "js-base64": "^3.6.1", + "protobufjs": "^6.11.2", + "rxjs": "^7.3.0" + } + }, + "node_modules/@certusone/wormhole-sdk/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, "node_modules/@cosmjs/encoding": { "version": "0.26.6", "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.26.6.tgz", @@ -546,10 +584,10 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "node_modules/@ethersproject/abi": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.3.tgz", + "integrity": "sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw==", "funding": [ { "type": "individual", @@ -561,19 +599,45 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz", + "integrity": "sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.3", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/web": "^5.6.1" } }, "node_modules/@ethersproject/abstract-signer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", - "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz", + "integrity": "sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==", "funding": [ { "type": "individual", @@ -585,17 +649,17 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0" } }, "node_modules/@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", "funding": [ { "type": "individual", @@ -607,17 +671,17 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" + "@ethersproject/rlp": "^5.6.1" } }, "node_modules/@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.1.tgz", + "integrity": "sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==", "funding": [ { "type": "individual", @@ -629,13 +693,32 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0" + "@ethersproject/bytes": "^5.6.1" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.1.tgz", + "integrity": "sha512-a52MkVz4vuBXR06nvflPMotld1FJWSj2QT0985v7P/emPZO00PucFAkbcmq2vpVU7Ts7umKiSI6SppiLykVWsA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/properties": "^5.6.0" } }, "node_modules/@ethersproject/bignumber": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", - "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.2.tgz", + "integrity": "sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==", "funding": [ { "type": "individual", @@ -647,11 +730,16 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" + "bn.js": "^5.2.1" } }, + "node_modules/@ethersproject/bignumber/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, "node_modules/@ethersproject/bytes": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", @@ -671,9 +759,9 @@ } }, "node_modules/@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.1.tgz", + "integrity": "sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==", "funding": [ { "type": "individual", @@ -685,13 +773,40 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.6.0" + "@ethersproject/bignumber": "^5.6.2" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.2.tgz", + "integrity": "sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.2" } }, "node_modules/@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", + "integrity": "sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==", "funding": [ { "type": "individual", @@ -703,20 +818,79 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.2.tgz", + "integrity": "sha512-tERxW8Ccf9CxW2db3WsN01Qao3wFeRsfYY9TCuhmG0xNpl2IO8wgXU3HtWIZ49gUWPggRy4Yg5axU0ACaEKf1Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/basex": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.1", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/sha2": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2", + "@ethersproject/strings": "^5.6.1", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/wordlists": "^5.6.1" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.1.tgz", + "integrity": "sha512-KfyJ6Zwz3kGeX25nLihPwZYlDqamO6pfGKNnVMWWfEVVp42lTfCZVXXy5Ie8IZTN0HKwAngpIPi7gk4IJzgmqQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/hdnode": "^5.6.2", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.1", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.1", + "@ethersproject/strings": "^5.6.1", + "@ethersproject/transactions": "^5.6.2", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" } }, "node_modules/@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.1.tgz", + "integrity": "sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==", "funding": [ { "type": "individual", @@ -728,7 +902,7 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", "js-sha3": "0.8.0" } }, @@ -748,9 +922,9 @@ ] }, "node_modules/@ethersproject/networks": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", - "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.3.tgz", + "integrity": "sha512-QZxRH7cA5Ut9TbXwZFiCyuPchdWi87ZtVNHWZd0R6YFgYtes2jQ3+bsslJ0WdyDe0i6QumqtoYqvY3rrQFRZOQ==", "funding": [ { "type": "individual", @@ -765,6 +939,25 @@ "@ethersproject/logger": "^5.6.0" } }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.1.tgz", + "integrity": "sha512-k4gRQ+D93zDRPNUfmduNKq065uadC2YjMP/CqwwX5qG6R05f47boq6pLZtV/RnC4NZAYOPH1Cyo54q0c9sshRQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/sha2": "^5.6.1" + } + }, "node_modules/@ethersproject/properties": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", @@ -783,10 +976,10 @@ "@ethersproject/logger": "^5.6.0" } }, - "node_modules/@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "node_modules/@ethersproject/providers": { + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.8.tgz", + "integrity": "sha512-Wf+CseT/iOJjrGtAOf3ck9zS7AgPmr2fZ3N97r4+YXN3mBePTG2/bJ8DApl9mVwYL+RpYbNxMEkEp4mPGdwG/w==", "funding": [ { "type": "individual", @@ -798,14 +991,76 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/base64": "^5.6.1", + "@ethersproject/basex": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.3", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.1", + "@ethersproject/rlp": "^5.6.1", + "@ethersproject/sha2": "^5.6.1", + "@ethersproject/strings": "^5.6.1", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/web": "^5.6.1", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.1.tgz", + "integrity": "sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0" } }, - "node_modules/@ethersproject/signing-key": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", - "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "node_modules/@ethersproject/rlp": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.1.tgz", + "integrity": "sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==", "funding": [ { "type": "individual", @@ -817,18 +1072,62 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.1.tgz", + "integrity": "sha512-5K2GyqcW7G4Yo3uenHegbXRPDgARpWUiXc6RiF7b6i/HXUoWlb7uCARh7BAHg7/qT/Q5ydofNwiZcim9qpjB6g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.2.tgz", + "integrity": "sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", + "bn.js": "^5.2.1", "elliptic": "6.5.4", "hash.js": "1.1.7" } }, - "node_modules/@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "node_modules/@ethersproject/signing-key/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/@ethersproject/solidity": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.1.tgz", + "integrity": "sha512-KWqVLkUUoLBfL1iwdzUVlkNqAUIFMpbbeH0rgCfKmJp0vFtY4AsaN91gHKo9ZZLkC4UOm3cI3BmMV4N53BOq4g==", "funding": [ { "type": "individual", @@ -840,15 +1139,38 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/sha2": "^5.6.1", + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.1.tgz", + "integrity": "sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", "@ethersproject/logger": "^5.6.0" } }, "node_modules/@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.2.tgz", + "integrity": "sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==", "funding": [ { "type": "individual", @@ -860,21 +1182,73 @@ } ], "dependencies": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" + "@ethersproject/rlp": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.1.tgz", + "integrity": "sha512-rEfSEvMQ7obcx3KWD5EWWx77gqv54K6BKiZzKxkQJqtpriVsICrktIQmKl8ReNToPeIYPnFHpXvKpi068YFZXw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.2.tgz", + "integrity": "sha512-lrgh0FDQPuOnHcF80Q3gHYsSUODp6aJLAdDmDV0xKCN/T7D99ta1jGVhulg3PY8wiXEngD0DfM0I2XKXlrqJfg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/hdnode": "^5.6.2", + "@ethersproject/json-wallets": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/wordlists": "^5.6.1" } }, "node_modules/@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.1.tgz", + "integrity": "sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==", "funding": [ { "type": "individual", @@ -886,11 +1260,44 @@ } ], "dependencies": { - "@ethersproject/base64": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/base64": "^5.6.1", + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.1.tgz", + "integrity": "sha512-wiPRgBpNbNwCQFoCr8bcWO8o5I810cqO6mkdtKfLKFlLxeCWcnzDi4Alu8iyNzlhYuS9npCwivMbRWF19dyblw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "node_modules/@improbable-eng/grpc-web": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", + "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" } }, "node_modules/@istanbuljs/load-nyc-config": { @@ -1529,7 +1936,7 @@ "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", @@ -1544,12 +1951,12 @@ "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -1558,27 +1965,27 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@sinonjs/commons": { "version": "1.8.3", @@ -1598,13 +2005,111 @@ "@sinonjs/commons": "^1.7.0" } }, - "node_modules/@terra-money/terra.js": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.0.9.tgz", - "integrity": "sha512-jC7E8SjYiUV7nTk8g3LwQhJXlW5t2aiulB6Qg+K9dWpNzfqMn1ovuOD250gyx9aFaCilbDVLzPiZJLLbKPCO0w==", + "node_modules/@solana/buffer-layout": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", "dependencies": { - "@terra-money/terra.proto": "^0.1.7", - "axios": "^0.24.0", + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "dependencies": { + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/spl-token/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/@solana/web3.js": { + "version": "1.43.6", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.6.tgz", + "integrity": "sha512-F1Q7EOnLi5X+Ap5bAEi5PTwwXPZR+GTfIyOuWpWJfgm3GoawdP/x5lxJolDzzV5S99bNEU/rSTdxcW9EFzIiEw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@solana/web3.js/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/@solana/web3.js/node_modules/buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@terra-money/legacy.proto": { + "name": "@terra-money/terra.proto", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", + "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "dependencies": { + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@terra-money/terra.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.3.tgz", + "integrity": "sha512-80HU5WXrqf3hZTo2GRhIycH17A+SkLD6afbu8MynMDGGD/A861F3zVv6NQ/Z7PWQGHxgddZEK/A0UQ2uK/xfHg==", + "dependencies": { + "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@terra-money/terra.proto": "~2.0.0", + "axios": "^0.26.1", "bech32": "^2.0.0", "bip32": "^2.0.6", "bip39": "^3.0.3", @@ -1622,10 +2127,11 @@ } }, "node_modules/@terra-money/terra.proto": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", - "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.0.0.tgz", + "integrity": "sha512-ZjyFOFUzrGn8IwzGIgr1OJFcPSsQoz/XAfoSKThJx+OjJA7CLhdcz51+5h7ehNfb+qB9wr7aNME0h24wu9D4SQ==", "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", "google-protobuf": "^3.17.3", "long": "^4.0.0", "protobufjs": "~6.11.2" @@ -1689,6 +2195,24 @@ "@types/node": "*" } }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -1719,10 +2243,15 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" + }, "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "node_modules/@types/node": { "version": "17.0.23", @@ -1743,6 +2272,16 @@ "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", "peer": true }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, "node_modules/@types/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", @@ -1757,6 +2296,14 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "peer": true }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -1819,6 +2366,11 @@ "node": ">=0.4.0" } }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1831,6 +2383,31 @@ "node": ">= 6.0.0" } }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/algosdk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.17.0.tgz", + "integrity": "sha512-WwHbZV03tZ2C/VLOapWOzJImm4lokav9HXnPLqbGrXyb8Gn/Q2AsoKMbOxd6MTzWguhaXU4Yk0VtbFlYhkaeoA==", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.2", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "superagent": "^6.1.0", + "tweetnacl": "^1.0.3", + "url-parse": "^1.5.1" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1889,15 +2466,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "peer": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "dependencies": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.14.8" } }, "node_modules/babel-jest": { @@ -2099,6 +2675,26 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -2155,6 +2751,21 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, + "node_modules/borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/borsh/node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2181,6 +2792,11 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, + "node_modules/browser-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", + "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==" + }, "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -2267,12 +2883,43 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "peer": true }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", + "engines": { + "node": ">=4.5" + } + }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -2299,6 +2946,18 @@ "node": ">=0.10.0" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2418,7 +3077,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2429,8 +3087,12 @@ "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -2452,6 +3114,11 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "peer": true }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -2533,7 +3200,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "peer": true, "dependencies": { "ms": "2.1.2" }, @@ -2572,11 +3238,21 @@ "node": ">=0.10.0" } }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "peer": true, "engines": { "node": ">=0.4.0" } @@ -2629,6 +3305,14 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.103", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", @@ -2675,6 +3359,19 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2793,6 +3490,53 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, + "node_modules/ethers": { + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.8.tgz", + "integrity": "sha512-YxIGaltAOdvBFPZwIkyHnXbW40f1r8mHUgapW6dxkO+6t7H6wY8POUn0Kbxrd/N7I4hHxyi7YCddMAH/wmho2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.6.3", + "@ethersproject/abstract-provider": "5.6.1", + "@ethersproject/abstract-signer": "5.6.2", + "@ethersproject/address": "5.6.1", + "@ethersproject/base64": "5.6.1", + "@ethersproject/basex": "5.6.1", + "@ethersproject/bignumber": "5.6.2", + "@ethersproject/bytes": "5.6.1", + "@ethersproject/constants": "5.6.1", + "@ethersproject/contracts": "5.6.2", + "@ethersproject/hash": "5.6.1", + "@ethersproject/hdnode": "5.6.2", + "@ethersproject/json-wallets": "5.6.1", + "@ethersproject/keccak256": "5.6.1", + "@ethersproject/logger": "5.6.0", + "@ethersproject/networks": "5.6.3", + "@ethersproject/pbkdf2": "5.6.1", + "@ethersproject/properties": "5.6.0", + "@ethersproject/providers": "5.6.8", + "@ethersproject/random": "5.6.1", + "@ethersproject/rlp": "5.6.1", + "@ethersproject/sha2": "5.6.1", + "@ethersproject/signing-key": "5.6.2", + "@ethersproject/solidity": "5.6.1", + "@ethersproject/strings": "5.6.1", + "@ethersproject/transactions": "5.6.2", + "@ethersproject/units": "5.6.1", + "@ethersproject/wallet": "5.6.2", + "@ethersproject/web": "5.6.1", + "@ethersproject/wordlists": "5.6.1" + } + }, "node_modules/ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", @@ -2811,6 +3555,11 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -2867,6 +3616,14 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2878,6 +3635,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "peer": true }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -2918,9 +3685,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", "funding": [ { "type": "individual", @@ -2940,7 +3707,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2950,6 +3716,15 @@ "node": ">= 6" } }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2991,6 +3766,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3041,9 +3829,9 @@ } }, "node_modules/google-protobuf": { - "version": "3.19.4", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.4.tgz", - "integrity": "sha512-OIPNCxsG2lkIvf+P5FNfJ/Km95CsXOBecS9ZcAU6m2Rq3svc0Apl9nB3GMDNKfQ9asNv4KjyAqGwPQFrVle3Yg==" + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz", + "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw==" }, "node_modules/graceful-fs": { "version": "4.2.9", @@ -3069,6 +3857,17 @@ "node": ">=4" } }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -3091,6 +3890,11 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3167,6 +3971,25 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -3291,6 +4114,14 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "peer": true }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -3387,6 +4218,39 @@ "node": ">=8" } }, + "node_modules/jayson": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -5094,11 +5958,26 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, + "node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5182,12 +6061,25 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "peer": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -5199,6 +6091,29 @@ "node": ">=6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/keccak": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", @@ -5265,8 +6180,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "peer": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -5343,6 +6257,14 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "peer": true }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -5356,11 +6278,21 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "peer": true, "engines": { "node": ">= 0.6" } @@ -5369,7 +6301,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -5428,8 +6359,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "peer": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nan": { "version": "2.15.0", @@ -5447,6 +6377,44 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-gyp-build": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", @@ -5514,6 +6482,14 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "peer": true }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5762,9 +6738,9 @@ } }, "node_modules/protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -5801,6 +6777,25 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.10.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz", + "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -5833,6 +6828,11 @@ "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5841,6 +6841,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -5926,6 +6931,58 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" }, + "node_modules/rpc-websockets": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.0.tgz", + "integrity": "sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6029,6 +7086,19 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -6182,6 +7252,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 7.0.0" + } + }, + "node_modules/superagent/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6274,12 +7385,22 @@ "node": ">=8" } }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, "node_modules/throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "peer": true }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, "node_modules/tiny-secp256k1": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", @@ -6473,6 +7594,11 @@ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -6541,6 +7667,15 @@ "node": ">= 4.0.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/utf-8-validate": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.6.tgz", @@ -6563,6 +7698,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -7201,6 +8344,14 @@ "@babel/helper-plugin-utils": "^7.16.7" } }, + "@babel/runtime": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", + "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -7246,6 +8397,33 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "peer": true }, + "@certusone/wormhole-sdk": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.3.7.tgz", + "integrity": "sha512-C+PqzRITASWJJ9XnGOUnUssGL6yV4B5ivkfHsBLR4WChmSSY8ENnYr92WMj/mH+sw55sQsEAycCjqZEsrIlaAQ==", + "requires": { + "@improbable-eng/grpc-web": "^0.14.0", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.24.0", + "@terra-money/terra.js": "^3.0.7", + "algosdk": "^1.15.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "js-base64": "^3.6.1", + "protobufjs": "^6.11.2", + "rxjs": "^7.3.0" + }, + "dependencies": { + "axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "requires": { + "follow-redirects": "^1.14.4" + } + } + } + }, "@cosmjs/encoding": { "version": "0.26.6", "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.26.6.tgz", @@ -7263,60 +8441,92 @@ } } }, - "@ethersproject/abstract-provider": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", - "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "@ethersproject/abi": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.6.3.tgz", + "integrity": "sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw==", "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "@ethersproject/networks": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/transactions": "^5.6.0", - "@ethersproject/web": "^5.6.0" + "@ethersproject/strings": "^5.6.1" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz", + "integrity": "sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==", + "requires": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.3", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/web": "^5.6.1" } }, "@ethersproject/abstract-signer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", - "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz", + "integrity": "sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==", "requires": { - "@ethersproject/abstract-provider": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0" } }, "@ethersproject/address": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", - "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", "requires": { - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "@ethersproject/rlp": "^5.6.0" + "@ethersproject/rlp": "^5.6.1" } }, "@ethersproject/base64": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", - "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.1.tgz", + "integrity": "sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==", "requires": { - "@ethersproject/bytes": "^5.6.0" + "@ethersproject/bytes": "^5.6.1" + } + }, + "@ethersproject/basex": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.6.1.tgz", + "integrity": "sha512-a52MkVz4vuBXR06nvflPMotld1FJWSj2QT0985v7P/emPZO00PucFAkbcmq2vpVU7Ts7umKiSI6SppiLykVWsA==", + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/properties": "^5.6.0" } }, "@ethersproject/bignumber": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", - "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.2.tgz", + "integrity": "sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==", "requires": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "bn.js": "^4.11.9" + "bn.js": "^5.2.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + } } }, "@ethersproject/bytes": { @@ -7328,34 +8538,90 @@ } }, "@ethersproject/constants": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", - "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.1.tgz", + "integrity": "sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==", "requires": { - "@ethersproject/bignumber": "^5.6.0" + "@ethersproject/bignumber": "^5.6.2" + } + }, + "@ethersproject/contracts": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.6.2.tgz", + "integrity": "sha512-hguUA57BIKi6WY0kHvZp6PwPlWF87MCeB4B7Z7AbUpTxfFXFdn/3b0GmjZPagIHS+3yhcBJDnuEfU4Xz+Ks/8g==", + "requires": { + "@ethersproject/abi": "^5.6.3", + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.2" } }, "@ethersproject/hash": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", - "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.1.tgz", + "integrity": "sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==", "requires": { - "@ethersproject/abstract-signer": "^5.6.0", - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@ethersproject/strings": "^5.6.1" + } + }, + "@ethersproject/hdnode": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.6.2.tgz", + "integrity": "sha512-tERxW8Ccf9CxW2db3WsN01Qao3wFeRsfYY9TCuhmG0xNpl2IO8wgXU3HtWIZ49gUWPggRy4Yg5axU0ACaEKf1Q==", + "requires": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/basex": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.1", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/sha2": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2", + "@ethersproject/strings": "^5.6.1", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/wordlists": "^5.6.1" + } + }, + "@ethersproject/json-wallets": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.6.1.tgz", + "integrity": "sha512-KfyJ6Zwz3kGeX25nLihPwZYlDqamO6pfGKNnVMWWfEVVp42lTfCZVXXy5Ie8IZTN0HKwAngpIPi7gk4IJzgmqQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/hdnode": "^5.6.2", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/pbkdf2": "^5.6.1", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.1", + "@ethersproject/strings": "^5.6.1", + "@ethersproject/transactions": "^5.6.2", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" } }, "@ethersproject/keccak256": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", - "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.1.tgz", + "integrity": "sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==", "requires": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", "js-sha3": "0.8.0" } }, @@ -7365,13 +8631,22 @@ "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" }, "@ethersproject/networks": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", - "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.3.tgz", + "integrity": "sha512-QZxRH7cA5Ut9TbXwZFiCyuPchdWi87ZtVNHWZd0R6YFgYtes2jQ3+bsslJ0WdyDe0i6QumqtoYqvY3rrQFRZOQ==", "requires": { "@ethersproject/logger": "^5.6.0" } }, + "@ethersproject/pbkdf2": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.6.1.tgz", + "integrity": "sha512-k4gRQ+D93zDRPNUfmduNKq065uadC2YjMP/CqwwX5qG6R05f47boq6pLZtV/RnC4NZAYOPH1Cyo54q0c9sshRQ==", + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/sha2": "^5.6.1" + } + }, "@ethersproject/properties": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", @@ -7380,64 +8655,195 @@ "@ethersproject/logger": "^5.6.0" } }, - "@ethersproject/rlp": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", - "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "@ethersproject/providers": { + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.8.tgz", + "integrity": "sha512-Wf+CseT/iOJjrGtAOf3ck9zS7AgPmr2fZ3N97r4+YXN3mBePTG2/bJ8DApl9mVwYL+RpYbNxMEkEp4mPGdwG/w==", "requires": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/base64": "^5.6.1", + "@ethersproject/basex": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.3", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.1", + "@ethersproject/rlp": "^5.6.1", + "@ethersproject/sha2": "^5.6.1", + "@ethersproject/strings": "^5.6.1", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/web": "^5.6.1", + "bech32": "1.1.4", + "ws": "7.4.6" + }, + "dependencies": { + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} + } + } + }, + "@ethersproject/random": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.6.1.tgz", + "integrity": "sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA==", + "requires": { + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0" } }, - "@ethersproject/signing-key": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", - "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "@ethersproject/rlp": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.1.tgz", + "integrity": "sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==", "requires": { - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/sha2": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.1.tgz", + "integrity": "sha512-5K2GyqcW7G4Yo3uenHegbXRPDgARpWUiXc6RiF7b6i/HXUoWlb7uCARh7BAHg7/qT/Q5ydofNwiZcim9qpjB6g==", + "requires": { + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", - "@ethersproject/properties": "^5.6.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", "hash.js": "1.1.7" } }, - "@ethersproject/strings": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", - "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "@ethersproject/signing-key": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.2.tgz", + "integrity": "sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==", "requires": { - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + } + } + }, + "@ethersproject/solidity": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.6.1.tgz", + "integrity": "sha512-KWqVLkUUoLBfL1iwdzUVlkNqAUIFMpbbeH0rgCfKmJp0vFtY4AsaN91gHKo9ZZLkC4UOm3cI3BmMV4N53BOq4g==", + "requires": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/sha2": "^5.6.1", + "@ethersproject/strings": "^5.6.1" + } + }, + "@ethersproject/strings": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.1.tgz", + "integrity": "sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==", + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", "@ethersproject/logger": "^5.6.0" } }, "@ethersproject/transactions": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", - "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.2.tgz", + "integrity": "sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==", "requires": { - "@ethersproject/address": "^5.6.0", - "@ethersproject/bignumber": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", - "@ethersproject/constants": "^5.6.0", - "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/rlp": "^5.6.0", - "@ethersproject/signing-key": "^5.6.0" + "@ethersproject/rlp": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2" + } + }, + "@ethersproject/units": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.6.1.tgz", + "integrity": "sha512-rEfSEvMQ7obcx3KWD5EWWx77gqv54K6BKiZzKxkQJqtpriVsICrktIQmKl8ReNToPeIYPnFHpXvKpi068YFZXw==", + "requires": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/constants": "^5.6.1", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/wallet": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.6.2.tgz", + "integrity": "sha512-lrgh0FDQPuOnHcF80Q3gHYsSUODp6aJLAdDmDV0xKCN/T7D99ta1jGVhulg3PY8wiXEngD0DfM0I2XKXlrqJfg==", + "requires": { + "@ethersproject/abstract-provider": "^5.6.1", + "@ethersproject/abstract-signer": "^5.6.2", + "@ethersproject/address": "^5.6.1", + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/hdnode": "^5.6.2", + "@ethersproject/json-wallets": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/random": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2", + "@ethersproject/transactions": "^5.6.2", + "@ethersproject/wordlists": "^5.6.1" } }, "@ethersproject/web": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", - "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.1.tgz", + "integrity": "sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==", "requires": { - "@ethersproject/base64": "^5.6.0", - "@ethersproject/bytes": "^5.6.0", + "@ethersproject/base64": "^5.6.1", + "@ethersproject/bytes": "^5.6.1", "@ethersproject/logger": "^5.6.0", "@ethersproject/properties": "^5.6.0", - "@ethersproject/strings": "^5.6.0" + "@ethersproject/strings": "^5.6.1" + } + }, + "@ethersproject/wordlists": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.6.1.tgz", + "integrity": "sha512-wiPRgBpNbNwCQFoCr8bcWO8o5I810cqO6mkdtKfLKFlLxeCWcnzDi4Alu8iyNzlhYuS9npCwivMbRWF19dyblw==", + "requires": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/hash": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.1" + } + }, + "@improbable-eng/grpc-web": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", + "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", + "requires": { + "browser-headers": "^0.4.1" } }, "@istanbuljs/load-nyc-config": { @@ -7923,7 +9329,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "@protobufjs/base64": { "version": "1.1.2", @@ -7938,12 +9344,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -7952,27 +9358,27 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "@sinonjs/commons": { "version": "1.8.3", @@ -7992,13 +9398,91 @@ "@sinonjs/commons": "^1.7.0" } }, - "@terra-money/terra.js": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.0.9.tgz", - "integrity": "sha512-jC7E8SjYiUV7nTk8g3LwQhJXlW5t2aiulB6Qg+K9dWpNzfqMn1ovuOD250gyx9aFaCilbDVLzPiZJLLbKPCO0w==", + "@solana/buffer-layout": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", "requires": { - "@terra-money/terra.proto": "^0.1.7", - "axios": "^0.24.0", + "buffer": "~6.0.3" + } + }, + "@solana/spl-token": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "requires": { + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + } + } + }, + "@solana/web3.js": { + "version": "1.43.6", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.6.tgz", + "integrity": "sha512-F1Q7EOnLi5X+Ap5bAEi5PTwwXPZR+GTfIyOuWpWJfgm3GoawdP/x5lxJolDzzV5S99bNEU/rSTdxcW9EFzIiEw==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } + } + }, + "@terra-money/legacy.proto": { + "version": "npm:@terra-money/terra.proto@0.1.7", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", + "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "requires": { + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "@terra-money/terra.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.3.tgz", + "integrity": "sha512-80HU5WXrqf3hZTo2GRhIycH17A+SkLD6afbu8MynMDGGD/A861F3zVv6NQ/Z7PWQGHxgddZEK/A0UQ2uK/xfHg==", + "requires": { + "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@terra-money/terra.proto": "~2.0.0", + "axios": "^0.26.1", "bech32": "^2.0.0", "bip32": "^2.0.6", "bip39": "^3.0.3", @@ -8013,10 +9497,11 @@ } }, "@terra-money/terra.proto": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", - "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.0.0.tgz", + "integrity": "sha512-ZjyFOFUzrGn8IwzGIgr1OJFcPSsQoz/XAfoSKThJx+OjJA7CLhdcz51+5h7ehNfb+qB9wr7aNME0h24wu9D4SQ==", "requires": { + "@improbable-eng/grpc-web": "^0.14.1", "google-protobuf": "^3.17.3", "long": "^4.0.0", "protobufjs": "~6.11.2" @@ -8077,6 +9562,24 @@ "@types/node": "*" } }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -8107,10 +9610,15 @@ "@types/istanbul-lib-report": "*" } }, + "@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" + }, "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "@types/node": { "version": "17.0.23", @@ -8131,6 +9639,16 @@ "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", "peer": true }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, "@types/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", @@ -8145,6 +9663,14 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "peer": true }, + "@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -8194,6 +9720,11 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "peer": true }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -8203,6 +9734,28 @@ "debug": "4" } }, + "algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==" + }, + "algosdk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.17.0.tgz", + "integrity": "sha512-WwHbZV03tZ2C/VLOapWOzJImm4lokav9HXnPLqbGrXyb8Gn/Q2AsoKMbOxd6MTzWguhaXU4Yk0VtbFlYhkaeoA==", + "requires": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.2", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "superagent": "^6.1.0", + "tweetnacl": "^1.0.3", + "url-parse": "^1.5.1" + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -8246,15 +9799,14 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "peer": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "requires": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.14.8" } }, "babel-jest": { @@ -8402,6 +9954,19 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "requires": { + "bindings": "^1.3.0" + } + }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -8459,6 +10024,23 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, + "borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "requires": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -8482,6 +10064,11 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, + "browser-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", + "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==" + }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -8549,12 +10136,26 @@ "node-int64": "^0.4.0" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "peer": true }, + "buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -8574,6 +10175,15 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -8667,7 +10277,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "peer": true, "requires": { "delayed-stream": "~1.0.0" } @@ -8675,8 +10284,12 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "concat-map": { "version": "0.0.1", @@ -8700,6 +10313,11 @@ } } }, + "cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -8774,7 +10392,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "peer": true, "requires": { "ms": "2.1.2" } @@ -8802,11 +10419,15 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "peer": true }, + "delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "peer": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "detect-newline": { "version": "3.1.0", @@ -8843,6 +10464,11 @@ } } }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, "electron-to-chromium": { "version": "1.4.103", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", @@ -8883,6 +10509,19 @@ "is-arrayish": "^0.2.1" } }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "requires": { + "es6-promise": "^4.0.3" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8972,6 +10611,43 @@ } } }, + "ethers": { + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.8.tgz", + "integrity": "sha512-YxIGaltAOdvBFPZwIkyHnXbW40f1r8mHUgapW6dxkO+6t7H6wY8POUn0Kbxrd/N7I4hHxyi7YCddMAH/wmho2w==", + "requires": { + "@ethersproject/abi": "5.6.3", + "@ethersproject/abstract-provider": "5.6.1", + "@ethersproject/abstract-signer": "5.6.2", + "@ethersproject/address": "5.6.1", + "@ethersproject/base64": "5.6.1", + "@ethersproject/basex": "5.6.1", + "@ethersproject/bignumber": "5.6.2", + "@ethersproject/bytes": "5.6.1", + "@ethersproject/constants": "5.6.1", + "@ethersproject/contracts": "5.6.2", + "@ethersproject/hash": "5.6.1", + "@ethersproject/hdnode": "5.6.2", + "@ethersproject/json-wallets": "5.6.1", + "@ethersproject/keccak256": "5.6.1", + "@ethersproject/logger": "5.6.0", + "@ethersproject/networks": "5.6.3", + "@ethersproject/pbkdf2": "5.6.1", + "@ethersproject/properties": "5.6.0", + "@ethersproject/providers": "5.6.8", + "@ethersproject/random": "5.6.1", + "@ethersproject/rlp": "5.6.1", + "@ethersproject/sha2": "5.6.1", + "@ethersproject/signing-key": "5.6.2", + "@ethersproject/solidity": "5.6.1", + "@ethersproject/strings": "5.6.1", + "@ethersproject/transactions": "5.6.2", + "@ethersproject/units": "5.6.1", + "@ethersproject/wallet": "5.6.2", + "@ethersproject/web": "5.6.1", + "@ethersproject/wordlists": "5.6.1" + } + }, "ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", @@ -8988,6 +10664,11 @@ } } }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -9032,6 +10713,11 @@ "jest-message-util": "^27.5.1" } }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==" + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -9043,6 +10729,16 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "peer": true }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -9077,21 +10773,25 @@ } }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "peer": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, + "formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -9120,6 +10820,16 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -9152,9 +10862,9 @@ "peer": true }, "google-protobuf": { - "version": "3.19.4", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.4.tgz", - "integrity": "sha512-OIPNCxsG2lkIvf+P5FNfJ/Km95CsXOBecS9ZcAU6m2Rq3svc0Apl9nB3GMDNKfQ9asNv4KjyAqGwPQFrVle3Yg==" + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz", + "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw==" }, "graceful-fs": { "version": "4.2.9", @@ -9174,6 +10884,11 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -9193,6 +10908,11 @@ "minimalistic-assert": "^1.0.1" } }, + "hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -9254,6 +10974,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -9344,6 +11069,12 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "peer": true }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "requires": {} + }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -9420,6 +11151,35 @@ "istanbul-lib-report": "^3.0.0" } }, + "jayson": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "requires": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "dependencies": { + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + } + } + }, "jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -10691,11 +12451,26 @@ } } }, + "js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, + "js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10756,17 +12531,44 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "peer": true }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + } + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "peer": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "keccak": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", @@ -10817,8 +12619,7 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "peer": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.memoize": { "version": "4.1.2", @@ -10885,6 +12686,11 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "peer": true }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -10895,17 +12701,20 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "peer": true + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "peer": true, "requires": { "mime-db": "1.52.0" } @@ -10952,8 +12761,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "peer": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nan": { "version": "2.15.0", @@ -10971,6 +12779,35 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "node-gyp-build": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", @@ -11025,6 +12862,11 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "peer": true }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -11200,9 +13042,9 @@ } }, "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -11231,6 +13073,19 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "peer": true }, + "qs": { + "version": "6.10.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz", + "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11260,11 +13115,21 @@ "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -11328,6 +13193,42 @@ } } }, + "rpc-websockets": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.0.tgz", + "integrity": "sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ==", + "requires": { + "@babel/runtime": "^7.17.2", + "bufferutil": "^4.0.1", + "eventemitter3": "^4.0.7", + "utf-8-validate": "^5.0.2", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "dependencies": { + "ws": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", + "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "requires": {} + } + } + }, + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -11398,6 +13299,16 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "peer": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -11516,6 +13427,39 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "peer": true }, + "superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -11583,12 +13527,22 @@ "minimatch": "^3.0.4" } }, + "text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, "throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "peer": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, "tiny-secp256k1": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", @@ -11716,6 +13670,11 @@ "tslib": "^1.8.1" } }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -11762,6 +13721,15 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "peer": true }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "utf-8-validate": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.6.tgz", @@ -11780,6 +13748,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, "v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", diff --git a/cosmwasm/test/package.json b/cosmwasm/test/package.json index 8141336bf..b1956faf2 100644 --- a/cosmwasm/test/package.json +++ b/cosmwasm/test/package.json @@ -9,9 +9,11 @@ "author": "", "license": "ISC", "dependencies": { + "@certusone/wormhole-sdk": "^0.3.7", "@cosmjs/encoding": "^0.26.2", - "@terra-money/terra.js": "^3.0.9", + "@terra-money/terra.js": "^3.1.3", "elliptic": "^6.5.4", + "ethers": "^5.6.8", "ts-jest": "^27.1.4", "web3-eth-abi": "^1.7.1", "web3-utils": "^1.7.1", diff --git a/cosmwasm/test/src/__tests__/bridge.ts b/cosmwasm/test/src/__tests__/bridge.ts index a0f663908..03770a80c 100644 --- a/cosmwasm/test/src/__tests__/bridge.ts +++ b/cosmwasm/test/src/__tests__/bridge.ts @@ -1,19 +1,26 @@ -import { describe, expect, jest, test } from "@jest/globals"; +import { + parseSequenceFromLogTerra, + setDefaultWasm, +} from "@certusone/wormhole-sdk"; import { Bech32, toHex } from "@cosmjs/encoding"; +import { describe, expect, jest, test } from "@jest/globals"; +import { Int, MsgExecuteContract } from "@terra-money/terra.js"; +import { keccak256 } from "ethers/lib/utils"; import { getNativeBalance, makeProviderAndWallet, transactWithoutMemo, } from "../helpers/client"; -import { storeCode, deploy } from "../instantiate"; -import { Int, MsgExecuteContract } from "@terra-money/terra.js"; +import { computeGasPaid, parseEventsFromLog } from "../helpers/receipt"; import { makeGovernanceVaaPayload, makeTransferVaaPayload, signAndEncodeVaa, TEST_SIGNER_PKS, } from "../helpers/vaa"; -import { computeGasPaid, parseEventsFromLog } from "../helpers/receipt"; +import { deploy, storeCode } from "../instantiate"; + +setDefaultWasm("node"); jest.setTimeout(60000); @@ -23,14 +30,35 @@ const GOVERNANCE_ADDRESS = const FOREIGN_CHAIN = 1; const FOREIGN_TOKEN_BRIDGE = "000000000000000000000000000000000000000000000000000000000000ffff"; +const FOREIGN_TOKEN = + "000000000000000000000000000000000000000000000000000000000000eeee"; const GUARDIAN_SET_INDEX = 0; +const GUARDIAN_ADDRESS = Buffer.from( + "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe", + "hex" +).toString("base64"); +const LUNA_ADDRESS = + "01" + keccak256(Buffer.from("uluna", "utf-8")).substring(4); // cut off 0x56 (0x prefix - 1 byte) +// const INJ_ADDRESS = +// "01" + keccak256(Buffer.from("inj", "utf-8")).substring(4); // cut off 0x56 (0x prefix - 1 byte) +const MCK_TOKEN_ID = + "00" + + keccak256( + Buffer.from( + "terra1zwv6feuzhy6a9wekh96cd57lsarmqlwxdypdsplw6zhfncqw6ftqynf7kp", + "utf-8" + ) + ).substring(4); const CONSISTENCY_LEVEL = 0; +const CHAIN_ID = 18; + const WASM_WORMHOLE = "../artifacts/wormhole.wasm"; -const WASM_WRAPPED_ASSET = "../artifacts/cw20_wrapped.wasm"; -const WASM_TOKEN_BRIDGE = "../artifacts/token_bridge_terra.wasm"; +const WASM_WRAPPED_ASSET = "../artifacts/cw20_wrapped_2.wasm"; +const WASM_TOKEN_BRIDGE = "../artifacts/token_bridge_terra_2.wasm"; const WASM_MOCK_BRIDGE_INTEGRATION = - "../artifacts/mock_bridge_integration.wasm"; + "../artifacts/mock_bridge_integration_2.wasm"; +const WASM_CW20 = "../artifacts/cw20_base.wasm"; // global map of contract addresses for all tests const contracts = new Map(); @@ -55,14 +83,25 @@ const contracts = new Map(); > should not allow a redemption from msg.sender other than 'to' on token bridge transfer with payload > should allow a redemption from msg.sender == 'to' on token bridge transfer with payload and check that sender recieves fee > should burn bridged assets wrappers on transfer to another chain - > should handle ETH deposits correctly (uusd) - > should handle ETH withdrawals and fees correctly (uusd) - > should handle ETH deposits with payload correctly (uusd) - > should handle ETH withdrawals with payload correctly (uusd) + > should handle ETH deposits correctly (uluna) + > should handle ETH withdrawals and fees correctly (uluna) + > should handle ETH deposits with payload correctly (uluna) + > should handle ETH withdrawals with payload correctly (uluna) > should revert on transfer out of a total of > max(uint64) tokens */ +test("LUNA Hashing", () => { + const knownLuna = + "01fa6c6fbc36d8c245b0a852a43eb5d644e8b4c477b27bfab9537c10945939da"; + expect(LUNA_ADDRESS).toBe(knownLuna); +}); +test("MCK Hashing", () => { + const knownMck = + "007160d54c6dabbf464c2f9d95d42f4a30aa6ab2da6c71363917e418c4abe689"; + expect(MCK_TOKEN_ID).toBe(knownMck); +}); + describe("Bridge Tests", () => { test("Deploy Contracts", (done) => { (async () => { @@ -75,36 +114,45 @@ describe("Bridge Tests", () => { ).toString("base64"); // wormhole - const wormhole = await deploy(client, wallet, WASM_WORMHOLE, { - gov_chain: GOVERNANCE_CHAIN, - gov_address: governanceAddress, - guardian_set_expirity: 86400, - initial_guardian_set: { - addresses: [ - { - bytes: Buffer.from( - "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe", - "hex" - ).toString("base64"), - }, - ], - expiration_time: 0, + const wormhole = await deploy( + client, + wallet, + WASM_WORMHOLE, + { + gov_chain: GOVERNANCE_CHAIN, + gov_address: governanceAddress, + guardian_set_expirity: 86400, + initial_guardian_set: { + addresses: [ + { + bytes: GUARDIAN_ADDRESS, + }, + ], + expiration_time: 0, + }, }, - }); - + "wormhole" + ); + console.log("wormhole deployed at", wormhole); // token bridge const wrappedAssetCodeId = await storeCode( client, wallet, WASM_WRAPPED_ASSET ); - const tokenBridge = await deploy(client, wallet, WASM_TOKEN_BRIDGE, { - gov_chain: GOVERNANCE_CHAIN, - gov_address: governanceAddress, - wormhole_contract: wormhole, - wrapped_asset_code_id: wrappedAssetCodeId, - }); - + const tokenBridge = await deploy( + client, + wallet, + WASM_TOKEN_BRIDGE, + { + gov_chain: GOVERNANCE_CHAIN, + gov_address: governanceAddress, + wormhole_contract: wormhole, + wrapped_asset_code_id: wrappedAssetCodeId, + }, + "tokenBridge" + ); + console.log("tokenBridge deployed at", tokenBridge); // mock bridge integration const mockBridgeIntegration = await deploy( client, @@ -112,11 +160,34 @@ describe("Bridge Tests", () => { WASM_MOCK_BRIDGE_INTEGRATION, { token_bridge_contract: tokenBridge, - } + }, + "mockBridgeIntegration" ); + console.log("mockBridgeIntegration deployed at", mockBridgeIntegration); + // test CW20 + const cw20 = await deploy( + client, + wallet, + WASM_CW20, + { + name: "MOCK", + symbol: "MCK", + decimals: 6, + initial_balances: [ + { + address: wallet.key.accAddress, + amount: "100000000", + }, + ], + mint: null, + }, + "mock" + ); + console.log("cw20 deployed at", cw20); contracts.set("wormhole", wormhole); contracts.set("tokenBridge", tokenBridge); contracts.set("mockBridgeIntegration", mockBridgeIntegration); + contracts.set("cw20", cw20); done(); } catch (e) { console.error(e); @@ -124,6 +195,95 @@ describe("Bridge Tests", () => { } })(); }); + test("Query GuardianSetInfo", (done) => { + (async () => { + try { + const [client] = await makeProviderAndWallet(); + + const wormhole = contracts.get("wormhole")!; + const result: any = await client.wasm.contractQuery(wormhole, { + guardian_set_info: {}, + }); + expect(result.guardian_set_index).toBe(0); + expect(result.addresses.length).toBe(1); + expect(result.addresses[0].bytes).toBe(GUARDIAN_ADDRESS); + done(); + } catch (e) { + console.error(e); + done("Failed to Query GuardianSetInfo"); + } + })(); + }); + test("Query State", (done) => { + (async () => { + try { + const [client] = await makeProviderAndWallet(); + + const wormhole = contracts.get("wormhole")!; + const result: any = await client.wasm.contractQuery(wormhole, { + get_state: {}, + }); + expect(result.fee.amount).toBe("0"); + expect(result.fee.denom).toBe("uluna"); + done(); + } catch (e) { + console.error(e); + done("Failed to Query State"); + } + })(); + }); + test("Post a Message", (done) => { + (async () => { + try { + const [client, wallet] = await makeProviderAndWallet(); + + const wormhole = contracts.get("wormhole")!; + const postMessage = new MsgExecuteContract( + wallet.key.accAddress, + wormhole, + { + post_message: { + message: Buffer.from("0001020304050607", "hex").toString( + "base64" + ), + nonce: 69, + }, + } + ); + const receipt = await transactWithoutMemo(client, wallet, [ + postMessage, + ]); + const seq0 = parseSequenceFromLogTerra(receipt as any); + expect(seq0).toBe("0"); + const receipt2 = await transactWithoutMemo(client, wallet, [ + postMessage, + ]); + const seq1 = parseSequenceFromLogTerra(receipt2 as any); + expect(seq1).toBe("1"); + done(); + } catch (e) { + console.error(e); + done("Failed to Post a Message"); + } + })(); + }); + test("Query Token", (done) => { + (async () => { + try { + const [client] = await makeProviderAndWallet(); + + const cw20 = contracts.get("cw20")!; + const result: any = await client.wasm.contractQuery(cw20, { + token_info: {}, + }); + console.log(result); + done(); + } catch (e) { + console.error(e); + done("Failed to Query Token"); + } + })(); + }); test("Register a Foreign Bridge Implementation", (done) => { (async () => { try { @@ -134,7 +294,6 @@ describe("Bridge Tests", () => { FOREIGN_CHAIN, FOREIGN_TOKEN_BRIDGE ); - console.info("vaaPayload", vaaPayload); const timestamp = 1; const nonce = 1; @@ -151,7 +310,6 @@ describe("Bridge Tests", () => { GUARDIAN_SET_INDEX, CONSISTENCY_LEVEL ); - console.info("signedVaa", signedVaa); const tokenBridge = contracts.get("tokenBridge")!; const submitVaa = new MsgExecuteContract( @@ -165,7 +323,6 @@ describe("Bridge Tests", () => { ); const receipt = await transactWithoutMemo(client, wallet, [submitVaa]); - console.info("receipt", receipt.txhash); done(); } catch (e) { console.error(e); @@ -180,8 +337,8 @@ describe("Bridge Tests", () => { const tokenBridge = contracts.get("tokenBridge")!; - // transfer uusd - const denom = "uusd"; + // transfer uluna + const denom = "uluna"; const recipientAddress = "0000000000000000000000004206942069420694206942069420694206942069"; const amount = "100000000"; // one benjamin @@ -230,11 +387,10 @@ describe("Bridge Tests", () => { ); // execute outbound transfer + await transactWithoutMemo(client, wallet, [deposit]); const receipt = await transactWithoutMemo(client, wallet, [ - deposit, initiateTransfer, ]); - console.info("receipt", receipt.txhash); const balanceAfter = await getNativeBalance(client, tokenBridge, denom); expect(balanceBefore.add(amount).eq(balanceAfter)).toBeTruthy(); @@ -253,27 +409,23 @@ describe("Bridge Tests", () => { const tokenBridge = contracts.get("tokenBridge")!; - const denom = "uusd"; + const denom = "uluna"; const amount = "100000000"; // one benjamin const relayerFee = "1000000"; // one dolla const walletAddress = wallet.key.accAddress; const recipient = "terra17lmam6zguazs5q5u6z5mmx76uj63gldnse2pdp"; // test2 const encodedTo = nativeToHex(recipient); - console.log("encodedTo", encodedTo); - const ustAddress = - "0100000000000000000000000000000000000000000000000000000075757364"; const vaaPayload = makeTransferVaaPayload( 1, amount, - ustAddress, + LUNA_ADDRESS, encodedTo, - 3, + CHAIN_ID, relayerFee, undefined ); - console.info("vaaPayload", vaaPayload); const timestamp = 0; const nonce = 0; @@ -290,7 +442,6 @@ describe("Bridge Tests", () => { GUARDIAN_SET_INDEX, CONSISTENCY_LEVEL ); - console.info("signedVaa", signedVaa); // check balances const walletBalanceBefore = await getNativeBalance( @@ -317,7 +468,6 @@ describe("Bridge Tests", () => { // execute outbound transfer with signed vaa const receipt = await transactWithoutMemo(client, wallet, [submitVaa]); - console.info("receipt", receipt.txhash); // check wallet (relayer) balance change const walletBalanceAfter = await getNativeBalance( @@ -329,7 +479,7 @@ describe("Bridge Tests", () => { const walletExpectedChange = new Int(relayerFee).sub(gasPaid); // due to rounding, we should expect the balances to reconcile - // within 1 unit (equivalent to 1e-6 uusd). Best-case scenario + // within 1 unit (equivalent to 1e-6 uluna). Best-case scenario // we end up with slightly more balance than expected const reconciled = walletBalanceAfter .minus(walletExpectedChange) @@ -351,7 +501,7 @@ describe("Bridge Tests", () => { .eq(recipientBalanceAfter) ).toBeTruthy(); - // cehck bridge balance change + // check bridge balance change const bridgeExpectedChange = new Int(amount); const bridgeBalanceAfter = await getNativeBalance( client, @@ -377,8 +527,8 @@ describe("Bridge Tests", () => { const tokenBridge = contracts.get("tokenBridge")!; - // transfer uusd - const denom = "uusd"; + // transfer uluna + const denom = "uluna"; const recipientAddress = "0000000000000000000000004206942069420694206942069420694206942069"; const amount = "100000000"; // one benjamin @@ -433,7 +583,6 @@ describe("Bridge Tests", () => { deposit, initiateTransferWithPayload, ]); - console.info("receipt txHash", receipt.txhash); const balanceAfter = await getNativeBalance(client, tokenBridge, denom); expect(balanceBefore.add(amount).eq(balanceAfter)).toBeTruthy(); @@ -453,28 +602,24 @@ describe("Bridge Tests", () => { const tokenBridge = contracts.get("tokenBridge")!; const mockBridgeIntegration = contracts.get("mockBridgeIntegration")!; - const denom = "uusd"; + const denom = "uluna"; const amount = "100000000"; // one benjamin const relayerFee = "1000000"; // one dolla const walletAddress = wallet.key.accAddress; const encodedTo = nativeToHex(mockBridgeIntegration); - console.log("encodedTo", encodedTo); - const ustAddress = - "0100000000000000000000000000000000000000000000000000000075757364"; const additionalPayload = "All your base are belong to us"; const vaaPayload = makeTransferVaaPayload( 3, amount, - ustAddress, + LUNA_ADDRESS, encodedTo, - 3, + CHAIN_ID, relayerFee, additionalPayload ); - console.info("vaaPayload", vaaPayload); const timestamp = 1; const nonce = 1; @@ -491,7 +636,6 @@ describe("Bridge Tests", () => { GUARDIAN_SET_INDEX, CONSISTENCY_LEVEL ); - console.info("signedVaa", signedVaa); // check balances before execute const walletBalanceBefore = await getNativeBalance( @@ -522,7 +666,6 @@ describe("Bridge Tests", () => { // execute outbound transfer with signed vaa const receipt = await transactWithoutMemo(client, wallet, [submitVaa]); - console.info("receipt txHash", receipt.txhash); // check wallet (relayer) balance change const walletBalanceAfter = await getNativeBalance( @@ -534,7 +677,7 @@ describe("Bridge Tests", () => { const walletExpectedChange = new Int(relayerFee).sub(gasPaid); // due to rounding, we should expect the balances to reconcile - // within 1 unit (equivalent to 1e-6 uusd). Best-case scenario + // within 1 unit (equivalent to 1e-6 uluna). Best-case scenario // we end up with slightly more balance than expected const reconciled = walletBalanceAfter .minus(walletExpectedChange) @@ -596,28 +739,24 @@ describe("Bridge Tests", () => { const tokenBridge = contracts.get("tokenBridge")!; const mockBridgeIntegration = contracts.get("mockBridgeIntegration")!; - const denom = "uusd"; + const denom = "uluna"; const amount = "100000000"; // one benjamin const relayerFee = "1000000"; // one dolla const walletAddress = wallet.key.accAddress; const encodedTo = nativeToHex(mockBridgeIntegration); - console.log("encodedTo", encodedTo); - const ustAddress = - "0100000000000000000000000000000000000000000000000000000075757364"; const additionalPayload = "All your base are belong to us"; const vaaPayload = makeTransferVaaPayload( 3, amount, - ustAddress, + LUNA_ADDRESS, encodedTo, - 3, + CHAIN_ID, relayerFee, additionalPayload ); - console.info("vaaPayload", vaaPayload); const timestamp = 1; const nonce = 1; @@ -634,7 +773,6 @@ describe("Bridge Tests", () => { GUARDIAN_SET_INDEX, CONSISTENCY_LEVEL ); - console.info("signedVaa", signedVaa); let expectedErrorFound = false; try { @@ -649,7 +787,6 @@ describe("Bridge Tests", () => { const receipt = await transactWithoutMemo(client, wallet, [ submitVaa, ]); - console.info("receipt txHash", receipt.txhash); } catch (e) { const errorMsg: string = e.response.data.message; expectedErrorFound = errorMsg.includes( @@ -668,6 +805,115 @@ describe("Bridge Tests", () => { } })(); }); + test("Attest a Native Asset", (done) => { + (async () => { + try { + const [client, wallet] = await makeProviderAndWallet(); + + const tokenBridge = contracts.get("tokenBridge")!; + const attest = new MsgExecuteContract( + wallet.key.accAddress, + tokenBridge, + { + create_asset_meta: { + asset_info: { + native_token: { denom: "uluna" }, + }, + nonce: 69, + }, + } + ); + + const receipt = await transactWithoutMemo(client, wallet, [attest]); + done(); + } catch (e) { + console.error(e); + done("Failed to Attest a Native Asset"); + } + })(); + }); + test("Attest a CW20", (done) => { + (async () => { + try { + const [client, wallet] = await makeProviderAndWallet(); + + const tokenBridge = contracts.get("tokenBridge")!; + const attest = new MsgExecuteContract( + wallet.key.accAddress, + tokenBridge, + { + create_asset_meta: { + asset_info: { + token: { + contract_addr: contracts.get("cw20"), + }, + }, + nonce: 69, + }, + } + ); + + const receipt = await transactWithoutMemo(client, wallet, [attest]); + console.log(receipt); + done(); + } catch (e) { + console.error(e); + done("Failed to Attest a CW20"); + } + })(); + }); + // test("Register a Foreign Asset", (done) => { + // (async () => { + // try { + // const [client, wallet] = await makeProviderAndWallet(); + + // const vaaPayload = makeAttestationVaaPayload( + // FOREIGN_CHAIN, + // FOREIGN_TOKEN, + // 18, + // hexZeroPad("0x" + Buffer.from("TEST", "utf-8").toString("hex"), 32), + // hexZeroPad( + // "0x" + Buffer.from("Testy Token", "utf-8").toString("hex"), + // 32 + // ) + // ); + + // const timestamp = 1; + // const nonce = 1; + // const sequence = 0; + + // const signedVaa = signAndEncodeVaa( + // timestamp, + // nonce, + // GOVERNANCE_CHAIN, + // GOVERNANCE_ADDRESS, + // sequence, + // vaaPayload, + // TEST_SIGNER_PKS, + // GUARDIAN_SET_INDEX, + // CONSISTENCY_LEVEL + // ); + + // const tokenBridge = contracts.get("tokenBridge")!; + // const submitVaa = new MsgExecuteContract( + // wallet.key.accAddress, + // tokenBridge, + // { + // submit_vaa: { + // data: Buffer.from(signedVaa, "hex").toString("base64"), + // }, + // } + // ); + + // const receipt = await transactWithoutMemo(client, wallet, [submitVaa]); + // console.log(receipt); + // done(); + // } catch (e) { + // console.error(e); + // done("Failed to Register a Foreign Asset"); + // } + // })(); + // }); }); function nativeToHex(address: string) { diff --git a/cosmwasm/test/src/helpers/client.ts b/cosmwasm/test/src/helpers/client.ts index d634a71a9..3199fa832 100644 --- a/cosmwasm/test/src/helpers/client.ts +++ b/cosmwasm/test/src/helpers/client.ts @@ -7,7 +7,7 @@ import { Wallet, } from "@terra-money/terra.js"; -export const GAS_PRICE = 0.2; // uusd +export const GAS_PRICE = 0.15; // uluna export async function makeProviderAndWallet(): Promise<[LCDClient, Wallet]> { // provider @@ -16,7 +16,7 @@ export async function makeProviderAndWallet(): Promise<[LCDClient, Wallet]> { chainID: "localterra", gasAdjustment: "2", gasPrices: { - uusd: GAS_PRICE, + uluna: GAS_PRICE, }, }); @@ -45,7 +45,7 @@ export async function transact( memo: memo, }); - return client.tx.broadcast(tx); + return client.tx.broadcastBlock(tx); } export async function transactWithoutMemo( diff --git a/cosmwasm/test/src/helpers/receipt.ts b/cosmwasm/test/src/helpers/receipt.ts index 3dc7ce745..28dec8a5e 100644 --- a/cosmwasm/test/src/helpers/receipt.ts +++ b/cosmwasm/test/src/helpers/receipt.ts @@ -7,7 +7,7 @@ export function parseEventsFromLog(receipt: BlockTxBroadcastResult): any[] { } export function computeGasPaid(receipt: BlockTxBroadcastResult): Int { - const gasPrice = new Coin("uusd", GAS_PRICE).amount; + const gasPrice = new Coin("uluna", GAS_PRICE).amount; // LocalTerra seems to spend all the gas_wanted // instead of spending gas_used... return new Int(gasPrice.mul(receipt.gas_wanted).ceil()); diff --git a/cosmwasm/test/src/helpers/vaa.ts b/cosmwasm/test/src/helpers/vaa.ts index da7473e43..78196fede 100644 --- a/cosmwasm/test/src/helpers/vaa.ts +++ b/cosmwasm/test/src/helpers/vaa.ts @@ -21,6 +21,23 @@ export function makeGovernanceVaaPayload( ); } +export function makeAttestationVaaPayload( + chain: number, + hexlifiedTokenAddress: string, + decimals: number, + symbol: string, + name: string +) { + return ( + abi.encodeParameter("uint8", 2).substring(2 + 62) + + hexlifiedTokenAddress + + abi.encodeParameter("uint16", chain).substring(2 + (64 - 4)) + + abi.encodeParameter("uint8", decimals).substring(2 + 62) + + symbol + + name + ); +} + export function makeTransferVaaPayload( payloadType: number, amount: string, @@ -37,7 +54,8 @@ export function makeTransferVaaPayload( // tokenaddress hexlifiedTokenAddress + // tokenchain - "0003" + // we only care about terra-specific tokens for these tests + // TODO: add tests for non-native tokens too + "0012" + // we only care about terra2-specific tokens for these tests // receiver encodedTo + // receiving chain diff --git a/cosmwasm/test/src/instantiate.ts b/cosmwasm/test/src/instantiate.ts index 1941dd330..928938566 100644 --- a/cosmwasm/test/src/instantiate.ts +++ b/cosmwasm/test/src/instantiate.ts @@ -29,7 +29,8 @@ export async function deploy( terra: LCDClient, wallet: Wallet, wasm: string, - instantiateMsg: Object + instantiateMsg: Object, + label: string ): Promise { const codeId = await storeCode(terra, wallet, wasm); @@ -38,11 +39,13 @@ export async function deploy( wallet.key.accAddress, wallet.key.accAddress, codeId, - instantiateMsg + instantiateMsg, + undefined, + label ), ]; const receipt = await transactWithoutMemo(terra, wallet, msgs); // @ts-ignore - return /"contract_address","value":"([^"]+)/gm.exec(receipt.raw_log)[1]; + return /"_contract_address","value":"([^"]+)/gm.exec(receipt.raw_log)[1]; } diff --git a/cosmwasm/tools/deploy.js b/cosmwasm/tools/deploy.js index 0706e2733..11e7232b3 100644 --- a/cosmwasm/tools/deploy.js +++ b/cosmwasm/tools/deploy.js @@ -1,7 +1,6 @@ -import 'dotenv/config' +import "dotenv/config"; import { LCDClient, MnemonicKey } from "@terra-money/terra.js"; import { - StdFee, MsgInstantiateContract, MsgExecuteContract, MsgStoreCode, @@ -17,13 +16,10 @@ import { zeroPad } from "ethers/lib/utils.js"; */ const artifacts = [ "wormhole.wasm", - "token_bridge_terra.wasm", - "cw20_wrapped.wasm", + "token_bridge_terra_2.wasm", + "cw20_wrapped_2.wasm", "cw20_base.wasm", - "nft_bridge.wasm", - "cw721_wrapped.wasm", - "cw721_base.wasm", - "mock_bridge_integration.wasm", + "mock_bridge_integration_2.wasm", ]; /* Check that the artifact folder contains all the wasm files we expect and nothing else */ @@ -117,7 +113,7 @@ const govChain = 1; const govAddress = "0000000000000000000000000000000000000000000000000000000000000004"; -async function instantiate(contract, inst_msg) { +async function instantiate(contract, inst_msg, label) { var address; await wallet .createAndSignTx({ @@ -126,14 +122,16 @@ async function instantiate(contract, inst_msg) { wallet.key.accAddress, wallet.key.accAddress, codeIds[contract], - inst_msg + inst_msg, + undefined, + label ), ], memo: "", }) .then((tx) => terra.tx.broadcast(tx)) .then((rs) => { - address = /"contract_address","value":"([^"]+)/gm.exec(rs.raw_log)[1]; + address = /"_contract_address","value":"([^"]+)/gm.exec(rs.raw_log)[1]; }); console.log( `Instantiated ${contract} at ${address} (${convert_terra_address_to_hex( @@ -148,99 +146,61 @@ async function instantiate(contract, inst_msg) { const addresses = {}; -const init_guardians = JSON.parse(process.env.INIT_SIGNERS) +const init_guardians = JSON.parse(process.env.INIT_SIGNERS); if (!init_guardians || init_guardians.length === 0) { - throw "failed to get initial guardians from .env file." + throw "failed to get initial guardians from .env file."; } -addresses["wormhole.wasm"] = await instantiate("wormhole.wasm", { - gov_chain: govChain, - gov_address: Buffer.from(govAddress, "hex").toString("base64"), - guardian_set_expirity: 86400, - initial_guardian_set: { - addresses: init_guardians.map(hex => { - return { - bytes: Buffer.from(hex, "hex").toString("base64") - } - }), - expiration_time: 0, - }, -}); - -addresses["token_bridge_terra.wasm"] = await instantiate("token_bridge_terra.wasm", { - gov_chain: govChain, - gov_address: Buffer.from(govAddress, "hex").toString("base64"), - wormhole_contract: addresses["wormhole.wasm"], - wrapped_asset_code_id: codeIds["cw20_wrapped.wasm"], -}); - -addresses["mock.wasm"] = await instantiate("cw20_base.wasm", { - name: "MOCK", - symbol: "MCK", - decimals: 6, - initial_balances: [ - { - address: wallet.key.accAddress, - amount: "100000000", - }, - ], - mint: null, -}); - -addresses["nft_bridge.wasm"] = await instantiate("nft_bridge.wasm", { - gov_chain: govChain, - gov_address: Buffer.from(govAddress, "hex").toString("base64"), - wormhole_contract: addresses["wormhole.wasm"], - wrapped_asset_code_id: codeIds["cw721_wrapped.wasm"], -}); - -addresses["cw721_base.wasm"] = await instantiate("cw721_base.wasm", { - name: "MOCK", - symbol: "MCK", - minter: wallet.key.accAddress, -}); - -async function mint_cw721(token_id, token_uri) { - await wallet - .createAndSignTx({ - msgs: [ - new MsgExecuteContract( - wallet.key.accAddress, - addresses["cw721_base.wasm"], - { - mint: { - token_id: token_id.toString(), - owner: wallet.key.accAddress, - token_uri: token_uri, - }, - }, - { uluna: 1000 } - ), - ], - memo: "", - fee: new StdFee(2000000, { - uluna: "100000", +addresses["wormhole.wasm"] = await instantiate( + "wormhole.wasm", + { + gov_chain: govChain, + gov_address: Buffer.from(govAddress, "hex").toString("base64"), + guardian_set_expirity: 86400, + initial_guardian_set: { + addresses: init_guardians.map((hex) => { + return { + bytes: Buffer.from(hex, "hex").toString("base64"), + }; }), - }) - .then((tx) => terra.tx.broadcast(tx)); - console.log( - `Minted NFT with token_id ${token_id} at ${addresses["cw721_base.wasm"]}` - ); -} - -await mint_cw721( - 0, - "https://ixmfkhnh2o4keek2457f2v2iw47cugsx23eynlcfpstxihsay7nq.arweave.net/RdhVHafTuKIRWud-XVdItz4qGlfWyYasRXyndB5Ax9s/" + expiration_time: 0, + }, + }, + "wormhole" ); -await mint_cw721( - 1, - "https://portal.neondistrict.io/api/getNft/158456327500392944014123206890" + +addresses["token_bridge_terra_2.wasm"] = await instantiate( + "token_bridge_terra_2.wasm", + { + gov_chain: govChain, + gov_address: Buffer.from(govAddress, "hex").toString("base64"), + wormhole_contract: addresses["wormhole.wasm"], + wrapped_asset_code_id: codeIds["cw20_wrapped_2.wasm"], + }, + "tokenBridge" +); + +addresses["mock.wasm"] = await instantiate( + "cw20_base.wasm", + { + name: "MOCK", + symbol: "MCK", + decimals: 6, + initial_balances: [ + { + address: wallet.key.accAddress, + amount: "100000000", + }, + ], + mint: null, + }, + "mock" ); /* Registrations: tell the bridge contracts to know about each other */ const contract_registrations = { - "token_bridge_terra.wasm": [ + "token_bridge_terra_2.wasm": [ // Solana process.env.REGISTER_SOL_TOKEN_BRIDGE_VAA, // Ethereum @@ -249,12 +209,8 @@ const contract_registrations = { process.env.REGISTER_BSC_TOKEN_BRIDGE_VAA, // ALGO process.env.REGISTER_ALGO_TOKEN_BRIDGE_VAA, - ], - "nft_bridge.wasm": [ - // Solana - process.env.REGISTER_SOL_NFT_BRIDGE_VAA, - // Ethereum - process.env.REGISTER_ETH_NFT_BRIDGE_VAA, + // TERRA + process.env.REGISTER_TERRA_TOKEN_BRIDGE_VAA, ], }; @@ -278,9 +234,6 @@ for (const [contract, registrations] of Object.entries( ), ], memo: "", - fee: new StdFee(2000000, { - uluna: "100000", - }), }) .then((tx) => terra.tx.broadcast(tx)) .then((rs) => console.log(rs)); diff --git a/cosmwasm/tools/package-lock.json b/cosmwasm/tools/package-lock.json index 7cf6dad0a..b834eae92 100644 --- a/cosmwasm/tools/package-lock.json +++ b/cosmwasm/tools/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@cosmjs/encoding": "^0.26.2", - "@terra-money/terra.js": "^2.0.11", + "@terra-money/terra.js": "^3.1.3", "dotenv": "^16.0.0", "ethers": "^5.4.4", "yargs": "^17.0.1" @@ -725,12 +725,90 @@ "@ethersproject/strings": "^5.6.0" } }, - "node_modules/@terra-money/terra.js": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-2.0.11.tgz", - "integrity": "sha512-33MrW3SGEmbHzjAA93dw1VA6IKbp6gYJbOTUkQzQbi+msIUf4m9ZewB6v5b8UZJfTfEe/T5RjXCWQHmANsz11w==", + "node_modules/@improbable-eng/grpc-web": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", + "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", "dependencies": { - "axios": "^0.21.1", + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@terra-money/legacy.proto": { + "name": "@terra-money/terra.proto", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", + "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "dependencies": { + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@terra-money/terra.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.3.tgz", + "integrity": "sha512-80HU5WXrqf3hZTo2GRhIycH17A+SkLD6afbu8MynMDGGD/A861F3zVv6NQ/Z7PWQGHxgddZEK/A0UQ2uK/xfHg==", + "dependencies": { + "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@terra-money/terra.proto": "~2.0.0", + "axios": "^0.26.1", "bech32": "^2.0.0", "bip32": "^2.0.6", "bip39": "^3.0.3", @@ -741,12 +819,28 @@ "secp256k1": "^4.0.2", "tmp": "^0.2.1", "utf-8-validate": "^5.0.5", - "ws": "^7.4.2" + "ws": "^7.5.5" }, "engines": { - "node": ">=12" + "node": ">=14" } }, + "node_modules/@terra-money/terra.proto": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.0.0.tgz", + "integrity": "sha512-ZjyFOFUzrGn8IwzGIgr1OJFcPSsQoz/XAfoSKThJx+OjJA7CLhdcz51+5h7ehNfb+qB9wr7aNME0h24wu9D4SQ==", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "node_modules/@types/node": { "version": "10.12.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", @@ -780,11 +874,11 @@ } }, "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "dependencies": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.14.8" } }, "node_modules/balanced-match": { @@ -884,6 +978,11 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, + "node_modules/browser-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", + "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==" + }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -1072,9 +1171,9 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "node_modules/follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", "funding": [ { "type": "individual", @@ -1122,6 +1221,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/google-protobuf": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz", + "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw==" + }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -1189,6 +1293,11 @@ "jscrypto": "bin/cli.js" } }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -1271,6 +1380,36 @@ "node": ">=0.12" } }, + "node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/@types/node": { + "version": "17.0.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.41.tgz", + "integrity": "sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -1942,12 +2081,86 @@ "@ethersproject/strings": "^5.6.0" } }, - "@terra-money/terra.js": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-2.0.11.tgz", - "integrity": "sha512-33MrW3SGEmbHzjAA93dw1VA6IKbp6gYJbOTUkQzQbi+msIUf4m9ZewB6v5b8UZJfTfEe/T5RjXCWQHmANsz11w==", + "@improbable-eng/grpc-web": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", + "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", "requires": { - "axios": "^0.21.1", + "browser-headers": "^0.4.1" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "@terra-money/legacy.proto": { + "version": "npm:@terra-money/terra.proto@0.1.7", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", + "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "requires": { + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "@terra-money/terra.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.3.tgz", + "integrity": "sha512-80HU5WXrqf3hZTo2GRhIycH17A+SkLD6afbu8MynMDGGD/A861F3zVv6NQ/Z7PWQGHxgddZEK/A0UQ2uK/xfHg==", + "requires": { + "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@terra-money/terra.proto": "~2.0.0", + "axios": "^0.26.1", "bech32": "^2.0.0", "bip32": "^2.0.6", "bip39": "^3.0.3", @@ -1958,9 +2171,25 @@ "secp256k1": "^4.0.2", "tmp": "^0.2.1", "utf-8-validate": "^5.0.5", - "ws": "^7.4.2" + "ws": "^7.5.5" } }, + "@terra-money/terra.proto": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.0.0.tgz", + "integrity": "sha512-ZjyFOFUzrGn8IwzGIgr1OJFcPSsQoz/XAfoSKThJx+OjJA7CLhdcz51+5h7ehNfb+qB9wr7aNME0h24wu9D4SQ==", + "requires": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, "@types/node": { "version": "10.12.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", @@ -1985,11 +2214,11 @@ } }, "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", "requires": { - "follow-redirects": "^1.14.0" + "follow-redirects": "^1.14.8" } }, "balanced-match": { @@ -2074,6 +2303,11 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, + "browser-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", + "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==" + }, "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -2239,9 +2473,9 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==" + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" }, "fs.realpath": { "version": "1.0.0", @@ -2266,6 +2500,11 @@ "path-is-absolute": "^1.0.0" } }, + "google-protobuf": { + "version": "3.20.1", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.20.1.tgz", + "integrity": "sha512-XMf1+O32FjYIV3CYu6Tuh5PNbfNEU5Xu22X+Xkdb/DUexFlCzhvv7d5Iirm4AOwn8lv4al1YvIhzGrg2j9Zfzw==" + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -2324,6 +2563,11 @@ "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.2.tgz", "integrity": "sha512-r+oNJLGTv1nkNMBBq3c70xYrFDgJOYVgs2OHijz5Ht+0KJ0yObD0oYxC9mN72KLzVfXw+osspg6t27IZvuTUxw==" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -2392,6 +2636,33 @@ "sha.js": "^2.4.8" } }, + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "17.0.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.41.tgz", + "integrity": "sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw==" + } + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", diff --git a/cosmwasm/tools/package.json b/cosmwasm/tools/package.json index 9b68b3840..3b666fe25 100644 --- a/cosmwasm/tools/package.json +++ b/cosmwasm/tools/package.json @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "@cosmjs/encoding": "^0.26.2", - "@terra-money/terra.js": "^2.0.11", + "@terra-money/terra.js": "^3.1.3", "dotenv": "^16.0.0", "ethers": "^5.4.4", "yargs": "^17.0.1" diff --git a/devnet/eth-devnet.yaml b/devnet/eth-devnet.yaml index 3f1a4fb66..484cccf1f 100644 --- a/devnet/eth-devnet.yaml +++ b/devnet/eth-devnet.yaml @@ -69,7 +69,7 @@ spec: command: - /bin/sh - -c - - "npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_bsc_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0" + - "npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_terra2_chain.js && npx truffle exec scripts/register_bsc_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0" readinessProbe: periodSeconds: 1 failureThreshold: 300 @@ -122,7 +122,7 @@ spec: command: - /bin/sh - -c - - "sed -i 's/CHAIN_ID=0x2/CHAIN_ID=0x4/g' .env && npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_eth_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0" + - "sed -i 's/CHAIN_ID=0x2/CHAIN_ID=0x4/g' .env && npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_terra2_chain.js && npx truffle exec scripts/register_eth_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0" readinessProbe: periodSeconds: 1 failureThreshold: 300 diff --git a/devnet/terra2-devnet.yaml b/devnet/terra2-devnet.yaml index 62f59207b..87ba815fb 100644 --- a/devnet/terra2-devnet.yaml +++ b/devnet/terra2-devnet.yaml @@ -138,7 +138,7 @@ spec: app: terra2-fcd spec: containers: - - image: terramoney/fcd:bombay + - image: terramoney/fcd:2.0.5 name: fcd-collector args: - collector @@ -168,7 +168,7 @@ spec: value: "false" - name: TYPEORM_ENTITIES value: "src/orm/*Entity.ts" - - image: terramoney/fcd:bombay + - image: terramoney/fcd:2.0.5 name: fcd-api args: - start diff --git a/docs/devnet.md b/docs/devnet.md index 334f13cfc..c2081eef7 100644 --- a/docs/devnet.md +++ b/docs/devnet.md @@ -1,29 +1,33 @@ ## Addresses -| Label | Network | Address | Note | -| ------------- | :-------------: | -----: | :----- | -| Test Wallet | ETH | 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1 | Key: `0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d` Mnemonic `myth like bonus scare over problem client lizard pioneer submit female collect` | -| Test ERC20 | ETH | 0x2D8BE6BF0baA74e0A907016679CaE9190e80dD0A | Tokens minted to Test Wallet | -| Test NFT | ETH | 0x5b9b42d6e4B2e4Bf8d42Eba32D46918e10899B66 | One minted to Test Wallet -| Test WETH | ETH | 0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E | Tokens minted to Test Wallet -| Bridge Core | ETH | 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 | | -| Token Bridge | ETH | 0x0290FB167208Af455bB137780163b7B7a9a10C16 | | -| NFT Bridge | ETH | 0x26b4afb60d6c903165150c6f0aa14f8016be4aec | | -| Test Wallet | SOL | 6sbzC1eH4FTujJXWj51eQe25cYvr4xfXbJ1vAj7j2k5J | Key in `solana/keys/solana-devnet.json` | -| Example Token | SOL | 2WDq7wSs9zYrpx2kbHDA4RUTRch2CCTP6ZWaH4GNfnQQ | Tokens minted to Test Wallet | -| Example NFT | SOL | BVxyYhm498L79r4HMQ9sxZ5bi41DmJmeWZ7SCS7Cyvna | One minted to Test Wallet | -| Example NFT 2 | SOL | nftMANh29jbMboVnbYt1AUAWFP9N4Jnckr9Zeq85WUs | One minted to Test Wallet | -| Bridge Core | SOL | Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o | | -| Token Bridge | SOL | B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE | | -| NFT Bridge | SOL | NFTWqJR8YnRVqPDvTJrYuLrQDitTG5AScqbeghi4zSA | | -| Migration Contract | SOL | Ex9bCdVMSfx7EzB3pgSi2R4UHwJAXvTw18rBQm5YQ8gK | | -| Test Wallet | Terra | terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v | Mnemonic: `notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius` | -| Test CW20 | Terra | terra13nkgqrfymug724h8pprpexqj9h629sa3ncw7sh | Tokens minted to Test Wallet | -| Test CW721 | Terra | terra18dt935pdcn2ka6l0syy5gt20wa48n3mktvdvjj | NFTs minted to Test Wallet | -| Bridge Core | Terra | terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5 | | -| Token Bridge | Terra | terra10pyejy66429refv3g35g2t7am0was7ya7kz2a4 | | -| NFT Bridge | Terra | terra1plju286nnfj3z54wgcggd4enwaa9fgf5kgrgzl | | -| Governance Emitter | Universal | 0x0000000000000000000000000000000000000000000000000000000000000004 / 11111111111111111111111111111115 | Emitter Chain: 0x01 | +| Label | Network | Address | Note | +| ------------------ | :-------: | ----------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Test Wallet | ETH | 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1 | Key: `0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d` Mnemonic `myth like bonus scare over problem client lizard pioneer submit female collect` | +| Test ERC20 | ETH | 0x2D8BE6BF0baA74e0A907016679CaE9190e80dD0A | Tokens minted to Test Wallet | +| Test NFT | ETH | 0x5b9b42d6e4B2e4Bf8d42Eba32D46918e10899B66 | One minted to Test Wallet | +| Test WETH | ETH | 0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E | Tokens minted to Test Wallet | +| Bridge Core | ETH | 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 | | +| Token Bridge | ETH | 0x0290FB167208Af455bB137780163b7B7a9a10C16 | | +| NFT Bridge | ETH | 0x26b4afb60d6c903165150c6f0aa14f8016be4aec | | +| Test Wallet | SOL | 6sbzC1eH4FTujJXWj51eQe25cYvr4xfXbJ1vAj7j2k5J | Key in `solana/keys/solana-devnet.json` | +| Example Token | SOL | 2WDq7wSs9zYrpx2kbHDA4RUTRch2CCTP6ZWaH4GNfnQQ | Tokens minted to Test Wallet | +| Example NFT | SOL | BVxyYhm498L79r4HMQ9sxZ5bi41DmJmeWZ7SCS7Cyvna | One minted to Test Wallet | +| Example NFT 2 | SOL | nftMANh29jbMboVnbYt1AUAWFP9N4Jnckr9Zeq85WUs | One minted to Test Wallet | +| Bridge Core | SOL | Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o | | +| Token Bridge | SOL | B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE | | +| NFT Bridge | SOL | NFTWqJR8YnRVqPDvTJrYuLrQDitTG5AScqbeghi4zSA | | +| Migration Contract | SOL | Ex9bCdVMSfx7EzB3pgSi2R4UHwJAXvTw18rBQm5YQ8gK | | +| Test Wallet | Terra | terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v | Mnemonic: `notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius` | +| Test CW20 | Terra | terra13nkgqrfymug724h8pprpexqj9h629sa3ncw7sh | Tokens minted to Test Wallet | +| Test CW721 | Terra | terra18dt935pdcn2ka6l0syy5gt20wa48n3mktvdvjj | NFTs minted to Test Wallet | +| Bridge Core | Terra | terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5 | | +| Token Bridge | Terra | terra10pyejy66429refv3g35g2t7am0was7ya7kz2a4 | | +| NFT Bridge | Terra | terra1plju286nnfj3z54wgcggd4enwaa9fgf5kgrgzl | | +| Test Wallet | Terra2 | terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v | Mnemonic: `notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius` | +| Test CW20 | Terra2 | terra1zwv6feuzhy6a9wekh96cd57lsarmqlwxdypdsplw6zhfncqw6ftqynf7kp | Tokens minted to Test Wallet | +| Bridge Core | Terra2 | terra14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9ssrc8au | | +| Token Bridge | Terra2 | terra1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrquka9l6 | | +| Governance Emitter | Universal | 0x0000000000000000000000000000000000000000000000000000000000000004 / 11111111111111111111111111111115 | Emitter Chain: 0x01 | ### Terra diff --git a/ethereum/scripts/register_terra2_chain.js b/ethereum/scripts/register_terra2_chain.js new file mode 100644 index 000000000..d3db9312a --- /dev/null +++ b/ethereum/scripts/register_terra2_chain.js @@ -0,0 +1,29 @@ +// run this script with truffle exec + +const jsonfile = require("jsonfile"); +const TokenBridge = artifacts.require("TokenBridge"); +const BridgeImplementationFullABI = jsonfile.readFileSync( + "../build/contracts/BridgeImplementation.json" +).abi; +const terra2TokenBridgeVAA = process.env.REGISTER_TERRA2_TOKEN_BRIDGE_VAA; + +module.exports = async function (callback) { + try { + const accounts = await web3.eth.getAccounts(); + const tokenBridge = new web3.eth.Contract( + BridgeImplementationFullABI, + TokenBridge.address + ); + + // Register the terra2 token bridge endpoint + await tokenBridge.methods.registerChain("0x" + terra2TokenBridgeVAA).send({ + value: 0, + from: accounts[0], + gasLimit: 2000000, + }); + + callback(); + } catch (e) { + callback(e); + } +}; diff --git a/scripts/devnet-consts.json b/scripts/devnet-consts.json index 0aa413f79..d17383009 100644 --- a/scripts/devnet-consts.json +++ b/scripts/devnet-consts.json @@ -202,6 +202,32 @@ "contracts": { "tokenBridgeEmitterAddress": "8edf5b0e108c3a1a0a4b704cc89591f2ad8d50df24e991567e640ed720a94be2" } + }, + "18": { + "rpcUrlTilt": "http://terra2-terrad:1317", + "rpcUrlLocal": "http://localhost:1318", + "rpcPort": "1318", + "contracts": { + "coreEmitterAddress": "ade4a5f5803a439835c636395a8d648dee57b2fc90d98dc17fa887159b69638b", + "coreNativeAddress": "terra14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9ssrc8au", + "tokenBridgeEmitterAddress": "9e28beafa966b2407bffb0d48651e94972a56e69f3c0897d9e8facbdaeb98386", + "tokenBridgeNativeAddress": "terra1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrquka9l6" + }, + "accounts": { + "testWallet": { + "public": "terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v", + "private": "", + "mnemonic": "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius" + } + }, + "addresses": { + "testToken": { + "address": "terra1zwv6feuzhy6a9wekh96cd57lsarmqlwxdypdsplw6zhfncqw6ftqynf7kp", + "name": "MOCK", + "symbol": "MCK", + "decimals": 6 + } + } } }, "gancheDefaults": [ diff --git a/scripts/guardian-set-init.sh b/scripts/guardian-set-init.sh index c1d2cf356..0c78ebdaa 100755 --- a/scripts/guardian-set-init.sh +++ b/scripts/guardian-set-init.sh @@ -76,6 +76,7 @@ ethTokenBridge=$(jq --raw-output '.chains."2".contracts.tokenBridgeEmitterAddres terraTokenBridge=$(jq --raw-output '.chains."3".contracts.tokenBridgeEmitterAddress' $addressesJson) bscTokenBridge=$(jq --raw-output '.chains."4".contracts.tokenBridgeEmitterAddress' $addressesJson) algoTokenBridge=$(jq --raw-output '.chains."8".contracts.tokenBridgeEmitterAddress' $addressesJson) +terra2TokenBridge=$(jq --raw-output '.chains."18".contracts.tokenBridgeEmitterAddress' $addressesJson) solNFTBridge=$(jq --raw-output '.chains."1".contracts.nftBridgeEmitterAddress' $addressesJson) ethNFTBridge=$(jq --raw-output '.chains."2".contracts.nftBridgeEmitterAddress' $addressesJson) @@ -95,6 +96,7 @@ ethTokenBridgeVAA=$(npm --prefix clients/js start --silent -- generate registrat terraTokenBridgeVAA=$(npm --prefix clients/js start --silent -- generate registration -m TokenBridge -c terra -a ${terraTokenBridge} -g ${guardiansPrivateCSV}) bscTokenBridgeVAA=$(npm --prefix clients/js start --silent -- generate registration -m TokenBridge -c bsc -a ${bscTokenBridge} -g ${guardiansPrivateCSV}) algoTokenBridgeVAA=$(npm --prefix clients/js start --silent -- generate registration -m TokenBridge -c algorand -a ${algoTokenBridge} -g ${guardiansPrivateCSV}) +terra2TokenBridgeVAA=$(npm --prefix clients/js start --silent -- generate registration -m TokenBridge -c terra2 -a ${terra2TokenBridge} -g ${guardiansPrivateCSV}) # 5) create nft bridge registration VAAs @@ -113,6 +115,7 @@ ethTokenBridge="REGISTER_ETH_TOKEN_BRIDGE_VAA" terraTokenBridge="REGISTER_TERRA_TOKEN_BRIDGE_VAA" bscTokenBridge="REGISTER_BSC_TOKEN_BRIDGE_VAA" algoTokenBridge="REGISTER_ALGO_TOKEN_BRIDGE_VAA" +terra2TokenBridge="REGISTER_TERRA2_TOKEN_BRIDGE_VAA" solNFTBridge="REGISTER_SOL_NFT_BRIDGE_VAA" ethNFTBridge="REGISTER_ETH_NFT_BRIDGE_VAA" @@ -151,6 +154,10 @@ upsert_env_file $envFile $bscTokenBridge $bscTokenBridgeVAA upsert_env_file $ethFile $algoTokenBridge $algoTokenBridgeVAA upsert_env_file $envFile $algoTokenBridge $algoTokenBridgeVAA +# terra2 token bridge +upsert_env_file $ethFile $terra2TokenBridge $terra2TokenBridgeVAA +upsert_env_file $envFile $terra2TokenBridge $terra2TokenBridgeVAA + # 7) copy the local .env file to the solana & terra dirs, if the script is running on the host machine # chain dirs will not exist if running in docker for Tilt, only if running locally. check before copying. @@ -161,7 +168,7 @@ if [[ -d ./ethereum ]]; then fi # copy the hex envFile to each of the non-EVM chains -for envDest in ./solana/.env ./terra/tools/.env ./algorand/.env; do +for envDest in ./solana/.env ./terra/tools/.env ./cosmwasm/tools/.env ./algorand/.env; do dirname=$(dirname $envDest) if [[ -d "$dirname" ]]; then echo "copying $envFile to $envDest" diff --git a/solana/devnet_setup.sh b/solana/devnet_setup.sh index eacef56c0..b1464e195 100755 --- a/solana/devnet_setup.sh +++ b/solana/devnet_setup.sh @@ -99,6 +99,7 @@ npm start -- submit -c solana -n devnet "$REGISTER_ETH_TOKEN_BRIDGE_VAA" npm start -- submit -c solana -n devnet "$REGISTER_TERRA_TOKEN_BRIDGE_VAA" npm start -- submit -c solana -n devnet "$REGISTER_BSC_TOKEN_BRIDGE_VAA" npm start -- submit -c solana -n devnet "$REGISTER_ALGO_TOKEN_BRIDGE_VAA" +npm start -- submit -c solana -n devnet "$REGISTER_TERRA2_TOKEN_BRIDGE_VAA" # Register the NFT Bridge Endpoint on ETH npm start -- submit -c solana -n devnet "$REGISTER_ETH_NFT_BRIDGE_VAA" npm start -- submit -c solana -n devnet "$REGISTER_TERRA_NFT_BRIDGE_VAA" diff --git a/terra/Dockerfile b/terra/Dockerfile index 6c058e2f8..e3884a70f 100644 --- a/terra/Dockerfile +++ b/terra/Dockerfile @@ -13,7 +13,7 @@ COPY README.md cert.pem* /certs/ # Alpine RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/cert.pem; fi -RUN optimize_workspace.sh +RUN --mount=type=cache,target=/code/target,id=terra_classic_target --mount=type=cache,target=/usr/local/cargo/registry optimize_workspace.sh FROM scratch as artifacts COPY --from=builder /code/artifacts / diff --git a/terra/tools/deploy.js b/terra/tools/deploy.js index 0706e2733..1d7419996 100644 --- a/terra/tools/deploy.js +++ b/terra/tools/deploy.js @@ -249,6 +249,8 @@ const contract_registrations = { process.env.REGISTER_BSC_TOKEN_BRIDGE_VAA, // ALGO process.env.REGISTER_ALGO_TOKEN_BRIDGE_VAA, + // TERRA2 + process.env.REGISTER_TERRA2_TOKEN_BRIDGE_VAA, ], "nft_bridge.wasm": [ // Solana