├── .cargo └── config ├── .circleci └── config.yml ├── .editorconfig ├── .github └── workflows │ ├── Lint.yml │ └── Test.yml ├── .gitignore ├── .gitpod.Dockerfile ├── .gitpod.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── artifacts ├── checksums.txt ├── checksums_intermediate.txt └── multicall.wasm ├── rustfmt.toml └── src ├── contract.rs ├── error.rs ├── lib.rs ├── mock_querier.rs ├── msg.rs ├── querier.rs └── test.rs /.cargo/config: -------------------------------------------------------------------------------- 1 | [alias] 2 | wasm = "build --release --target wasm32-unknown-unknown" 3 | unit-test = "test --lib" 4 | schema = "run --example schema" 5 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | builder: 5 | docker: 6 | - image: buildpack-deps:trusty 7 | 8 | jobs: 9 | docker-image: 10 | executor: builder 11 | steps: 12 | - checkout 13 | - setup_remote_docker 14 | docker_layer_caching: true 15 | - run: 16 | name: Build Docker artifact 17 | command: docker build --pull -t "cosmwasm/cw-gitpod-base:${CIRCLE_SHA1}" . 18 | - run: 19 | name: Push application Docker image to docker hub 20 | command: | 21 | if [ "${CIRCLE_BRANCH}" = "master" ]; then 22 | docker tag "cosmwasm/cw-gitpod-base:${CIRCLE_SHA1}" cosmwasm/cw-gitpod-base:latest 23 | docker login --password-stdin -u "$DOCKER_USER" \<<<"$DOCKER_PASS" 24 | docker push cosmwasm/cw-gitpod-base:latest 25 | docker logout 26 | fi 27 | 28 | docker-tagged: 29 | executor: builder 30 | steps: 31 | - checkout 32 | - setup_remote_docker 33 | docker_layer_caching: true 34 | - run: 35 | name: Push application Docker image to docker hub 36 | command: | 37 | docker tag "cosmwasm/cw-gitpod-base:${CIRCLE_SHA1}" "cosmwasm/cw-gitpod-base:${CIRCLE_TAG}" 38 | docker login --password-stdin -u "$DOCKER_USER" \<<<"$DOCKER_PASS" 39 | docker push 40 | docker logout 41 | 42 | workflows: 43 | version: 2 44 | test-suite: 45 | jobs: 46 | # this is now a slow process... let's only run on master 47 | - docker-image: 48 | filters: 49 | branches: 50 | only: 51 | - master 52 | - docker-tagged: 53 | filters: 54 | tags: 55 | only: 56 | - /^v.*/ 57 | branches: 58 | ignore: 59 | - /.*/ 60 | requires: 61 | - docker-image 62 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.rs] 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /.github/workflows/Lint.yml: -------------------------------------------------------------------------------- 1 | # Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml 2 | 3 | on: [push, pull_request] 4 | 5 | name: Test 6 | 7 | jobs: 8 | 9 | lints: 10 | name: Lints 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout sources 14 | uses: actions/checkout@v2 15 | 16 | - name: Install nightly toolchain 17 | uses: actions-rs/toolchain@v1 18 | with: 19 | profile: minimal 20 | toolchain: nightly 21 | override: true 22 | components: rustfmt, clippy 23 | 24 | - name: Run cargo fmt 25 | uses: actions-rs/cargo@v1 26 | with: 27 | command: fmt 28 | args: --all -- --check 29 | 30 | - name: Run cargo clippy 31 | uses: actions-rs/cargo@v1 32 | with: 33 | command: clippy 34 | args: -- -D warnings 35 | -------------------------------------------------------------------------------- /.github/workflows/Test.yml: -------------------------------------------------------------------------------- 1 | # Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml 2 | 3 | on: [push, pull_request] 4 | 5 | name: Test 6 | 7 | jobs: 8 | 9 | test: 10 | name: Test Suite 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout sources 14 | uses: actions/checkout@v2 15 | 16 | - name: Install nightly toolchain 17 | uses: actions-rs/toolchain@v1 18 | with: 19 | profile: minimal 20 | toolchain: nightly 21 | target: wasm32-unknown-unknown 22 | override: true 23 | 24 | - name: Run unit tests 25 | uses: actions-rs/cargo@v1 26 | with: 27 | command: unit-test 28 | args: --locked 29 | env: 30 | RUST_BACKTRACE: 1 31 | 32 | - name: Compile WASM contract 33 | uses: actions-rs/cargo@v1 34 | with: 35 | command: wasm 36 | args: --locked 37 | env: 38 | RUSTFLAGS: "-C link-arg=-s" 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build results 2 | /target 3 | 4 | # Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) 5 | .cargo-ok 6 | 7 | # Text file backups 8 | **/*.rs.bk 9 | 10 | # macOS 11 | .DS_Store 12 | 13 | # IDEs 14 | *.iml 15 | .idea 16 | -------------------------------------------------------------------------------- /.gitpod.Dockerfile: -------------------------------------------------------------------------------- 1 | ### wasmd ### 2 | FROM cosmwasm/wasmd:v0.18.0 as wasmd 3 | 4 | ### rust-optimizer ### 5 | FROM cosmwasm/rust-optimizer:0.11.5 as rust-optimizer 6 | 7 | FROM gitpod/workspace-full:latest 8 | 9 | COPY --from=wasmd /usr/bin/wasmd /usr/local/bin/wasmd 10 | COPY --from=wasmd /opt/* /opt/ 11 | 12 | RUN sudo apt-get update \ 13 | && sudo apt-get install -y jq \ 14 | && sudo rm -rf /var/lib/apt/lists/* 15 | 16 | RUN rustup update stable \ 17 | && rustup target add wasm32-unknown-unknown 18 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: cosmwasm/cw-gitpod-base:v0.16 2 | 3 | vscode: 4 | extensions: 5 | - rust-lang.rust 6 | 7 | tasks: 8 | - name: Dependencies & Build 9 | init: | 10 | cargo build 11 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.17.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" 10 | dependencies = [ 11 | "gimli 0.26.1", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "ahash" 22 | version = "0.7.6" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 25 | dependencies = [ 26 | "getrandom 0.2.3", 27 | "once_cell", 28 | "version_check", 29 | ] 30 | 31 | [[package]] 32 | name = "autocfg" 33 | version = "1.1.0" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 36 | 37 | [[package]] 38 | name = "backtrace" 39 | version = "0.3.64" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" 42 | dependencies = [ 43 | "addr2line", 44 | "cc", 45 | "cfg-if", 46 | "libc", 47 | "miniz_oxide", 48 | "object 0.27.1", 49 | "rustc-demangle", 50 | ] 51 | 52 | [[package]] 53 | name = "base16ct" 54 | version = "0.1.1" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" 57 | 58 | [[package]] 59 | name = "base64" 60 | version = "0.13.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 63 | 64 | [[package]] 65 | name = "base64ct" 66 | version = "1.5.2" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" 69 | 70 | [[package]] 71 | name = "bitflags" 72 | version = "1.3.2" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 75 | 76 | [[package]] 77 | name = "block-buffer" 78 | version = "0.9.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 81 | dependencies = [ 82 | "generic-array", 83 | ] 84 | 85 | [[package]] 86 | name = "bumpalo" 87 | version = "3.9.1" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 90 | 91 | [[package]] 92 | name = "bytecheck" 93 | version = "0.6.7" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "314889ea31cda264cb7c3d6e6e5c9415a987ecb0e72c17c00d36fbb881d34abe" 96 | dependencies = [ 97 | "bytecheck_derive", 98 | "ptr_meta", 99 | ] 100 | 101 | [[package]] 102 | name = "bytecheck_derive" 103 | version = "0.6.7" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "4a2b3b92c135dae665a6f760205b89187638e83bed17ef3e44e83c712cf30600" 106 | dependencies = [ 107 | "proc-macro2", 108 | "quote", 109 | "syn", 110 | ] 111 | 112 | [[package]] 113 | name = "byteorder" 114 | version = "1.4.3" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 117 | 118 | [[package]] 119 | name = "cc" 120 | version = "1.0.73" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 123 | 124 | [[package]] 125 | name = "cfg-if" 126 | version = "1.0.0" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 129 | 130 | [[package]] 131 | name = "clru" 132 | version = "0.4.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" 135 | 136 | [[package]] 137 | name = "const-oid" 138 | version = "0.7.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" 141 | 142 | [[package]] 143 | name = "cosmwasm-crypto" 144 | version = "1.0.0" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" 147 | dependencies = [ 148 | "digest", 149 | "ed25519-zebra", 150 | "k256", 151 | "rand_core 0.6.3", 152 | "thiserror", 153 | ] 154 | 155 | [[package]] 156 | name = "cosmwasm-derive" 157 | version = "1.0.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" 160 | dependencies = [ 161 | "syn", 162 | ] 163 | 164 | [[package]] 165 | name = "cosmwasm-std" 166 | version = "1.0.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" 169 | dependencies = [ 170 | "base64", 171 | "cosmwasm-crypto", 172 | "cosmwasm-derive", 173 | "forward_ref", 174 | "schemars", 175 | "serde", 176 | "serde-json-wasm", 177 | "thiserror", 178 | "uint", 179 | ] 180 | 181 | [[package]] 182 | name = "cosmwasm-vm" 183 | version = "1.0.0" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "472bd6f037bf4de43a29f65ca5d66b8c06510fdb2cd9c911ed08b5a2cec3606f" 186 | dependencies = [ 187 | "clru", 188 | "cosmwasm-crypto", 189 | "cosmwasm-std", 190 | "hex", 191 | "loupe", 192 | "parity-wasm", 193 | "schemars", 194 | "serde", 195 | "serde_json", 196 | "sha2", 197 | "thiserror", 198 | "wasmer", 199 | "wasmer-middlewares", 200 | ] 201 | 202 | [[package]] 203 | name = "cpufeatures" 204 | version = "0.1.5" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" 207 | dependencies = [ 208 | "libc", 209 | ] 210 | 211 | [[package]] 212 | name = "cranelift-bforest" 213 | version = "0.76.0" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "7e6bea67967505247f54fa2c85cf4f6e0e31c4e5692c9b70e4ae58e339067333" 216 | dependencies = [ 217 | "cranelift-entity", 218 | ] 219 | 220 | [[package]] 221 | name = "cranelift-codegen" 222 | version = "0.76.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "48194035d2752bdd5bdae429e3ab88676e95f52a2b1355a5d4e809f9e39b1d74" 225 | dependencies = [ 226 | "cranelift-bforest", 227 | "cranelift-codegen-meta", 228 | "cranelift-codegen-shared", 229 | "cranelift-entity", 230 | "gimli 0.25.0", 231 | "log", 232 | "regalloc", 233 | "smallvec", 234 | "target-lexicon", 235 | ] 236 | 237 | [[package]] 238 | name = "cranelift-codegen-meta" 239 | version = "0.76.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "976efb22fcab4f2cd6bd4e9913764616a54d895c1a23530128d04e03633c555f" 242 | dependencies = [ 243 | "cranelift-codegen-shared", 244 | "cranelift-entity", 245 | ] 246 | 247 | [[package]] 248 | name = "cranelift-codegen-shared" 249 | version = "0.76.0" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "9dabb5fe66e04d4652e434195b45ae65b5c8172d520247b8f66d8df42b2b45dc" 252 | 253 | [[package]] 254 | name = "cranelift-entity" 255 | version = "0.76.0" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "3329733e4d4b8e91c809efcaa4faee80bf66f20164e3dd16d707346bd3494799" 258 | 259 | [[package]] 260 | name = "cranelift-frontend" 261 | version = "0.76.0" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "279afcc0d3e651b773f94837c3d581177b348c8d69e928104b2e9fccb226f921" 264 | dependencies = [ 265 | "cranelift-codegen", 266 | "log", 267 | "smallvec", 268 | "target-lexicon", 269 | ] 270 | 271 | [[package]] 272 | name = "crc32fast" 273 | version = "1.3.2" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 276 | dependencies = [ 277 | "cfg-if", 278 | ] 279 | 280 | [[package]] 281 | name = "crossbeam-channel" 282 | version = "0.5.2" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" 285 | dependencies = [ 286 | "cfg-if", 287 | "crossbeam-utils", 288 | ] 289 | 290 | [[package]] 291 | name = "crossbeam-deque" 292 | version = "0.8.1" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" 295 | dependencies = [ 296 | "cfg-if", 297 | "crossbeam-epoch", 298 | "crossbeam-utils", 299 | ] 300 | 301 | [[package]] 302 | name = "crossbeam-epoch" 303 | version = "0.9.7" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" 306 | dependencies = [ 307 | "cfg-if", 308 | "crossbeam-utils", 309 | "lazy_static", 310 | "memoffset", 311 | "scopeguard", 312 | ] 313 | 314 | [[package]] 315 | name = "crossbeam-utils" 316 | version = "0.8.7" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" 319 | dependencies = [ 320 | "cfg-if", 321 | "lazy_static", 322 | ] 323 | 324 | [[package]] 325 | name = "crunchy" 326 | version = "0.2.2" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 329 | 330 | [[package]] 331 | name = "crypto-bigint" 332 | version = "0.3.2" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" 335 | dependencies = [ 336 | "generic-array", 337 | "rand_core 0.6.3", 338 | "subtle", 339 | "zeroize", 340 | ] 341 | 342 | [[package]] 343 | name = "crypto-mac" 344 | version = "0.11.1" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" 347 | dependencies = [ 348 | "generic-array", 349 | "subtle", 350 | ] 351 | 352 | [[package]] 353 | name = "curve25519-dalek" 354 | version = "3.2.0" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" 357 | dependencies = [ 358 | "byteorder", 359 | "digest", 360 | "rand_core 0.5.1", 361 | "subtle", 362 | "zeroize", 363 | ] 364 | 365 | [[package]] 366 | name = "cw-storage-plus" 367 | version = "0.14.0" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "1c8b264257c4f44c49b7ce09377af63aa040768ecd3fd7bdd2d48a09323a1e90" 370 | dependencies = [ 371 | "cosmwasm-std", 372 | "schemars", 373 | "serde", 374 | ] 375 | 376 | [[package]] 377 | name = "cw2" 378 | version = "0.14.0" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "aa74c324af8e3506fd8d50759a265bead3f87402e413c840042af5d2808463d6" 381 | dependencies = [ 382 | "cosmwasm-std", 383 | "cw-storage-plus", 384 | "schemars", 385 | "serde", 386 | ] 387 | 388 | [[package]] 389 | name = "darling" 390 | version = "0.13.1" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" 393 | dependencies = [ 394 | "darling_core", 395 | "darling_macro", 396 | ] 397 | 398 | [[package]] 399 | name = "darling_core" 400 | version = "0.13.1" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" 403 | dependencies = [ 404 | "fnv", 405 | "ident_case", 406 | "proc-macro2", 407 | "quote", 408 | "strsim", 409 | "syn", 410 | ] 411 | 412 | [[package]] 413 | name = "darling_macro" 414 | version = "0.13.1" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" 417 | dependencies = [ 418 | "darling_core", 419 | "quote", 420 | "syn", 421 | ] 422 | 423 | [[package]] 424 | name = "der" 425 | version = "0.5.1" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" 428 | dependencies = [ 429 | "const-oid", 430 | ] 431 | 432 | [[package]] 433 | name = "digest" 434 | version = "0.9.0" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 437 | dependencies = [ 438 | "generic-array", 439 | ] 440 | 441 | [[package]] 442 | name = "dyn-clone" 443 | version = "1.0.4" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" 446 | 447 | [[package]] 448 | name = "dynasm" 449 | version = "1.2.1" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "47b1801e630bd336d0bbbdbf814de6cc749c9a400c7e3d995e6adfd455d0c83c" 452 | dependencies = [ 453 | "bitflags", 454 | "byteorder", 455 | "lazy_static", 456 | "proc-macro-error", 457 | "proc-macro2", 458 | "quote", 459 | "syn", 460 | ] 461 | 462 | [[package]] 463 | name = "dynasmrt" 464 | version = "1.2.1" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "1d428afc93ad288f6dffc1fa5f4a78201ad2eec33c5a522e51c181009eb09061" 467 | dependencies = [ 468 | "byteorder", 469 | "dynasm", 470 | "memmap2", 471 | ] 472 | 473 | [[package]] 474 | name = "ecdsa" 475 | version = "0.13.4" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" 478 | dependencies = [ 479 | "der", 480 | "elliptic-curve", 481 | "rfc6979", 482 | "signature", 483 | ] 484 | 485 | [[package]] 486 | name = "ed25519-zebra" 487 | version = "3.0.0" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" 490 | dependencies = [ 491 | "curve25519-dalek", 492 | "hex", 493 | "rand_core 0.6.3", 494 | "serde", 495 | "sha2", 496 | "thiserror", 497 | "zeroize", 498 | ] 499 | 500 | [[package]] 501 | name = "either" 502 | version = "1.6.1" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 505 | 506 | [[package]] 507 | name = "elliptic-curve" 508 | version = "0.11.12" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" 511 | dependencies = [ 512 | "base16ct", 513 | "crypto-bigint", 514 | "der", 515 | "ff", 516 | "generic-array", 517 | "group", 518 | "rand_core 0.6.3", 519 | "sec1", 520 | "subtle", 521 | "zeroize", 522 | ] 523 | 524 | [[package]] 525 | name = "enum-iterator" 526 | version = "0.7.0" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" 529 | dependencies = [ 530 | "enum-iterator-derive", 531 | ] 532 | 533 | [[package]] 534 | name = "enum-iterator-derive" 535 | version = "0.7.0" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" 538 | dependencies = [ 539 | "proc-macro2", 540 | "quote", 541 | "syn", 542 | ] 543 | 544 | [[package]] 545 | name = "enumset" 546 | version = "1.0.8" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "6216d2c19a6fb5f29d1ada1dc7bc4367a8cbf0fa4af5cf12e07b5bbdde6b5b2c" 549 | dependencies = [ 550 | "enumset_derive", 551 | ] 552 | 553 | [[package]] 554 | name = "enumset_derive" 555 | version = "0.5.5" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "6451128aa6655d880755345d085494cf7561a6bee7c8dc821e5d77e6d267ecd4" 558 | dependencies = [ 559 | "darling", 560 | "proc-macro2", 561 | "quote", 562 | "syn", 563 | ] 564 | 565 | [[package]] 566 | name = "fallible-iterator" 567 | version = "0.2.0" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" 570 | 571 | [[package]] 572 | name = "fastrand" 573 | version = "1.7.0" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" 576 | dependencies = [ 577 | "instant", 578 | ] 579 | 580 | [[package]] 581 | name = "ff" 582 | version = "0.11.1" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" 585 | dependencies = [ 586 | "rand_core 0.6.3", 587 | "subtle", 588 | ] 589 | 590 | [[package]] 591 | name = "fnv" 592 | version = "1.0.7" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 595 | 596 | [[package]] 597 | name = "forward_ref" 598 | version = "1.0.0" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" 601 | 602 | [[package]] 603 | name = "generic-array" 604 | version = "0.14.4" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" 607 | dependencies = [ 608 | "typenum", 609 | "version_check", 610 | ] 611 | 612 | [[package]] 613 | name = "getrandom" 614 | version = "0.1.16" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 617 | dependencies = [ 618 | "cfg-if", 619 | "libc", 620 | "wasi 0.9.0+wasi-snapshot-preview1", 621 | ] 622 | 623 | [[package]] 624 | name = "getrandom" 625 | version = "0.2.3" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 628 | dependencies = [ 629 | "cfg-if", 630 | "libc", 631 | "wasi 0.10.2+wasi-snapshot-preview1", 632 | ] 633 | 634 | [[package]] 635 | name = "gimli" 636 | version = "0.25.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" 639 | dependencies = [ 640 | "fallible-iterator", 641 | "indexmap", 642 | "stable_deref_trait", 643 | ] 644 | 645 | [[package]] 646 | name = "gimli" 647 | version = "0.26.1" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" 650 | 651 | [[package]] 652 | name = "group" 653 | version = "0.11.0" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" 656 | dependencies = [ 657 | "ff", 658 | "rand_core 0.6.3", 659 | "subtle", 660 | ] 661 | 662 | [[package]] 663 | name = "hashbrown" 664 | version = "0.11.2" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 667 | dependencies = [ 668 | "ahash", 669 | ] 670 | 671 | [[package]] 672 | name = "hashbrown" 673 | version = "0.12.0" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" 676 | dependencies = [ 677 | "ahash", 678 | ] 679 | 680 | [[package]] 681 | name = "hermit-abi" 682 | version = "0.1.19" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 685 | dependencies = [ 686 | "libc", 687 | ] 688 | 689 | [[package]] 690 | name = "hex" 691 | version = "0.4.3" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 694 | 695 | [[package]] 696 | name = "hmac" 697 | version = "0.11.0" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" 700 | dependencies = [ 701 | "crypto-mac", 702 | "digest", 703 | ] 704 | 705 | [[package]] 706 | name = "ident_case" 707 | version = "1.0.1" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 710 | 711 | [[package]] 712 | name = "indexmap" 713 | version = "1.8.0" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" 716 | dependencies = [ 717 | "autocfg", 718 | "hashbrown 0.11.2", 719 | "serde", 720 | ] 721 | 722 | [[package]] 723 | name = "instant" 724 | version = "0.1.12" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 727 | dependencies = [ 728 | "cfg-if", 729 | ] 730 | 731 | [[package]] 732 | name = "itoa" 733 | version = "0.4.7" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 736 | 737 | [[package]] 738 | name = "js-sys" 739 | version = "0.3.56" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" 742 | dependencies = [ 743 | "wasm-bindgen", 744 | ] 745 | 746 | [[package]] 747 | name = "k256" 748 | version = "0.10.4" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" 751 | dependencies = [ 752 | "cfg-if", 753 | "ecdsa", 754 | "elliptic-curve", 755 | "sec1", 756 | "sha2", 757 | ] 758 | 759 | [[package]] 760 | name = "lazy_static" 761 | version = "1.4.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 764 | 765 | [[package]] 766 | name = "leb128" 767 | version = "0.2.5" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" 770 | 771 | [[package]] 772 | name = "libc" 773 | version = "0.2.99" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" 776 | 777 | [[package]] 778 | name = "libloading" 779 | version = "0.7.3" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" 782 | dependencies = [ 783 | "cfg-if", 784 | "winapi", 785 | ] 786 | 787 | [[package]] 788 | name = "log" 789 | version = "0.4.14" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 792 | dependencies = [ 793 | "cfg-if", 794 | ] 795 | 796 | [[package]] 797 | name = "loupe" 798 | version = "0.1.3" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" 801 | dependencies = [ 802 | "indexmap", 803 | "loupe-derive", 804 | "rustversion", 805 | ] 806 | 807 | [[package]] 808 | name = "loupe-derive" 809 | version = "0.1.3" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" 812 | dependencies = [ 813 | "quote", 814 | "syn", 815 | ] 816 | 817 | [[package]] 818 | name = "mach" 819 | version = "0.3.2" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" 822 | dependencies = [ 823 | "libc", 824 | ] 825 | 826 | [[package]] 827 | name = "memchr" 828 | version = "2.4.1" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 831 | 832 | [[package]] 833 | name = "memmap2" 834 | version = "0.5.3" 835 | source = "registry+https://github.com/rust-lang/crates.io-index" 836 | checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" 837 | dependencies = [ 838 | "libc", 839 | ] 840 | 841 | [[package]] 842 | name = "memoffset" 843 | version = "0.6.5" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 846 | dependencies = [ 847 | "autocfg", 848 | ] 849 | 850 | [[package]] 851 | name = "miniz_oxide" 852 | version = "0.4.4" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" 855 | dependencies = [ 856 | "adler", 857 | "autocfg", 858 | ] 859 | 860 | [[package]] 861 | name = "more-asserts" 862 | version = "0.2.2" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" 865 | 866 | [[package]] 867 | name = "multicall" 868 | version = "0.1.0" 869 | dependencies = [ 870 | "base64", 871 | "cosmwasm-std", 872 | "cosmwasm-vm", 873 | "cw2", 874 | "rand", 875 | "serde", 876 | "test-case", 877 | "thiserror", 878 | ] 879 | 880 | [[package]] 881 | name = "num_cpus" 882 | version = "1.13.1" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 885 | dependencies = [ 886 | "hermit-abi", 887 | "libc", 888 | ] 889 | 890 | [[package]] 891 | name = "object" 892 | version = "0.27.1" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" 895 | dependencies = [ 896 | "memchr", 897 | ] 898 | 899 | [[package]] 900 | name = "object" 901 | version = "0.28.3" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "40bec70ba014595f99f7aa110b84331ffe1ee9aece7fe6f387cc7e3ecda4d456" 904 | dependencies = [ 905 | "crc32fast", 906 | "hashbrown 0.11.2", 907 | "indexmap", 908 | "memchr", 909 | ] 910 | 911 | [[package]] 912 | name = "once_cell" 913 | version = "1.10.0" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 916 | 917 | [[package]] 918 | name = "opaque-debug" 919 | version = "0.3.0" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 922 | 923 | [[package]] 924 | name = "parity-wasm" 925 | version = "0.42.2" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" 928 | 929 | [[package]] 930 | name = "pin-project-lite" 931 | version = "0.2.8" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" 934 | 935 | [[package]] 936 | name = "pkcs8" 937 | version = "0.8.0" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" 940 | dependencies = [ 941 | "der", 942 | "spki", 943 | "zeroize", 944 | ] 945 | 946 | [[package]] 947 | name = "ppv-lite86" 948 | version = "0.2.16" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 951 | 952 | [[package]] 953 | name = "proc-macro-error" 954 | version = "1.0.4" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 957 | dependencies = [ 958 | "proc-macro-error-attr", 959 | "proc-macro2", 960 | "quote", 961 | "syn", 962 | "version_check", 963 | ] 964 | 965 | [[package]] 966 | name = "proc-macro-error-attr" 967 | version = "1.0.4" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 970 | dependencies = [ 971 | "proc-macro2", 972 | "quote", 973 | "version_check", 974 | ] 975 | 976 | [[package]] 977 | name = "proc-macro2" 978 | version = "1.0.28" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" 981 | dependencies = [ 982 | "unicode-xid", 983 | ] 984 | 985 | [[package]] 986 | name = "ptr_meta" 987 | version = "0.1.4" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" 990 | dependencies = [ 991 | "ptr_meta_derive", 992 | ] 993 | 994 | [[package]] 995 | name = "ptr_meta_derive" 996 | version = "0.1.4" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" 999 | dependencies = [ 1000 | "proc-macro2", 1001 | "quote", 1002 | "syn", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "quote" 1007 | version = "1.0.9" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 1010 | dependencies = [ 1011 | "proc-macro2", 1012 | ] 1013 | 1014 | [[package]] 1015 | name = "rand" 1016 | version = "0.8.5" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1019 | dependencies = [ 1020 | "libc", 1021 | "rand_chacha", 1022 | "rand_core 0.6.3", 1023 | ] 1024 | 1025 | [[package]] 1026 | name = "rand_chacha" 1027 | version = "0.3.1" 1028 | source = "registry+https://github.com/rust-lang/crates.io-index" 1029 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1030 | dependencies = [ 1031 | "ppv-lite86", 1032 | "rand_core 0.6.3", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "rand_core" 1037 | version = "0.5.1" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1040 | dependencies = [ 1041 | "getrandom 0.1.16", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "rand_core" 1046 | version = "0.6.3" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 1049 | dependencies = [ 1050 | "getrandom 0.2.3", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "rayon" 1055 | version = "1.5.1" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" 1058 | dependencies = [ 1059 | "autocfg", 1060 | "crossbeam-deque", 1061 | "either", 1062 | "rayon-core", 1063 | ] 1064 | 1065 | [[package]] 1066 | name = "rayon-core" 1067 | version = "1.9.1" 1068 | source = "registry+https://github.com/rust-lang/crates.io-index" 1069 | checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" 1070 | dependencies = [ 1071 | "crossbeam-channel", 1072 | "crossbeam-deque", 1073 | "crossbeam-utils", 1074 | "lazy_static", 1075 | "num_cpus", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "redox_syscall" 1080 | version = "0.2.11" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" 1083 | dependencies = [ 1084 | "bitflags", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "regalloc" 1089 | version = "0.0.31" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5" 1092 | dependencies = [ 1093 | "log", 1094 | "rustc-hash", 1095 | "smallvec", 1096 | ] 1097 | 1098 | [[package]] 1099 | name = "region" 1100 | version = "3.0.0" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" 1103 | dependencies = [ 1104 | "bitflags", 1105 | "libc", 1106 | "mach", 1107 | "winapi", 1108 | ] 1109 | 1110 | [[package]] 1111 | name = "remove_dir_all" 1112 | version = "0.5.3" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 1115 | dependencies = [ 1116 | "winapi", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "rend" 1121 | version = "0.3.6" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" 1124 | dependencies = [ 1125 | "bytecheck", 1126 | ] 1127 | 1128 | [[package]] 1129 | name = "rfc6979" 1130 | version = "0.1.0" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" 1133 | dependencies = [ 1134 | "crypto-bigint", 1135 | "hmac", 1136 | "zeroize", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "rkyv" 1141 | version = "0.7.35" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "2cdcf5caf69bcc87b1e3f5427b4f21a32fdd53c2847687bdf9861abb1cdaa0d8" 1144 | dependencies = [ 1145 | "bytecheck", 1146 | "hashbrown 0.12.0", 1147 | "ptr_meta", 1148 | "rend", 1149 | "rkyv_derive", 1150 | "seahash", 1151 | ] 1152 | 1153 | [[package]] 1154 | name = "rkyv_derive" 1155 | version = "0.7.35" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "a6cf557da1f81b8c7e889c59c9c3abaf6978f7feb156b9579e4f8bf6d7a2bada" 1158 | dependencies = [ 1159 | "proc-macro2", 1160 | "quote", 1161 | "syn", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "rustc-demangle" 1166 | version = "0.1.21" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" 1169 | 1170 | [[package]] 1171 | name = "rustc-hash" 1172 | version = "1.1.0" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1175 | 1176 | [[package]] 1177 | name = "rustversion" 1178 | version = "1.0.6" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" 1181 | 1182 | [[package]] 1183 | name = "ryu" 1184 | version = "1.0.5" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 1187 | 1188 | [[package]] 1189 | name = "schemars" 1190 | version = "0.8.3" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "bc6ab463ae35acccb5cba66c0084c985257b797d288b6050cc2f6ac1b266cb78" 1193 | dependencies = [ 1194 | "dyn-clone", 1195 | "schemars_derive", 1196 | "serde", 1197 | "serde_json", 1198 | ] 1199 | 1200 | [[package]] 1201 | name = "schemars_derive" 1202 | version = "0.8.3" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "902fdfbcf871ae8f653bddf4b2c05905ddaabc08f69d32a915787e3be0d31356" 1205 | dependencies = [ 1206 | "proc-macro2", 1207 | "quote", 1208 | "serde_derive_internals", 1209 | "syn", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "scopeguard" 1214 | version = "1.1.0" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1217 | 1218 | [[package]] 1219 | name = "seahash" 1220 | version = "4.1.0" 1221 | source = "registry+https://github.com/rust-lang/crates.io-index" 1222 | checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" 1223 | 1224 | [[package]] 1225 | name = "sec1" 1226 | version = "0.2.1" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" 1229 | dependencies = [ 1230 | "der", 1231 | "generic-array", 1232 | "pkcs8", 1233 | "subtle", 1234 | "zeroize", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "serde" 1239 | version = "1.0.127" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" 1242 | dependencies = [ 1243 | "serde_derive", 1244 | ] 1245 | 1246 | [[package]] 1247 | name = "serde-json-wasm" 1248 | version = "0.4.1" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" 1251 | dependencies = [ 1252 | "serde", 1253 | ] 1254 | 1255 | [[package]] 1256 | name = "serde_bytes" 1257 | version = "0.11.5" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" 1260 | dependencies = [ 1261 | "serde", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "serde_derive" 1266 | version = "1.0.127" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" 1269 | dependencies = [ 1270 | "proc-macro2", 1271 | "quote", 1272 | "syn", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "serde_derive_internals" 1277 | version = "0.25.0" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" 1280 | dependencies = [ 1281 | "proc-macro2", 1282 | "quote", 1283 | "syn", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "serde_json" 1288 | version = "1.0.66" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" 1291 | dependencies = [ 1292 | "itoa", 1293 | "ryu", 1294 | "serde", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "sha2" 1299 | version = "0.9.5" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" 1302 | dependencies = [ 1303 | "block-buffer", 1304 | "cfg-if", 1305 | "cpufeatures", 1306 | "digest", 1307 | "opaque-debug", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "signature" 1312 | version = "1.3.1" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" 1315 | dependencies = [ 1316 | "digest", 1317 | "rand_core 0.6.3", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "smallvec" 1322 | version = "1.8.0" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 1325 | 1326 | [[package]] 1327 | name = "spki" 1328 | version = "0.5.4" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" 1331 | dependencies = [ 1332 | "base64ct", 1333 | "der", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "stable_deref_trait" 1338 | version = "1.2.0" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1341 | 1342 | [[package]] 1343 | name = "static_assertions" 1344 | version = "1.1.0" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1347 | 1348 | [[package]] 1349 | name = "strsim" 1350 | version = "0.10.0" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1353 | 1354 | [[package]] 1355 | name = "subtle" 1356 | version = "2.4.1" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1359 | 1360 | [[package]] 1361 | name = "syn" 1362 | version = "1.0.74" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" 1365 | dependencies = [ 1366 | "proc-macro2", 1367 | "quote", 1368 | "unicode-xid", 1369 | ] 1370 | 1371 | [[package]] 1372 | name = "target-lexicon" 1373 | version = "0.12.3" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1" 1376 | 1377 | [[package]] 1378 | name = "tempfile" 1379 | version = "3.3.0" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 1382 | dependencies = [ 1383 | "cfg-if", 1384 | "fastrand", 1385 | "libc", 1386 | "redox_syscall", 1387 | "remove_dir_all", 1388 | "winapi", 1389 | ] 1390 | 1391 | [[package]] 1392 | name = "test-case" 1393 | version = "2.0.0" 1394 | source = "registry+https://github.com/rust-lang/crates.io-index" 1395 | checksum = "4f7d58e237f65d5fe5eaf1105188c94c9a441e1fbc298ed5df45ec9c9af236d3" 1396 | dependencies = [ 1397 | "cfg-if", 1398 | "proc-macro-error", 1399 | "proc-macro2", 1400 | "quote", 1401 | "syn", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "thiserror" 1406 | version = "1.0.26" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" 1409 | dependencies = [ 1410 | "thiserror-impl", 1411 | ] 1412 | 1413 | [[package]] 1414 | name = "thiserror-impl" 1415 | version = "1.0.26" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" 1418 | dependencies = [ 1419 | "proc-macro2", 1420 | "quote", 1421 | "syn", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "tracing" 1426 | version = "0.1.32" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" 1429 | dependencies = [ 1430 | "cfg-if", 1431 | "log", 1432 | "pin-project-lite", 1433 | "tracing-attributes", 1434 | "tracing-core", 1435 | ] 1436 | 1437 | [[package]] 1438 | name = "tracing-attributes" 1439 | version = "0.1.20" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" 1442 | dependencies = [ 1443 | "proc-macro2", 1444 | "quote", 1445 | "syn", 1446 | ] 1447 | 1448 | [[package]] 1449 | name = "tracing-core" 1450 | version = "0.1.23" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" 1453 | dependencies = [ 1454 | "lazy_static", 1455 | ] 1456 | 1457 | [[package]] 1458 | name = "typenum" 1459 | version = "1.13.0" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" 1462 | 1463 | [[package]] 1464 | name = "uint" 1465 | version = "0.9.3" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" 1468 | dependencies = [ 1469 | "byteorder", 1470 | "crunchy", 1471 | "hex", 1472 | "static_assertions", 1473 | ] 1474 | 1475 | [[package]] 1476 | name = "unicode-xid" 1477 | version = "0.2.2" 1478 | source = "registry+https://github.com/rust-lang/crates.io-index" 1479 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1480 | 1481 | [[package]] 1482 | name = "version_check" 1483 | version = "0.9.3" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 1486 | 1487 | [[package]] 1488 | name = "wasi" 1489 | version = "0.9.0+wasi-snapshot-preview1" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1492 | 1493 | [[package]] 1494 | name = "wasi" 1495 | version = "0.10.2+wasi-snapshot-preview1" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1498 | 1499 | [[package]] 1500 | name = "wasm-bindgen" 1501 | version = "0.2.79" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" 1504 | dependencies = [ 1505 | "cfg-if", 1506 | "wasm-bindgen-macro", 1507 | ] 1508 | 1509 | [[package]] 1510 | name = "wasm-bindgen-backend" 1511 | version = "0.2.79" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" 1514 | dependencies = [ 1515 | "bumpalo", 1516 | "lazy_static", 1517 | "log", 1518 | "proc-macro2", 1519 | "quote", 1520 | "syn", 1521 | "wasm-bindgen-shared", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "wasm-bindgen-macro" 1526 | version = "0.2.79" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" 1529 | dependencies = [ 1530 | "quote", 1531 | "wasm-bindgen-macro-support", 1532 | ] 1533 | 1534 | [[package]] 1535 | name = "wasm-bindgen-macro-support" 1536 | version = "0.2.79" 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" 1538 | checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" 1539 | dependencies = [ 1540 | "proc-macro2", 1541 | "quote", 1542 | "syn", 1543 | "wasm-bindgen-backend", 1544 | "wasm-bindgen-shared", 1545 | ] 1546 | 1547 | [[package]] 1548 | name = "wasm-bindgen-shared" 1549 | version = "0.2.79" 1550 | source = "registry+https://github.com/rust-lang/crates.io-index" 1551 | checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" 1552 | 1553 | [[package]] 1554 | name = "wasmer" 1555 | version = "2.2.1" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "f727a39e7161f7438ddb8eafe571b67c576a8c2fb459f666d9053b5bba4afdea" 1558 | dependencies = [ 1559 | "cfg-if", 1560 | "indexmap", 1561 | "js-sys", 1562 | "loupe", 1563 | "more-asserts", 1564 | "target-lexicon", 1565 | "thiserror", 1566 | "wasm-bindgen", 1567 | "wasmer-compiler", 1568 | "wasmer-compiler-cranelift", 1569 | "wasmer-compiler-singlepass", 1570 | "wasmer-derive", 1571 | "wasmer-engine", 1572 | "wasmer-engine-dylib", 1573 | "wasmer-engine-universal", 1574 | "wasmer-types", 1575 | "wasmer-vm", 1576 | "winapi", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "wasmer-compiler" 1581 | version = "2.2.1" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "4e9951599222eb12bd13d4d91bcded0a880e4c22c2dfdabdf5dc7e5e803b7bf3" 1584 | dependencies = [ 1585 | "enumset", 1586 | "loupe", 1587 | "rkyv", 1588 | "serde", 1589 | "serde_bytes", 1590 | "smallvec", 1591 | "target-lexicon", 1592 | "thiserror", 1593 | "wasmer-types", 1594 | "wasmer-vm", 1595 | "wasmparser", 1596 | ] 1597 | 1598 | [[package]] 1599 | name = "wasmer-compiler-cranelift" 1600 | version = "2.2.1" 1601 | source = "registry+https://github.com/rust-lang/crates.io-index" 1602 | checksum = "44c83273bce44e668f3a2b9ccb7f1193db918b1d6806f64acc5ff71f6ece5f20" 1603 | dependencies = [ 1604 | "cranelift-codegen", 1605 | "cranelift-entity", 1606 | "cranelift-frontend", 1607 | "gimli 0.25.0", 1608 | "loupe", 1609 | "more-asserts", 1610 | "rayon", 1611 | "smallvec", 1612 | "target-lexicon", 1613 | "tracing", 1614 | "wasmer-compiler", 1615 | "wasmer-types", 1616 | "wasmer-vm", 1617 | ] 1618 | 1619 | [[package]] 1620 | name = "wasmer-compiler-singlepass" 1621 | version = "2.2.1" 1622 | source = "registry+https://github.com/rust-lang/crates.io-index" 1623 | checksum = "5432e993840cdb8e6875ddc8c9eea64e7a129579b4706bd91b8eb474d9c4a860" 1624 | dependencies = [ 1625 | "byteorder", 1626 | "dynasm", 1627 | "dynasmrt", 1628 | "lazy_static", 1629 | "loupe", 1630 | "more-asserts", 1631 | "rayon", 1632 | "smallvec", 1633 | "wasmer-compiler", 1634 | "wasmer-types", 1635 | "wasmer-vm", 1636 | ] 1637 | 1638 | [[package]] 1639 | name = "wasmer-derive" 1640 | version = "2.2.1" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "458dbd9718a837e6dbc52003aef84487d79eedef5fa28c7d28b6784be98ac08e" 1643 | dependencies = [ 1644 | "proc-macro-error", 1645 | "proc-macro2", 1646 | "quote", 1647 | "syn", 1648 | ] 1649 | 1650 | [[package]] 1651 | name = "wasmer-engine" 1652 | version = "2.2.1" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "6ed603a6d037ebbb14014d7f739ae996a78455a4b86c41cfa4e81c590a1253b9" 1655 | dependencies = [ 1656 | "backtrace", 1657 | "enumset", 1658 | "lazy_static", 1659 | "loupe", 1660 | "memmap2", 1661 | "more-asserts", 1662 | "rustc-demangle", 1663 | "serde", 1664 | "serde_bytes", 1665 | "target-lexicon", 1666 | "thiserror", 1667 | "wasmer-compiler", 1668 | "wasmer-types", 1669 | "wasmer-vm", 1670 | ] 1671 | 1672 | [[package]] 1673 | name = "wasmer-engine-dylib" 1674 | version = "2.2.1" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "ccd7fdc60e252a795c849b3f78a81a134783051407e7e279c10b7019139ef8dc" 1677 | dependencies = [ 1678 | "cfg-if", 1679 | "enum-iterator", 1680 | "enumset", 1681 | "leb128", 1682 | "libloading", 1683 | "loupe", 1684 | "object 0.28.3", 1685 | "rkyv", 1686 | "serde", 1687 | "tempfile", 1688 | "tracing", 1689 | "wasmer-compiler", 1690 | "wasmer-engine", 1691 | "wasmer-object", 1692 | "wasmer-types", 1693 | "wasmer-vm", 1694 | "which", 1695 | ] 1696 | 1697 | [[package]] 1698 | name = "wasmer-engine-universal" 1699 | version = "2.2.1" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "dcff0cd2c01a8de6009fd863b14ea883132a468a24f2d2ee59dc34453d3a31b5" 1702 | dependencies = [ 1703 | "cfg-if", 1704 | "enum-iterator", 1705 | "enumset", 1706 | "leb128", 1707 | "loupe", 1708 | "region", 1709 | "rkyv", 1710 | "wasmer-compiler", 1711 | "wasmer-engine", 1712 | "wasmer-types", 1713 | "wasmer-vm", 1714 | "winapi", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "wasmer-middlewares" 1719 | version = "2.2.1" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "659775db15684f4674c3a8967409682c2eb44f63cc21121fa3dcd975c03ab887" 1722 | dependencies = [ 1723 | "loupe", 1724 | "wasmer", 1725 | "wasmer-types", 1726 | "wasmer-vm", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "wasmer-object" 1731 | version = "2.2.1" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "24ce18ac2877050e59580d27ee1a88f3192d7a31e77fbba0852abc7888d6e0b5" 1734 | dependencies = [ 1735 | "object 0.28.3", 1736 | "thiserror", 1737 | "wasmer-compiler", 1738 | "wasmer-types", 1739 | ] 1740 | 1741 | [[package]] 1742 | name = "wasmer-types" 1743 | version = "2.2.1" 1744 | source = "registry+https://github.com/rust-lang/crates.io-index" 1745 | checksum = "659fa3dd6c76f62630deff4ac8c7657b07f0b1e4d7e0f8243a552b9d9b448e24" 1746 | dependencies = [ 1747 | "indexmap", 1748 | "loupe", 1749 | "rkyv", 1750 | "serde", 1751 | "thiserror", 1752 | ] 1753 | 1754 | [[package]] 1755 | name = "wasmer-vm" 1756 | version = "2.2.1" 1757 | source = "registry+https://github.com/rust-lang/crates.io-index" 1758 | checksum = "afdc46158517c2769f9938bc222a7d41b3bb330824196279d8aa2d667cd40641" 1759 | dependencies = [ 1760 | "backtrace", 1761 | "cc", 1762 | "cfg-if", 1763 | "enum-iterator", 1764 | "indexmap", 1765 | "libc", 1766 | "loupe", 1767 | "memoffset", 1768 | "more-asserts", 1769 | "region", 1770 | "rkyv", 1771 | "serde", 1772 | "thiserror", 1773 | "wasmer-types", 1774 | "winapi", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "wasmparser" 1779 | version = "0.78.2" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "52144d4c78e5cf8b055ceab8e5fa22814ce4315d6002ad32cfd914f37c12fd65" 1782 | 1783 | [[package]] 1784 | name = "which" 1785 | version = "4.2.4" 1786 | source = "registry+https://github.com/rust-lang/crates.io-index" 1787 | checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" 1788 | dependencies = [ 1789 | "either", 1790 | "lazy_static", 1791 | "libc", 1792 | ] 1793 | 1794 | [[package]] 1795 | name = "winapi" 1796 | version = "0.3.9" 1797 | source = "registry+https://github.com/rust-lang/crates.io-index" 1798 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1799 | dependencies = [ 1800 | "winapi-i686-pc-windows-gnu", 1801 | "winapi-x86_64-pc-windows-gnu", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "winapi-i686-pc-windows-gnu" 1806 | version = "0.4.0" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1809 | 1810 | [[package]] 1811 | name = "winapi-x86_64-pc-windows-gnu" 1812 | version = "0.4.0" 1813 | source = "registry+https://github.com/rust-lang/crates.io-index" 1814 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1815 | 1816 | [[package]] 1817 | name = "zeroize" 1818 | version = "1.4.1" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" 1821 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multicall" 3 | version = "0.1.0" 4 | authors = ["SCB10x"] 5 | edition = "2021" 6 | repository = "https://github.com/scb-10x/multicall" 7 | description = "On-chain query aggregator/batcher in Terra" 8 | 9 | exclude = [ 10 | # 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. 11 | "contract.wasm", 12 | "hash.txt", 13 | ] 14 | 15 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 16 | 17 | [lib] 18 | crate-type = ["cdylib", "rlib"] 19 | 20 | [profile.release] 21 | opt-level = 3 22 | debug = false 23 | rpath = false 24 | lto = true 25 | debug-assertions = false 26 | codegen-units = 1 27 | panic = 'abort' 28 | incremental = false 29 | overflow-checks = true 30 | 31 | [features] 32 | # for more explicit tests, cargo test --features=backtraces 33 | backtraces = ["cosmwasm-std/backtraces"] 34 | # use library feature to disable all instantiate/execute/query exports 35 | library = [] 36 | 37 | [package.metadata.scripts] 38 | optimize = """docker run --rm -v "$(pwd)":/code \ 39 | --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ 40 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ 41 | cosmwasm/rust-optimizer:0.12.7 42 | """ 43 | 44 | [dependencies] 45 | cosmwasm-std = "1.0.0" 46 | cw2 = "0.14.0" 47 | serde = { version = "1.0.127", default-features = false, features = ["derive"] } 48 | thiserror = { version = "1.0.26" } 49 | 50 | [dev-dependencies] 51 | cosmwasm-vm = { version = "1.0.0" } 52 | rand = "0.8.3" 53 | base64 = "0.13.0" 54 | test-case = "2.0.0" 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multicall 2 | 3 | On-chain query aggregator/batcher in Terra. 4 | 5 | Artboard_12x 6 | 7 | ---- 8 | 9 | Mainnet (Phoenix) Code Id: `381` 10 | 11 | Mainnet Address: [`terra1g5puatcgawc58d95rflj9sxrl8wsted6n66yp6pndy69rc40k39snsefs3`](https://terrasco.pe/mainnet/address/terra1g5puatcgawc58d95rflj9sxrl8wsted6n66yp6pndy69rc40k39snsefs3) 12 | 13 | Testnet (Pisco) Code Id: `3616` 14 | 15 | Testnet Address: [`terra1s2crcfhahev6dclcv6wyeg3sd0c5nj3jrtv40nf0wpey6elk6pvqt2r562`](https://finder.terra.money/testnet/address/terra1s2crcfhahev6dclcv6wyeg3sd0c5nj3jrtv40nf0wpey6elk6pvqt2r562) 16 | 17 | Classic (Columbus) Code Id: `3758` 18 | 19 | Classic Address: [`terra1y60jx2jqh5qpmcnvgz3n0zg2p6ky4mr6ax2qa5`](https://finder.terra.money/classic/address/terra1y60jx2jqh5qpmcnvgz3n0zg2p6ky4mr6ax2qa5) 20 | 21 | ## Example Usage 22 | 23 | ### Aggregate 24 | 25 | #### Aggregate 26 | 27 | Example Query: [Link](https://bombay-fcd.terra.dev/wasm/contracts/terra1z9p02s5fkasx5qxdaes6mfyf2gt3kxuhcsd4va/store?query_msg=%7B%22aggregate%22:%7B%22queries%22:%5B%7B%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJjb25maWciOnt9fQ==%22%7D,%7B%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJlcG9jaF9zdGF0ZSI6e319%22%7D%5D%7D%7D) 28 | 29 | ```ts 30 | const multicallRes: any = await terra.wasm.contractQuery(multicall, { 31 | aggregate: { 32 | queries: [ 33 | { 34 | address: "terra15dwd5mj8v59wpj0wvt23mf5efdff808c5tkal", 35 | data: toBase64({ config: {} }), 36 | }, 37 | { 38 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 39 | data: toBase64({ epoch_state: {} }), 40 | }, 41 | ], 42 | }, 43 | }) 44 | 45 | console.log(multicallRes) 46 | 47 | // --- 48 | { 49 | return_data: [ 50 | { 51 | success: true, 52 | data: "eyJvd25lcl9hZGRyIjoidGVycmExNmNrZXV1N2M2Z2d1NTJhOHNlMD....", 53 | }, 54 | { 55 | success: true, 56 | data: "eyJleGNoYWnZV9yYXRlIjoiMS4yMzE0NTYyNzU4MjA1MDYwMDQiLC.....", 57 | }, 58 | ] 59 | } 60 | // --- 61 | 62 | const decoded = multicallRes.return_data.map((e) => { 63 | return JSON.parse(Buffer.from(e.data, "base64").toString()) 64 | }) 65 | 66 | 67 | console.log(decoded) 68 | 69 | // --- 70 | 71 | [ 72 | ({ 73 | owner_addr: "terra16ckeuu7c6ggu52a8se005mg5c0kd2kmuun63cu", 74 | aterra_contract: "terra1ajt556dpzvjwl0kl5tzku3fc3p3knkg9mkv8jl", 75 | interest_model: "terra1m25aqupscdw2kw4tnq5ql6hexgr34mr76azh5x", 76 | distribution_model: "terra1u64cezah94sq3ye8y0ung28x3pxc37tv8fth7h", 77 | overseer_contract: "terra1qljxd0y3j3gk97025qvl3lgq8ygup4gsksvaxv", 78 | collector_contract: "terra1hlctcrrhcl2azxzcsns467le876cfuzam6jty4", 79 | distributor_contract: "terra1z7nxemcnm8kp7fs33cs7ge4wfuld307v80gypj", 80 | stable_denom: "uusd", 81 | max_borrow_factor: "0.95", 82 | }, 83 | { 84 | exchange_rate: "1.231456275820506004", 85 | aterra_supply: "146558727243845", 86 | }) 87 | ] 88 | ``` 89 | 90 | #### Try Aggregate 91 | 92 | Aggregate with error suppression variant. If `include_cause` is `true`, `data` of the query will be error message in `String` if that query is return error. Else will return **empty string**. 93 | 94 | Example Query: [Link](https://bombay-fcd.terra.dev/wasm/contracts/terra1z9p02s5fkasx5qxdaes6mfyf2gt3kxuhcsd4va/store?query_msg=%7B%22try_aggregate%22:%7B%22require_success%22:false,%22include_cause%22:true,%22queries%22:%5B%7B%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJjb25maWciOnt9fQ==%22%7D,%7B%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJlcG9jaF9zdGF0ZSI6e319%22%7D%5D%7D%7D) 95 | 96 | ```ts 97 | const multicallRes: any = await terra.wasm.contractQuery(multicall, { 98 | try_aggregate: { 99 | require_success: false, // defualt to false 100 | include_cause: true, // default to false 101 | queries: [ 102 | { 103 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 104 | data: toBase64({ config: {} }), 105 | }, 106 | { 107 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 108 | data: toBase64({ epoch_state: {} }), 109 | }, 110 | ], 111 | }, 112 | }) 113 | 114 | const decoded = multicallRes.return_data.map((e) => { 115 | return e.length == 0 116 | ? null 117 | : JSON.parse(Buffer.from(e.data, "base64").toString()) 118 | }) 119 | ``` 120 | 121 | #### Try Aggregate With Optional Require Success 122 | 123 | Aggregate with specific error suppression variant. Same as `try_aggregate` but with element-specific error handling. 124 | 125 | Example Query: [Link](https://bombay-fcd.terra.dev/wasm/contracts/terra1z9p02s5fkasx5qxdaes6mfyf2gt3kxuhcsd4va/store?query_msg=%7B%22try_aggregate_optional%22:%7B%22include_cause%22:true,%22queries%22:%5B%7B%22require_success%22:true,%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJjb25maWciOnt9fQ==%22%7D,%7B%22require_success%22:false,%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJlcG9jaF9zdGF0ZSI6e319%22%7D%5D%7D%7D) 126 | 127 | ```ts 128 | const multicallRes: any = await terra.wasm.contractQuery(multicall, { 129 | try_aggregate_optional: { 130 | include_cause: true, // default to false 131 | queries: []]]] 132 | { 133 | require_success: true, 134 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 135 | data: toBase64({ config: {} }) 136 | }, 137 | { 138 | require_success: false, 139 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 140 | data: toBase64({ epoch_state: {} }) 141 | }, 142 | ] 143 | } 144 | }) 145 | 146 | const decoded = multicallRes.return_data.map((e) => { 147 | return e.length == 0 ? null : JSON.parse(Buffer.from(e.data, 'base64').toString()) 148 | }) 149 | ``` 150 | 151 | ### Aggregate With Block 152 | 153 | Include `block_` as prefix for query message to include block height as a result. 154 | 155 | Example Query: [Link](https://bombay-fcd.terra.dev/wasm/contracts/terra1z9p02s5fkasx5qxdaes6mfyf2gt3kxuhcsd4va/store?query_msg=%7B%22block_aggregate%22:%7B%22queries%22:%5B%7B%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJjb25maWciOnt9fQ==%22%7D,%7B%22address%22:%22terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal%22,%22data%22:%22eyJlcG9jaF9zdGF0ZSI6e319%22%7D%5D%7D%7D) 156 | 157 | ```ts 158 | const multicallRes: any = await terra.wasm.contractQuery(multicall, { 159 | block_aggregate: { 160 | queries: [ 161 | { 162 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 163 | data: toBase64({ config: {} }) 164 | }, 165 | { 166 | address: "terra15dwd5mj8v59wpj0wvt233mf5efdff808c5tkal", 167 | data: toBase64({ epoch_state: {} }) 168 | }, 169 | ] 170 | } 171 | }) 172 | 173 | console.log(multicallRes) 174 | 175 | // -- 176 | 177 | { 178 | block: 8259453, 179 | return_data: [ 180 | { 181 | success: true, 182 | data: 'eyJvd25lcl9hZGRyIjoidGVycmExNmNrZXV1N2M2Z2d1NTJhOHNlMDA1bWc1YzBrZDJrbXV1bjYzY3UiLCJhdGVycmFfY29udHJhY3QiOiJ0ZXJyYTFhanQ1NTZkcHp2andsMGtsNXR6a3UzZmMzcDNrbmtnOW1rdjhqbCIsImludGVyZXN0X21vZGVsIjoidGVycmExbTI1YXF1cHNjZHcya3c0dG5xNXFsNmhleGdyMzRtcjc2YXpoNXgiLCJkaXN0cmlidXRpb25fbW9kZWwiOiJ0ZXJyYTF1NjRjZXphaDk0c3EzeWU4eTB1bmcyOHgzcHhjMzd0djhmdGg3aCIsIm92ZXJzZWVyX2NvbnRyYWN0IjoidGVycmExcWxqeGQweTNqM2drOTcwMjVxdmwzbGdxOHlndXA0Z3Nrc3ZheHYiLCJjb2xsZWN0b3JfY29udHJhY3QiOiJ0ZXJyYTFobGN0Y3JyaGNsMmF6eHpjc25zNDY3bGU4NzZjZnV6YW02anR5NCIsImRpc3RyaWJ1dG9yX2NvbnRyYWN0IjoidGVycmExejdueGVtY25tOGtwN2ZzMzNjczdnZTR3ZnVsZDMwN3Y4MGd5cGoiLCJzdGFibGVfZGVub20iOiJ1dXNkIiwibWF4X2JvcnJvd19mYWN0b3IiOiIwLjk1In0=' 183 | }, 184 | { 185 | success: true, 186 | data: 'eyJleGNoYW5nZV9yYXRlIjoiMS4yMzIxNzc1ODQ0NTQzOTY2OTQiLCJhdGVycmFfc3VwcGx5IjoiMTQxNjE3NTE5MTk2NTY2In0=' 187 | } 188 | ] 189 | } 190 | ``` 191 | -------------------------------------------------------------------------------- /artifacts/checksums.txt: -------------------------------------------------------------------------------- 1 | 214391dd2fdf2394e8d28c1e348d20ca6a718dd77e2f5412e515c3c08f2f01d6 multicall.wasm 2 | -------------------------------------------------------------------------------- /artifacts/checksums_intermediate.txt: -------------------------------------------------------------------------------- 1 | 5ede30dbd04c32c533ab4fb273dba9bc563b446421ae54826c560df80b283e2f ./target/wasm32-unknown-unknown/release/multicall.wasm 2 | -------------------------------------------------------------------------------- /artifacts/multicall.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scb-10x/multicall/4200360a90605bc3cb714580cb8f0933056175df/artifacts/multicall.wasm -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | # stable 2 | newline_style = "unix" 3 | hard_tabs = false 4 | tab_spaces = 4 5 | 6 | # unstable... should we require `rustup run nightly cargo fmt` ? 7 | # or just update the style guide when they are stable? 8 | #fn_single_line = true 9 | #format_code_in_doc_comments = true 10 | #overflow_delimited_expr = true 11 | #reorder_impl_items = true 12 | #struct_field_align_threshold = 20 13 | #struct_lit_single_line = true 14 | #report_todo = "Always" 15 | 16 | -------------------------------------------------------------------------------- /src/contract.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(feature = "library"))] 2 | use cosmwasm_std::{ 3 | entry_point, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, 4 | }; 5 | use cw2::{get_contract_version, set_contract_version}; 6 | 7 | use crate::{ 8 | error::ContractError, 9 | msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, 10 | querier::{ 11 | aggregrate, block_aggregrate, block_try_aggregate_optional, block_try_aggregrate, 12 | try_aggregate, try_aggregate_optional, 13 | }, 14 | }; 15 | 16 | // version info for migration info 17 | const CONTRACT_NAME: &str = "crates.io:multicall"; 18 | const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); 19 | 20 | #[cfg_attr(not(feature = "library"), entry_point)] 21 | pub fn instantiate( 22 | deps: DepsMut, 23 | _env: Env, 24 | _info: MessageInfo, 25 | _msg: InstantiateMsg, 26 | ) -> Result { 27 | set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; 28 | Ok(Response::new().add_attribute("method", "instantiate")) 29 | } 30 | 31 | #[cfg_attr(not(feature = "library"), entry_point)] 32 | pub fn execute( 33 | _deps: DepsMut, 34 | _env: Env, 35 | _info: MessageInfo, 36 | _msg: ExecuteMsg, 37 | ) -> Result { 38 | Err(ContractError::ExecuteNotSupported) 39 | } 40 | 41 | #[cfg_attr(not(feature = "library"), entry_point)] 42 | pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { 43 | set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; 44 | Ok(Response::default()) 45 | } 46 | 47 | #[cfg_attr(not(feature = "library"), entry_point)] 48 | pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { 49 | match msg { 50 | QueryMsg::ContractVersion {} => to_binary(&get_contract_version(deps.storage)?), 51 | QueryMsg::Aggregate { queries } => to_binary(&aggregrate(deps, queries)?), 52 | QueryMsg::TryAggregate { 53 | require_success, 54 | include_cause, 55 | queries, 56 | } => to_binary(&try_aggregate( 57 | deps, 58 | require_success, 59 | include_cause, 60 | queries, 61 | )?), 62 | QueryMsg::TryAggregateOptional { 63 | include_cause, 64 | queries, 65 | } => to_binary(&try_aggregate_optional(deps, include_cause, queries)?), 66 | QueryMsg::BlockAggregate { queries } => to_binary(&block_aggregrate(deps, env, queries)?), 67 | QueryMsg::BlockTryAggregate { 68 | require_success, 69 | include_cause, 70 | queries, 71 | } => to_binary(&block_try_aggregrate( 72 | deps, 73 | env, 74 | require_success, 75 | include_cause, 76 | queries, 77 | )?), 78 | QueryMsg::BlockTryAggregateOptional { 79 | include_cause, 80 | queries, 81 | } => to_binary(&block_try_aggregate_optional( 82 | deps, 83 | env, 84 | include_cause, 85 | queries, 86 | )?), 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use cosmwasm_std::{Binary, StdError}; 2 | use thiserror::Error; 3 | 4 | #[derive(Error, Debug)] 5 | pub enum ContractError { 6 | #[error("{0}")] 7 | Std(#[from] StdError), 8 | 9 | #[error("Contract execution is not supported")] 10 | ExecuteNotSupported, 11 | } 12 | 13 | #[derive(Error, Debug)] 14 | pub enum QueryError { 15 | #[error("Querier system error: {0}")] 16 | System(String), 17 | 18 | #[error("Querier contract error: {0}")] 19 | Contract(String), 20 | } 21 | 22 | pub type QueryResult = core::result::Result; 23 | 24 | impl QueryError { 25 | pub fn std_at_index(self, i: usize) -> StdError { 26 | StdError::generic_err(format!("Error at index {}, {}", i, self)) 27 | } 28 | 29 | pub fn std(self) -> StdError { 30 | StdError::generic_err(self) 31 | } 32 | } 33 | 34 | impl From for String { 35 | fn from(q: QueryError) -> Self { 36 | q.to_string() 37 | } 38 | } 39 | 40 | impl From for StdError { 41 | fn from(source: QueryError) -> Self { 42 | source.std() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod contract; 2 | mod error; 3 | pub mod msg; 4 | pub mod querier; 5 | 6 | #[cfg(test)] 7 | mod test; 8 | 9 | #[cfg(test)] 10 | pub mod mock_querier; 11 | -------------------------------------------------------------------------------- /src/mock_querier.rs: -------------------------------------------------------------------------------- 1 | use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; 2 | use cosmwasm_std::{ 3 | from_binary, from_slice, to_binary, Addr, Api, Binary, Coin, ContractResult, Empty, OwnedDeps, 4 | Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, 5 | }; 6 | use serde::{Deserialize, Serialize}; 7 | use std::marker::PhantomData; 8 | 9 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 10 | pub enum MockQueryMsg { 11 | One, 12 | Str(String), 13 | FailSystem, 14 | FailContract, 15 | Struct, 16 | StructAmount(u64), 17 | StructStr(String), 18 | } 19 | 20 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 21 | pub struct SomeStructResponse { 22 | pub address: Addr, 23 | pub amount: Uint128, 24 | pub list: Vec, 25 | } 26 | 27 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 28 | pub struct AnotherStructResponse { 29 | pub result: String, 30 | pub another_result: String, 31 | } 32 | 33 | pub fn mock_dependencies( 34 | contract_balance: &[Coin], 35 | ) -> OwnedDeps { 36 | let contract_addr = MOCK_CONTRACT_ADDR.to_string(); 37 | let custom_querier: WasmMockQuerier = WasmMockQuerier::new( 38 | MockQuerier::::new(&[(&contract_addr, contract_balance)]), 39 | MockApi::default(), 40 | ); 41 | 42 | OwnedDeps { 43 | storage: MockStorage::default(), 44 | api: MockApi::default(), 45 | querier: custom_querier, 46 | custom_query_type: PhantomData, 47 | } 48 | } 49 | 50 | pub struct WasmMockQuerier { 51 | base: MockQuerier, 52 | } 53 | 54 | impl Querier for WasmMockQuerier { 55 | fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { 56 | // MockQuerier doesn't support Custom, so we ignore it completely here 57 | let request: QueryRequest = match from_slice(bin_request) { 58 | Ok(v) => v, 59 | Err(e) => { 60 | return SystemResult::Err(SystemError::InvalidRequest { 61 | error: format!("Parsing query request: {}", e), 62 | request: bin_request.into(), 63 | }) 64 | } 65 | }; 66 | self.handle_query(&request) 67 | } 68 | } 69 | 70 | impl WasmMockQuerier { 71 | pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { 72 | match &request { 73 | QueryRequest::Wasm(WasmQuery::Smart { 74 | contract_addr: _, 75 | msg, 76 | }) => match from_binary(msg).unwrap() { 77 | MockQueryMsg::One {} => SystemResult::Ok(ContractResult::Ok( 78 | Binary::from_base64(base64::encode(b"1").as_str()).unwrap(), 79 | )), 80 | MockQueryMsg::Str(i) => SystemResult::Ok(ContractResult::Ok( 81 | Binary::from_base64(base64::encode(i).as_str()).unwrap(), 82 | )), 83 | MockQueryMsg::FailSystem => SystemResult::Err(SystemError::Unknown {}), 84 | MockQueryMsg::FailContract => { 85 | SystemResult::Ok(ContractResult::Err(String::from("error"))) 86 | } 87 | MockQueryMsg::Struct => SystemResult::Ok(ContractResult::Ok( 88 | to_binary(&SomeStructResponse { 89 | address: Addr::unchecked("random"), 90 | amount: Uint128::from(100_000_000u64), 91 | list: vec![0, 1, 2, 3, 4, 5], 92 | }) 93 | .unwrap(), 94 | )), 95 | MockQueryMsg::StructAmount(amt) => SystemResult::Ok(ContractResult::Ok( 96 | to_binary(&SomeStructResponse { 97 | address: Addr::unchecked("random_amount"), 98 | amount: Uint128::from(amt * 3), 99 | list: vec![amt, amt + 1, amt + 2], 100 | }) 101 | .unwrap(), 102 | )), 103 | MockQueryMsg::StructStr(s) => SystemResult::Ok(ContractResult::Ok( 104 | to_binary(&AnotherStructResponse { 105 | another_result: s.to_uppercase(), 106 | result: s, 107 | }) 108 | .unwrap(), 109 | )), 110 | }, 111 | _ => self.base.handle_query(request), 112 | } 113 | } 114 | } 115 | 116 | impl WasmMockQuerier { 117 | pub fn new(base: MockQuerier, _api: A) -> Self { 118 | WasmMockQuerier { base } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/msg.rs: -------------------------------------------------------------------------------- 1 | use cosmwasm_std::{Addr, Binary}; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 5 | pub struct InstantiateMsg {} 6 | 7 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 8 | pub struct MigrateMsg {} 9 | 10 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 11 | #[serde(rename_all = "snake_case")] 12 | pub enum ExecuteMsg {} 13 | 14 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 15 | #[serde(rename_all = "snake_case")] 16 | pub enum QueryMsg { 17 | ContractVersion {}, 18 | Aggregate { 19 | queries: Vec, 20 | }, 21 | TryAggregate { 22 | require_success: Option, 23 | include_cause: Option, 24 | queries: Vec, 25 | }, 26 | TryAggregateOptional { 27 | include_cause: Option, 28 | queries: Vec, 29 | }, 30 | BlockAggregate { 31 | queries: Vec, 32 | }, 33 | BlockTryAggregate { 34 | require_success: Option, 35 | include_cause: Option, 36 | queries: Vec, 37 | }, 38 | BlockTryAggregateOptional { 39 | include_cause: Option, 40 | queries: Vec, 41 | }, 42 | } 43 | 44 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 45 | pub struct Call { 46 | pub address: Addr, 47 | pub data: Binary, 48 | } 49 | 50 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 51 | pub struct CallOptional { 52 | pub require_success: bool, 53 | pub address: Addr, 54 | pub data: Binary, 55 | } 56 | 57 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)] 58 | pub struct CallResult { 59 | pub success: bool, 60 | pub data: Binary, 61 | } 62 | 63 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 64 | pub struct AggregateResult { 65 | pub return_data: Vec, 66 | } 67 | 68 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 69 | pub struct BlockAggregateResult { 70 | pub block: u64, 71 | pub return_data: Vec, 72 | } 73 | 74 | impl AggregateResult { 75 | pub fn from_return_data(return_data: Vec) -> AggregateResult { 76 | AggregateResult { return_data } 77 | } 78 | } 79 | 80 | impl BlockAggregateResult { 81 | pub fn from_return_data(block: u64, return_data: Vec) -> BlockAggregateResult { 82 | BlockAggregateResult { block, return_data } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/querier.rs: -------------------------------------------------------------------------------- 1 | use cosmwasm_std::{ 2 | to_binary, to_vec, Addr, Binary, ContractResult, Deps, Empty, Env, QuerierResult, QueryRequest, 3 | StdResult, SystemResult, WasmQuery, 4 | }; 5 | 6 | use crate::{ 7 | error::{QueryError, QueryResult}, 8 | msg::{AggregateResult, BlockAggregateResult, Call, CallOptional, CallResult}, 9 | }; 10 | 11 | fn process_query_result(result: QuerierResult) -> QueryResult { 12 | match result { 13 | SystemResult::Err(system_err) => Err(QueryError::System(system_err.to_string())), 14 | SystemResult::Ok(ContractResult::Err(contract_err)) => { 15 | Err(QueryError::Contract(contract_err)) 16 | } 17 | SystemResult::Ok(ContractResult::Ok(value)) => Ok(value), 18 | } 19 | } 20 | 21 | fn process_wasm_query(address: Addr, binary: Binary) -> StdResult> { 22 | to_vec(&QueryRequest::::Wasm(WasmQuery::Smart { 23 | contract_addr: address.to_string(), 24 | msg: binary, 25 | })) 26 | } 27 | 28 | pub fn block_aggregrate( 29 | deps: Deps, 30 | env: Env, 31 | queries: Vec, 32 | ) -> StdResult { 33 | let block = env.block.height; 34 | let result = aggregrate(deps, queries)?; 35 | 36 | Ok(BlockAggregateResult::from_return_data( 37 | block, 38 | result.return_data, 39 | )) 40 | } 41 | 42 | pub fn block_try_aggregrate( 43 | deps: Deps, 44 | env: Env, 45 | require_success: Option, 46 | include_cause: Option, 47 | queries: Vec, 48 | ) -> StdResult { 49 | let block = env.block.height; 50 | let result = try_aggregate(deps, require_success, include_cause, queries)?; 51 | 52 | Ok(BlockAggregateResult::from_return_data( 53 | block, 54 | result.return_data, 55 | )) 56 | } 57 | 58 | pub fn block_try_aggregate_optional( 59 | deps: Deps, 60 | env: Env, 61 | include_cause: Option, 62 | queries: Vec, 63 | ) -> StdResult { 64 | let block = env.block.height; 65 | let result = try_aggregate_optional(deps, include_cause, queries)?; 66 | 67 | Ok(BlockAggregateResult::from_return_data( 68 | block, 69 | result.return_data, 70 | )) 71 | } 72 | 73 | pub fn aggregrate(deps: Deps, queries: Vec) -> StdResult { 74 | let n = queries.len(); 75 | let mut result: Vec = vec![CallResult::default(); n]; 76 | 77 | for i in 0..n { 78 | let query = queries[i].clone(); 79 | let wasm = &process_wasm_query(query.address, query.data)?; 80 | let res = deps.querier.raw_query(wasm); 81 | let data = match process_query_result(res) { 82 | Ok(res) => res, 83 | Err(err) => return Err(err.std_at_index(i)), 84 | }; 85 | result[i] = CallResult { 86 | success: true, 87 | data, 88 | }; 89 | } 90 | 91 | Ok(AggregateResult::from_return_data(result)) 92 | } 93 | 94 | pub fn try_aggregate( 95 | deps: Deps, 96 | require_success: Option, 97 | include_cause: Option, 98 | queries: Vec, 99 | ) -> StdResult { 100 | let n = queries.len(); 101 | let mut result: Vec = vec![CallResult::default(); n]; 102 | 103 | for i in 0..n { 104 | let query = queries[i].clone(); 105 | let wasm = &process_wasm_query(query.address, query.data)?; 106 | let res = deps.querier.raw_query(wasm); 107 | result[i] = match process_query_result(res) { 108 | Ok(res) => CallResult { 109 | success: true, 110 | data: res, 111 | }, 112 | Err(err) => match require_success.unwrap_or(false) { 113 | true => return Err(err.std_at_index(i)), 114 | false => match include_cause.unwrap_or(false) { 115 | true => CallResult { 116 | success: false, 117 | data: to_binary(&err.to_string())?, 118 | }, 119 | false => CallResult { 120 | success: false, 121 | data: Binary::default(), 122 | }, 123 | }, 124 | }, 125 | }; 126 | } 127 | 128 | Ok(AggregateResult::from_return_data(result)) 129 | } 130 | 131 | pub fn try_aggregate_optional( 132 | deps: Deps, 133 | include_cause: Option, 134 | queries: Vec, 135 | ) -> StdResult { 136 | let n = queries.len(); 137 | let mut result: Vec = vec![CallResult::default(); n]; 138 | 139 | for i in 0..n { 140 | let query = queries[i].clone(); 141 | let wasm = &process_wasm_query(query.address, query.data)?; 142 | let res = deps.querier.raw_query(wasm); 143 | result[i] = match process_query_result(res) { 144 | Ok(res) => CallResult { 145 | success: true, 146 | data: res, 147 | }, 148 | Err(err) => match query.require_success { 149 | true => return Err(err.std_at_index(i)), 150 | false => match include_cause.unwrap_or(false) { 151 | true => CallResult { 152 | success: false, 153 | data: to_binary(&err.to_string())?, 154 | }, 155 | false => CallResult { 156 | success: false, 157 | data: Binary::default(), 158 | }, 159 | }, 160 | }, 161 | }; 162 | } 163 | 164 | Ok(AggregateResult::from_return_data(result)) 165 | } 166 | -------------------------------------------------------------------------------- /src/test.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | 3 | use crate::{ 4 | contract::query, 5 | mock_querier::{mock_dependencies, AnotherStructResponse, MockQueryMsg}, 6 | msg::{AggregateResult, BlockAggregateResult, Call, CallOptional, QueryMsg}, 7 | }; 8 | use cosmwasm_std::{from_binary, testing::mock_env, to_binary, Addr, BlockInfo, Env, StdError}; 9 | use test_case::test_case; 10 | 11 | fn env_with_height(height: u64) -> Env { 12 | let mock = mock_env(); 13 | 14 | Env { 15 | block: BlockInfo { 16 | height, 17 | ..mock.block 18 | }, 19 | ..mock 20 | } 21 | } 22 | 23 | #[test_case(10; "block ten")] 24 | #[test_case(100; "block hundred")] 25 | #[test_case(1289189451295; "block random")] 26 | fn block_aggregate(x: u64) { 27 | let deps = mock_dependencies(&[]); 28 | let env = env_with_height(x); 29 | 30 | let err = query( 31 | deps.as_ref(), 32 | env.clone(), 33 | QueryMsg::BlockAggregate { 34 | queries: vec![Call { 35 | address: Addr::unchecked(""), 36 | data: to_binary(&MockQueryMsg::FailSystem).unwrap(), 37 | }], 38 | }, 39 | ) 40 | .unwrap_err(); 41 | 42 | assert!(matches!(err, StdError::GenericErr { msg: _ })); 43 | 44 | let q: BlockAggregateResult = from_binary( 45 | &query( 46 | deps.as_ref(), 47 | env.clone(), 48 | QueryMsg::BlockAggregate { 49 | queries: vec![Call { 50 | address: Addr::unchecked(""), 51 | data: to_binary(&MockQueryMsg::One).unwrap(), 52 | }], 53 | }, 54 | ) 55 | .unwrap(), 56 | ) 57 | .unwrap(); 58 | 59 | assert_eq!(q.block, x); 60 | assert_eq!( 61 | base64::encode(b"1"), 62 | q.return_data.first().unwrap().data.to_base64() 63 | ); 64 | assert!(q.return_data.first().unwrap().success); 65 | 66 | let q: BlockAggregateResult = from_binary( 67 | &query( 68 | deps.as_ref(), 69 | env.clone(), 70 | QueryMsg::BlockTryAggregate { 71 | require_success: None, 72 | include_cause: None, 73 | queries: vec![Call { 74 | address: Addr::unchecked(""), 75 | data: to_binary(&MockQueryMsg::One).unwrap(), 76 | }], 77 | }, 78 | ) 79 | .unwrap(), 80 | ) 81 | .unwrap(); 82 | 83 | assert_eq!(q.block, x); 84 | assert_eq!( 85 | base64::encode(b"1"), 86 | q.return_data.first().unwrap().data.to_base64() 87 | ); 88 | assert!(q.return_data.first().unwrap().success); 89 | 90 | let q: BlockAggregateResult = from_binary( 91 | &query( 92 | deps.as_ref(), 93 | env, 94 | QueryMsg::BlockTryAggregateOptional { 95 | include_cause: None, 96 | queries: vec![CallOptional { 97 | require_success: false, 98 | address: Addr::unchecked(""), 99 | data: to_binary(&MockQueryMsg::One).unwrap(), 100 | }], 101 | }, 102 | ) 103 | .unwrap(), 104 | ) 105 | .unwrap(); 106 | 107 | assert_eq!(q.block, x); 108 | assert_eq!( 109 | base64::encode(b"1"), 110 | q.return_data.first().unwrap().data.to_base64() 111 | ); 112 | assert!(q.return_data.first().unwrap().success); 113 | } 114 | 115 | #[test_case("1"; "number")] 116 | #[test_case("11231123"; "numbers")] 117 | #[test_case("112311233910930150"; "very long numbers")] 118 | #[test_case("x"; "character")] 119 | #[test_case("hello"; "word")] 120 | #[test_case("hello world"; "words")] 121 | fn aggregate(x: &str) { 122 | let deps = mock_dependencies(&[]); 123 | let env = mock_env(); 124 | 125 | let err = query( 126 | deps.as_ref(), 127 | env.clone(), 128 | QueryMsg::Aggregate { 129 | queries: vec![Call { 130 | address: Addr::unchecked(""), 131 | data: to_binary(&MockQueryMsg::FailSystem).unwrap(), 132 | }], 133 | }, 134 | ) 135 | .unwrap_err(); 136 | 137 | assert!(matches!(err, StdError::GenericErr { msg: _ })); 138 | 139 | let q: AggregateResult = from_binary( 140 | &query( 141 | deps.as_ref(), 142 | env.clone(), 143 | QueryMsg::Aggregate { 144 | queries: vec![Call { 145 | address: Addr::unchecked(""), 146 | data: to_binary(&MockQueryMsg::Str(x.to_string())).unwrap(), 147 | }], 148 | }, 149 | ) 150 | .unwrap(), 151 | ) 152 | .unwrap(); 153 | 154 | assert_eq!( 155 | base64::encode(x), 156 | q.return_data.first().unwrap().data.to_base64() 157 | ); 158 | assert!(q.return_data.first().unwrap().success); 159 | 160 | let q: AggregateResult = from_binary( 161 | &query( 162 | deps.as_ref(), 163 | env, 164 | QueryMsg::Aggregate { 165 | queries: vec![ 166 | Call { 167 | address: Addr::unchecked(""), 168 | data: to_binary(&MockQueryMsg::Str(x.to_string())).unwrap(), 169 | }, 170 | Call { 171 | address: Addr::unchecked(""), 172 | data: to_binary(&MockQueryMsg::Str(x.to_string())).unwrap(), 173 | }, 174 | ], 175 | }, 176 | ) 177 | .unwrap(), 178 | ) 179 | .unwrap(); 180 | 181 | assert_eq!(q.return_data.len(), 2); 182 | assert_eq!( 183 | base64::encode(x), 184 | q.return_data.first().unwrap().data.to_base64() 185 | ); 186 | assert!(q.return_data.first().unwrap().success); 187 | assert_eq!( 188 | base64::encode(x), 189 | q.return_data.last().unwrap().data.to_base64() 190 | ); 191 | assert!(q.return_data.last().unwrap().success); 192 | } 193 | 194 | #[test_case(""; "empty")] 195 | #[test_case("1"; "number")] 196 | #[test_case("11231123"; "numbers")] 197 | #[test_case("112311233910930150"; "very long numbers")] 198 | #[test_case("x"; "character")] 199 | #[test_case("hello"; "word")] 200 | #[test_case("hello world"; "words")] 201 | fn aggregate_struct(x: &str) { 202 | let deps = mock_dependencies(&[]); 203 | let env = mock_env(); 204 | 205 | let q: AggregateResult = from_binary( 206 | &query( 207 | deps.as_ref(), 208 | env, 209 | QueryMsg::Aggregate { 210 | queries: vec![ 211 | Call { 212 | address: Addr::unchecked(""), 213 | data: to_binary(&MockQueryMsg::StructStr(x.to_string())).unwrap(), 214 | }, 215 | Call { 216 | address: Addr::unchecked(""), 217 | data: to_binary(&MockQueryMsg::StructStr(x.to_string())).unwrap(), 218 | }, 219 | ], 220 | }, 221 | ) 222 | .unwrap(), 223 | ) 224 | .unwrap(); 225 | 226 | assert_eq!(q.return_data.len(), 2); 227 | 228 | let first: AnotherStructResponse = from_binary(&q.return_data.first().unwrap().data).unwrap(); 229 | let last: AnotherStructResponse = from_binary(&q.return_data.last().unwrap().data).unwrap(); 230 | 231 | assert_eq!(first.result, x); 232 | assert_eq!(first.another_result, x.to_uppercase()); 233 | assert_eq!(last.result, x); 234 | assert_eq!(last.another_result, x.to_uppercase()); 235 | } 236 | 237 | #[test_case(10, vec![]; "no error")] 238 | #[test_case(10, vec![0]; "error at start")] 239 | #[test_case(10, vec![9]; "error at end")] 240 | #[test_case(10, vec![0, 3, 4, 5, 8]; "multiple error")] 241 | #[test_case(5, vec![0, 1, 2, 3, 4]; "all error")] 242 | fn try_aggregate(total: usize, error_at: Vec) { 243 | let deps = mock_dependencies(&[]); 244 | let env = mock_env(); 245 | 246 | let body = (0..total) 247 | .map(|i| Call { 248 | address: Addr::unchecked(""), 249 | data: to_binary(&match i { 250 | _ if error_at.contains(&i) => MockQueryMsg::FailSystem, 251 | _ => MockQueryMsg::One, 252 | }) 253 | .unwrap(), 254 | }) 255 | .collect::>(); 256 | 257 | let q: AggregateResult = from_binary( 258 | &query( 259 | deps.as_ref(), 260 | env.clone(), 261 | QueryMsg::TryAggregate { 262 | require_success: Some(false), 263 | queries: body.clone(), 264 | include_cause: Some(false), 265 | }, 266 | ) 267 | .unwrap(), 268 | ) 269 | .unwrap(); 270 | 271 | for (i, bin) in q.return_data.iter().enumerate() { 272 | assert_eq!( 273 | match i { 274 | _ if error_at.contains(&i) => String::new(), 275 | _ => base64::encode(b"1"), 276 | }, 277 | bin.data.to_base64() 278 | ); 279 | } 280 | 281 | let q = query( 282 | deps.as_ref(), 283 | env, 284 | QueryMsg::TryAggregate { 285 | require_success: Some(true), 286 | queries: body, 287 | include_cause: Some(false), 288 | }, 289 | ); 290 | 291 | match error_at[..] { 292 | [] => assert!( 293 | matches!(from_binary::(&q.unwrap()).unwrap(), x if x.return_data.len() == total) 294 | ), 295 | _ => assert!(matches!(q.unwrap_err(), StdError::GenericErr { msg: _ })), 296 | } 297 | } 298 | 299 | #[test_case(10, vec![], vec![]; "no error")] 300 | #[test_case(10, vec![0, 3, 4, 5, 8], vec![]; "multiple error")] 301 | #[test_case(10, vec![0, 3, 4, 5, 8], vec![1, 2, 6]; "multiple error and none require success")] 302 | #[test_case(10, vec![0, 3, 4, 5, 8], vec![3]; "multiple error and some require success")] 303 | #[test_case(10, vec![0, 3, 4, 5, 8], vec![0, 3, 4, 5, 8]; "multiple error and all require success")] 304 | fn try_aggregate_optional(total: usize, error_at: Vec, required: Vec) { 305 | let deps = mock_dependencies(&[]); 306 | let env = mock_env(); 307 | 308 | let body = (0..total) 309 | .map(|i| CallOptional { 310 | require_success: false, 311 | address: Addr::unchecked(""), 312 | data: to_binary(&match i { 313 | _ if error_at.contains(&i) => MockQueryMsg::FailSystem, 314 | _ => MockQueryMsg::One, 315 | }) 316 | .unwrap(), 317 | }) 318 | .collect::>(); 319 | 320 | let q: AggregateResult = from_binary( 321 | &query( 322 | deps.as_ref(), 323 | env.clone(), 324 | QueryMsg::TryAggregateOptional { 325 | include_cause: Some(false), 326 | queries: body, 327 | }, 328 | ) 329 | .unwrap(), 330 | ) 331 | .unwrap(); 332 | 333 | for (i, bin) in q.return_data.iter().enumerate() { 334 | assert_eq!( 335 | match i { 336 | _ if error_at.contains(&i) => String::new(), 337 | _ => base64::encode(b"1"), 338 | }, 339 | bin.data.to_base64() 340 | ); 341 | } 342 | 343 | let body = (0..total) 344 | .map(|i| CallOptional { 345 | require_success: matches!(i, _ if required.contains(&i)), 346 | address: Addr::unchecked(""), 347 | data: to_binary(&match i { 348 | _ if error_at.contains(&i) => MockQueryMsg::FailSystem, 349 | _ => MockQueryMsg::One, 350 | }) 351 | .unwrap(), 352 | }) 353 | .collect::>(); 354 | 355 | let q = query( 356 | deps.as_ref(), 357 | env, 358 | QueryMsg::TryAggregateOptional { 359 | include_cause: Some(false), 360 | queries: body, 361 | }, 362 | ); 363 | 364 | let err_hs = error_at.iter().collect::>(); 365 | let rq_hs = required.iter().collect::>(); 366 | 367 | match err_hs.intersection(&rq_hs).into_iter().next() { 368 | Some(_) => assert!(matches!(q.unwrap_err(), StdError::GenericErr { msg: _ })), 369 | None => assert!( 370 | matches!(from_binary::(&q.unwrap()).unwrap(), x if x.return_data.len() == total) 371 | ), 372 | } 373 | } 374 | --------------------------------------------------------------------------------